use of org.kie.dmn.feel.lang.types.GenListType in project drools by kiegroup.
the class ParserHelper method recoverScope.
public void recoverScope(String name) {
LOG.trace("[{}] recoverScope( name: {}) with currentScope: {}", this.currentScope.getName(), name, currentScope);
Scope s = this.currentScope.getChildScopes().get(name);
if (s != null) {
currentScope = s;
if (currentScope.getType() != null && currentScope.getType().equals(BuiltInType.UNKNOWN)) {
enableDynamicResolution();
}
} else {
Symbol resolved = this.currentScope.resolve(name);
Type scopeType = resolved != null ? resolved.getType() : null;
if (scopeType instanceof GenListType) {
scopeType = ((GenListType) scopeType).getGen();
}
if (resolved != null && scopeType instanceof CompositeType) {
pushScope(scopeType);
CompositeType type = (CompositeType) scopeType;
for (Map.Entry<String, Type> f : type.getFields().entrySet()) {
this.currentScope.define(new VariableSymbol(f.getKey(), f.getValue()));
}
LOG.trace(".. PUSHED, scope name {} with symbols {}", this.currentName.peek(), this.currentScope.getSymbols());
} else if (resolved != null && scopeType instanceof SimpleType) {
BuiltInType resolvedBIType = null;
if (scopeType instanceof BuiltInType) {
resolvedBIType = (BuiltInType) scopeType;
} else if (scopeType instanceof AliasFEELType) {
resolvedBIType = ((AliasFEELType) scopeType).getBuiltInType();
} else {
throw new UnsupportedOperationException("Unsupported BIType " + scopeType + "!");
}
pushScope(resolvedBIType);
switch(resolvedBIType) {
// FEEL spec table 53
case DATE:
this.currentScope.define(new VariableSymbol("year", BuiltInType.NUMBER));
this.currentScope.define(new VariableSymbol("month", BuiltInType.NUMBER));
this.currentScope.define(new VariableSymbol("day", BuiltInType.NUMBER));
if (isFeatDMN12weekday()) {
// Table 60 spec DMN v1.2
this.currentScope.define(new VariableSymbol("weekday", BuiltInType.NUMBER));
}
break;
case TIME:
this.currentScope.define(new VariableSymbol("hour", BuiltInType.NUMBER));
this.currentScope.define(new VariableSymbol("minute", BuiltInType.NUMBER));
this.currentScope.define(new VariableSymbol("second", BuiltInType.NUMBER));
this.currentScope.define(new VariableSymbol("time offset", BuiltInType.DURATION));
this.currentScope.define(new VariableSymbol("timezone", BuiltInType.NUMBER));
break;
case DATE_TIME:
this.currentScope.define(new VariableSymbol("year", BuiltInType.NUMBER));
this.currentScope.define(new VariableSymbol("month", BuiltInType.NUMBER));
this.currentScope.define(new VariableSymbol("day", BuiltInType.NUMBER));
if (isFeatDMN12weekday()) {
// Table 60 spec DMN v1.2
this.currentScope.define(new VariableSymbol("weekday", BuiltInType.NUMBER));
}
this.currentScope.define(new VariableSymbol("hour", BuiltInType.NUMBER));
this.currentScope.define(new VariableSymbol("minute", BuiltInType.NUMBER));
this.currentScope.define(new VariableSymbol("second", BuiltInType.NUMBER));
this.currentScope.define(new VariableSymbol("time offset", BuiltInType.DURATION));
this.currentScope.define(new VariableSymbol("timezone", BuiltInType.NUMBER));
break;
case DURATION:
// TODO might need to distinguish between `years and months duration` and `days and time duration`
this.currentScope.define(new VariableSymbol("years", BuiltInType.NUMBER));
this.currentScope.define(new VariableSymbol("months", BuiltInType.NUMBER));
this.currentScope.define(new VariableSymbol("days", BuiltInType.NUMBER));
this.currentScope.define(new VariableSymbol("hours", BuiltInType.NUMBER));
this.currentScope.define(new VariableSymbol("minutes", BuiltInType.NUMBER));
this.currentScope.define(new VariableSymbol("seconds", BuiltInType.NUMBER));
break;
case RANGE:
this.currentScope.define(new VariableSymbol("start included", BuiltInType.BOOLEAN));
this.currentScope.define(new VariableSymbol("start", BuiltInType.UNKNOWN));
this.currentScope.define(new VariableSymbol("end", BuiltInType.UNKNOWN));
this.currentScope.define(new VariableSymbol("end included", BuiltInType.BOOLEAN));
break;
// table 53 applies only to type(e) is a date/time/duration
case UNKNOWN:
enableDynamicResolution();
break;
default:
break;
}
} else {
pushScope();
}
}
}
use of org.kie.dmn.feel.lang.types.GenListType in project drools by kiegroup.
the class CompileEvaluateTest method testHyphenInPropertyOfCollectionForAccessor.
@Test
public void testHyphenInPropertyOfCollectionForAccessor() {
MapBackedType compositeType = new MapBackedType().addField("Primary-Key", BuiltInType.STRING).addField("Value", BuiltInType.STRING);
CompilerContext ctx = feel.newCompilerContext();
ctx.addInputVariableType("my input", new GenListType(compositeType));
CompiledExpression compiledExpression = feel.compile("my input[1].Primary-Key", ctx);
assertTrue(errors.isEmpty());
Map<String, Object> inputs = new HashMap<>();
inputs.put("my input", Arrays.asList(prototype(entry("Primary-Key", "k987"))));
Object result = feel.evaluate(compiledExpression, inputs);
assertThat(result, is("k987"));
assertTrue(errors.isEmpty());
}
use of org.kie.dmn.feel.lang.types.GenListType in project drools by kiegroup.
the class CompileEvaluateTest method testHyphenInPropertyOfCollectionForProjection.
@Test
public void testHyphenInPropertyOfCollectionForProjection() {
MapBackedType compositeType = new MapBackedType().addField("Primary-Key", BuiltInType.STRING).addField("Value", BuiltInType.STRING);
CompilerContext ctx = feel.newCompilerContext();
ctx.addInputVariableType("input", new GenListType(compositeType));
CompiledExpression compiledExpression = feel.compile("input.Primary-Key", ctx);
assertTrue(errors.isEmpty());
Map<String, Object> inputs = new HashMap<>();
inputs.put("input", Arrays.asList(prototype(entry("Primary-Key", "k987"))));
Object result = feel.evaluate(compiledExpression, inputs);
assertThat(result, is(Arrays.asList("k987")));
assertTrue(errors.isEmpty());
}
use of org.kie.dmn.feel.lang.types.GenListType in project drools by kiegroup.
the class CompositeTypeImpl method addField.
public void addField(String name, DMNType type) {
this.fields.put(name, type);
MapBackedType mbType = !isCollection() ? (MapBackedType) getFeelType() : (MapBackedType) ((GenListType) getFeelType()).getGen();
mbType.addField(name, ((BaseDMNTypeImpl) type).getFeelType());
}
use of org.kie.dmn.feel.lang.types.GenListType in project drools by kiegroup.
the class DMNCompilerImpl method buildTypeDef.
/**
* @param topLevel null if it is a top level ItemDefinition
*/
private DMNType buildTypeDef(DMNCompilerContext ctx, DMNModelImpl dmnModel, DMNNode node, ItemDefinition itemDef, DMNType topLevel) {
BaseDMNTypeImpl type = null;
if (itemDef.getTypeRef() != null) {
// this is a reference to an existing type, so resolve the reference
type = (BaseDMNTypeImpl) resolveTypeRef(dmnModel, itemDef, itemDef, itemDef.getTypeRef());
if (type != null) {
UnaryTests allowedValuesStr = itemDef.getAllowedValues();
// or if it changes the metadata for the base type
if (topLevel == null || allowedValuesStr != null || itemDef.isIsCollection() != type.isCollection()) {
// we have to clone this type definition into a new one
String name = itemDef.getName();
String namespace = dmnModel.getNamespace();
String id = itemDef.getId();
BaseDMNTypeImpl baseType = type;
Type baseFEELType = type.getFeelType();
if (baseFEELType instanceof BuiltInType) {
// Then it is an ItemDefinition in place for "aliasing" a base FEEL type, for having type(itemDefname) I need to define its SimpleType.
baseFEELType = new AliasFEELType(itemDef.getName(), (BuiltInType) baseFEELType);
}
List<UnaryTest> av = null;
if (allowedValuesStr != null) {
av = ctx.getFeelHelper().evaluateUnaryTests(ctx, allowedValuesStr.getText(), dmnModel, itemDef, Msg.ERR_COMPILING_ALLOWED_VALUES_LIST_ON_ITEM_DEF, allowedValuesStr.getText(), node.getName());
}
boolean isCollection = itemDef.isIsCollection();
if (isCollection) {
baseFEELType = new GenListType(baseFEELType);
}
if (type instanceof CompositeTypeImpl) {
CompositeTypeImpl compositeTypeImpl = (CompositeTypeImpl) type;
type = new CompositeTypeImpl(namespace, name, id, isCollection, compositeTypeImpl.getFields(), baseType, baseFEELType);
} else if (type instanceof SimpleTypeImpl) {
type = new SimpleTypeImpl(namespace, name, id, isCollection, av, baseType, baseFEELType);
}
if (topLevel != null) {
((BaseDMNTypeImpl) type).setBelongingType(topLevel);
}
}
if (topLevel == null) {
DMNType registered = dmnModel.getTypeRegistry().registerType(type);
if (registered != type) {
MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, itemDef, dmnModel, null, null, Msg.DUPLICATED_ITEM_DEFINITION, itemDef.getName());
}
}
}
} else if (itemDef.getItemComponent() != null && itemDef.getItemComponent().size() > 0) {
// first, locate preregistered or create anonymous inner composite
if (topLevel == null) {
type = (CompositeTypeImpl) dmnModel.getTypeRegistry().resolveType(dmnModel.getNamespace(), itemDef.getName());
} else {
DMNCompilerHelper.checkVariableName(dmnModel, itemDef, itemDef.getName());
type = new CompositeTypeImpl(dmnModel.getNamespace(), itemDef.getName(), itemDef.getId(), itemDef.isIsCollection());
((BaseDMNTypeImpl) type).setBelongingType(topLevel);
}
// second, add fields to located composite
for (ItemDefinition fieldDef : itemDef.getItemComponent()) {
DMNCompilerHelper.checkVariableName(dmnModel, fieldDef, fieldDef.getName());
DMNType fieldType = buildTypeDef(ctx, dmnModel, node, fieldDef, type);
fieldType = fieldType != null ? fieldType : dmnModel.getTypeRegistry().unknown();
((CompositeTypeImpl) type).addField(fieldDef.getName(), fieldType);
}
} else if (isFunctionItem(itemDef)) {
FunctionItem fi = itemDef.getFunctionItem();
String name = itemDef.getName();
String namespace = dmnModel.getNamespace();
String id = itemDef.getId();
Map<String, DMNType> params = new HashMap<>();
for (InformationItem p : fi.getParameters()) {
DMNType resolveTypeRef = resolveTypeRef(dmnModel, itemDef, itemDef, p.getTypeRef());
params.put(p.getName(), resolveTypeRef);
}
DMNType returnType = resolveTypeRef(dmnModel, itemDef, itemDef, fi.getOutputTypeRef());
List<Type> feelPs = fi.getParameters().stream().map(InformationItem::getName).map(n -> ((BaseDMNTypeImpl) params.get(n)).getFeelType()).collect(Collectors.toList());
GenFnType feeltype = new GenFnType(feelPs, ((BaseDMNTypeImpl) returnType).getFeelType());
type = new SimpleFnTypeImpl(namespace, name, id, feeltype, params, returnType, fi);
DMNType registered = dmnModel.getTypeRegistry().registerType(type);
if (registered != type) {
MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, itemDef, dmnModel, null, null, Msg.DUPLICATED_ITEM_DEFINITION, itemDef.getName());
}
} else {
DMNType unknown = (BaseDMNTypeImpl) resolveTypeRef(dmnModel, itemDef, itemDef, null);
type = new SimpleTypeImpl(dmnModel.getNamespace(), itemDef.getName(), itemDef.getId(), itemDef.isIsCollection(), null, unknown, ((BaseDMNTypeImpl) unknown).getFeelType());
if (topLevel == null) {
DMNType registered = dmnModel.getTypeRegistry().registerType(type);
if (registered != type) {
MsgUtil.reportMessage(logger, DMNMessage.Severity.ERROR, itemDef, dmnModel, null, null, Msg.DUPLICATED_ITEM_DEFINITION, itemDef.getName());
}
} else {
((BaseDMNTypeImpl) type).setBelongingType(topLevel);
}
}
return type;
}
Aggregations