Search in sources :

Example 1 with FunctionClassification

use of com.dexels.navajo.expression.api.FunctionClassification in project navajo by Dexels.

the class ASTReactiveScriptNode method interpretToLambda.

@Override
public ContextExpression interpretToLambda(List<String> problems, String originalExpression, Function<String, FunctionClassification> functionClassifier, Function<String, Optional<Node>> mapResolver) {
    int start = hasHeader ? headers : 0;
    if (hasHeader) {
        for (int i = 0; i < headers; i++) {
            ASTKeyValueNode hdr = (ASTKeyValueNode) jjtGetChild(i);
            NamedExpression ne = (NamedExpression) hdr.interpretToLambda(problems, originalExpression, functionClassifier, mapResolver);
            String key = ne.name;
            headerMap.put(key, ne.apply());
        }
    }
    int count = jjtGetNumChildren();
    List<Node> unnamedPipes = new ArrayList<>();
    Map<String, Node> namedPipes = new HashMap<>();
    for (int i = start; i < count; i++) {
        Node child = jjtGetChild(i);
        // ASTReactivePipe pipe = null;
        if (child instanceof ASTPipeDefinition) {
            unnamedPipes.add((ASTPipeDefinition) child);
        } else if (child instanceof ASTKeyValueNode) {
            ASTKeyValueNode kvNode = (ASTKeyValueNode) child;
            String streamName = kvNode.val;
            Node namedPipe = kvNode.jjtGetChild(0);
            // assert value types perhaps? TODO
            namedPipes.put(streamName, namedPipe);
        }
    }
    List<ReactivePipeNode> pipes = unnamedPipes.stream().map(p -> (ReactivePipeNode) p.interpretToLambda(problems, originalExpression, functionClassifier, name -> {
        Optional<Node> initial = Optional.ofNullable(namedPipes.get(name));
        if (initial.isPresent()) {
            return initial;
        } else {
            return mapResolver.apply(name);
        }
    })).collect(Collectors.toList());
    return new ContextExpression() {

        @Override
        public Optional<String> returnType() {
            return Optional.of(Reactive.ReactiveItemType.REACTIVE_SCRIPT.toString());
        }

        @Override
        public boolean isLiteral() {
            return true;
        }

        @Override
        public String expression() {
            return "";
        }

        @Override
        public Operand apply(Navajo doc, Message parentMsg, Message parentParamMsg, Selection parentSel, MappableTreeNode mapNode, TipiLink tipiLink, Access access, Optional<ImmutableMessage> immutableMessage, Optional<ImmutableMessage> paramMessage) {
            return Operand.ofCustom(pipes, Reactive.ReactiveItemType.REACTIVE_SCRIPT.toString());
        }
    };
}
Also used : TipiLink(com.dexels.navajo.expression.api.TipiLink) Arrays(java.util.Arrays) Access(com.dexels.navajo.script.api.Access) Message(com.dexels.navajo.document.Message) Reactive(com.dexels.navajo.reactive.api.Reactive) HashMap(java.util.HashMap) Function(java.util.function.Function) Collectors(java.util.stream.Collectors) ContextExpression(com.dexels.navajo.expression.api.ContextExpression) ArrayList(java.util.ArrayList) List(java.util.List) Operand(com.dexels.navajo.document.Operand) Selection(com.dexels.navajo.document.Selection) FunctionClassification(com.dexels.navajo.expression.api.FunctionClassification) NamedExpression(com.dexels.navajo.parser.NamedExpression) ReactivePipeNode(com.dexels.navajo.parser.compiled.api.ReactivePipeNode) Map(java.util.Map) Optional(java.util.Optional) ImmutableMessage(com.dexels.immutable.api.ImmutableMessage) Collections(java.util.Collections) MappableTreeNode(com.dexels.navajo.script.api.MappableTreeNode) Navajo(com.dexels.navajo.document.Navajo) MappableTreeNode(com.dexels.navajo.script.api.MappableTreeNode) Optional(java.util.Optional) Message(com.dexels.navajo.document.Message) ImmutableMessage(com.dexels.immutable.api.ImmutableMessage) HashMap(java.util.HashMap) Selection(com.dexels.navajo.document.Selection) ReactivePipeNode(com.dexels.navajo.parser.compiled.api.ReactivePipeNode) MappableTreeNode(com.dexels.navajo.script.api.MappableTreeNode) ContextExpression(com.dexels.navajo.expression.api.ContextExpression) ArrayList(java.util.ArrayList) Access(com.dexels.navajo.script.api.Access) Navajo(com.dexels.navajo.document.Navajo) ReactivePipeNode(com.dexels.navajo.parser.compiled.api.ReactivePipeNode) TipiLink(com.dexels.navajo.expression.api.TipiLink) NamedExpression(com.dexels.navajo.parser.NamedExpression)

Example 2 with FunctionClassification

use of com.dexels.navajo.expression.api.FunctionClassification in project navajo by Dexels.

the class ASTFunctionNode method interpretToLambda.

@Override
public ContextExpression interpretToLambda(List<String> problems, String expression, Function<String, FunctionClassification> functionClassifier, Function<String, Optional<Node>> mapResolver) {
    List<ContextExpression> unnamed = new LinkedList<>();
    // TODO make lazy?
    Map<String, ContextExpression> named = new HashMap<>();
    for (int i = 0; i < jjtGetNumChildren(); i++) {
        Node sn = jjtGetChild(i);
        ContextExpression cn = sn.interpretToLambda(problems, expression, functionClassifier, mapResolver);
        if (cn instanceof NamedExpression) {
            NamedExpression ne = (NamedExpression) cn;
            named.put(ne.name, ne.expression);
        } else {
            unnamed.add(cn);
        }
    }
    FunctionClassification mode = functionClassifier.apply(functionName);
    switch(mode) {
        case REACTIVE_HEADER:
            break;
        case REACTIVE_SOURCE:
            return new ReactiveParseItem(functionName, Reactive.ReactiveItemType.REACTIVE_SOURCE, named, unnamed, expression, this);
        case REACTIVE_TRANSFORMER:
            return new ReactiveParseItem(functionName, Reactive.ReactiveItemType.REACTIVE_TRANSFORMER, named, unnamed, expression, this);
        case REACTIVE_REDUCER:
            return new ReactiveParseItem(functionName, Reactive.ReactiveItemType.REACTIVE_MAPPER, named, unnamed, expression, this);
        case DEFAULT:
        default:
    }
    return resolveNormalFunction(unnamed, named, problems, expression);
}
Also used : HashMap(java.util.HashMap) ReactiveParseItem(com.dexels.navajo.parser.compiled.api.ReactiveParseItem) NamedExpression(com.dexels.navajo.parser.NamedExpression) ContextExpression(com.dexels.navajo.expression.api.ContextExpression) MappableTreeNode(com.dexels.navajo.script.api.MappableTreeNode) FunctionClassification(com.dexels.navajo.expression.api.FunctionClassification) LinkedList(java.util.LinkedList)

Example 3 with FunctionClassification

use of com.dexels.navajo.expression.api.FunctionClassification in project navajo by Dexels.

the class ASTTmlNode method interpretToLambda.

@Override
public final ContextExpression interpretToLambda(List<String> problems, String expression, Function<String, FunctionClassification> functionClassifier, Function<String, Optional<Node>> mapResolver) {
    return new ContextExpression() {

        @Override
        public boolean isLiteral() {
            return false;
        }

        @Override
        public Operand apply(Navajo doc, Message parentMsg, Message parentParamMsg, Selection parentSel, MappableTreeNode mapNode, TipiLink tipiLink, Access access, Optional<ImmutableMessage> immutableMessage, Optional<ImmutableMessage> paramMessage) {
            List<Property> match = null;
            List<Object> resultList = new ArrayList<>();
            boolean singleMatch = true;
            if (val.equals("[") || val.equals("[/")) {
                return immutableMessage.map(msg -> Operand.ofImmutable(msg)).orElse(parentMsg != null ? Operand.ofMessage(parentMsg) : Operand.NULL);
            }
            String[] parts = val.split("\\|");
            String text = parts.length > 1 ? parts[1] : val;
            boolean isParam = false;
            Property prop = null;
            if (parentSel != null) {
                String dum = text;
                if (dum.length() > 1 && dum.startsWith("[")) {
                    dum = dum.substring(1, dum.length());
                }
                if (dum.equals("name") || selectionOption.equals("name")) {
                    return Operand.ofString(parentSel.getName());
                } else if (dum.equals("value") || selectionOption.equals("value")) {
                    return Operand.ofString(parentSel.getValue());
                } else if (dum.equals("selected") || selectionOption.equals("selected")) {
                    return Operand.ofBoolean(parentSel.isSelected());
                }
            }
            if (!exists) {
                if (text.startsWith("[")) {
                    text = text.substring(1, text.length());
                }
            } else {
                if (text.startsWith("?[")) {
                    text = text.substring(2, text.length());
                }
            }
            if (text.length() > 0 && text.charAt(0) == '@') {
                // relative param property.
                isParam = true;
                text = text.substring(1);
            }
            if (text.startsWith("/@")) {
                // Absolute param property, exclude the '[/@]' expression
                isParam = true;
                if (!text.equals("/@")) {
                    parentParamMsg = doc.getMessage("__parms__");
                    text = text.substring(2);
                }
            }
            if (text.contains("__globals__")) {
                // Absolute globals property.
                parentMsg = doc.getMessage("__globals__");
                int length = "__globals__".length();
                if (text.startsWith("/")) {
                    length += 1;
                }
                // trailing /
                length += 1;
                text = text.substring(length);
            }
            if (Util.isRegularExpression(text))
                singleMatch = false;
            else
                singleMatch = true;
            try {
                if (!isParam && immutableMessage != null && immutableMessage.isPresent()) {
                    ImmutableMessage rm = immutableMessage.get();
                    return parseImmutablePath(text, rm);
                }
                if (isParam && paramMessage != null && paramMessage.isPresent()) {
                    ImmutableMessage rm = paramMessage.get();
                    return parseImmutablePath(text, rm);
                }
                if (parentMsg == null && !isParam) {
                    if (text.indexOf(Navajo.MESSAGE_SEPARATOR) != -1) {
                        if (doc == null) {
                            throw new NullPointerException("Can't evaluate TML node: No parent message and no document found.");
                        }
                        match = doc.getProperties(text);
                        if (match.size() > 1) {
                            singleMatch = false;
                        }
                    } else {
                        throw new TMLExpressionException("No parent message present for property: " + text + " -> " + ImmutableFactory.getInstance().describe(immutableMessage.orElse(ImmutableFactory.empty())));
                    }
                } else if (parentParamMsg == null && isParam) {
                    parentParamMsg = doc.getMessage("__parms__");
                    if (text.indexOf(Navajo.MESSAGE_SEPARATOR) != -1) {
                        match = doc.getProperties(text);
                        if (match.size() > 1) {
                            singleMatch = false;
                        }
                    } else
                        throw new TMLExpressionException("No parent message present for param: " + text);
                } else {
                    if (text.indexOf(Navajo.MESSAGE_SEPARATOR) != -1) {
                        match = (!isParam ? parentMsg.getProperties(text) : parentParamMsg.getProperties(text));
                        if (match.size() > 1)
                            singleMatch = false;
                    } else {
                        match = new ArrayList<>();
                        match.add((!isParam ? parentMsg.getProperty(text) : parentParamMsg.getProperty(text)));
                    }
                }
            } catch (NavajoException te) {
                throw new TMLExpressionException(te.getMessage(), te);
            }
            for (int j = 0; j < match.size(); j++) {
                prop = (Property) match.get(j);
                if (!exists && (prop == null))
                    if (parentMsg != null) {
                        throw new TMLExpressionException("TML property does not exist: " + text + " parent message: " + parentMsg.getFullMessageName());
                    } else {
                        throw new TMLExpressionException("TML property does not exist: " + text + " exists? " + exists);
                    }
                else if (exists) {
                    // Check for existence and datatype validity.
                    if (prop != null) {
                        // Check type. If integer, float or date type and if is empty
                        String type = prop.getType();
                        // of binary properties. Should be equivalent, and MUCH faster.
                        if (prop.getTypedValue() == null && !type.equals(Property.SELECTION_PROPERTY)) {
                            return Operand.FALSE;
                        }
                        if (type.equals(Property.INTEGER_PROPERTY)) {
                            try {
                                Integer.parseInt(prop.getValue());
                                return Operand.TRUE;
                            } catch (Exception e) {
                                return Operand.FALSE;
                            }
                        } else if (type.equals(Property.FLOAT_PROPERTY)) {
                            try {
                                Double.parseDouble(prop.getValue());
                                return Operand.TRUE;
                            } catch (Exception e) {
                                return Operand.FALSE;
                            }
                        } else if (type.equals(Property.DATE_PROPERTY)) {
                            try {
                                if (prop.getTypedValue() instanceof Date) {
                                    return Operand.TRUE;
                                } else {
                                    return Operand.FALSE;
                                }
                            } catch (Exception e) {
                                return Operand.FALSE;
                            }
                        } else if (type.equals(Property.CLOCKTIME_PROPERTY)) {
                            try {
                                ClockTime ct = new ClockTime(prop.getValue());
                                if (ct.calendarValue() == null) {
                                    return Operand.FALSE;
                                }
                                return Operand.TRUE;
                            } catch (Exception e) {
                                return Operand.FALSE;
                            }
                        } else
                            return Operand.TRUE;
                    } else
                        return Operand.FALSE;
                }
                String type = prop.getType();
                Object value = prop.getTypedValue();
                /**
                 * LEGACY MODE!
                 */
                if (value instanceof NavajoType && ((NavajoType) value).isEmpty()) {
                    value = null;
                }
                if (value == null && !type.equals(Property.SELECTION_PROPERTY)) {
                    // If value attribute does not exist AND property is not selection property assume null value
                    resultList.add(null);
                } else if (type.equals(Property.SELECTION_PROPERTY)) {
                    if (!prop.getCardinality().equals("+")) {
                        // Uni-selection property.
                        try {
                            List<Selection> list = prop.getAllSelectedSelections();
                            if (!list.isEmpty()) {
                                Selection sel = list.get(0);
                                resultList.add((selectionOption.equals("name") ? sel.getName() : sel.getValue()));
                            } else {
                                return Operand.NULL;
                            }
                        } catch (com.dexels.navajo.document.NavajoException te) {
                            throw new TMLExpressionException(te.getMessage());
                        }
                    } else {
                        // Multi-selection property.
                        try {
                            List<Selection> list = prop.getAllSelectedSelections();
                            List<Object> result = new ArrayList<>();
                            for (int i = 0; i < list.size(); i++) {
                                Selection sel = list.get(i);
                                Object o = (selectionOption.equals("name")) ? sel.getName() : sel.getValue();
                                result.add(o);
                            }
                            resultList.add(result);
                        } catch (NavajoException te) {
                            throw new TMLExpressionException(te.getMessage(), te);
                        }
                    }
                } else if (type.equals(Property.DATE_PROPERTY)) {
                    if (value == null)
                        resultList.add(null);
                    else {
                        if (!option.equals("")) {
                            try {
                                Date a = (Date) prop.getTypedValue();
                                Calendar cal = Calendar.getInstance();
                                cal.setTime(a);
                                int altA = 0;
                                if (option.equals("month")) {
                                    altA = cal.get(Calendar.MONTH) + 1;
                                } else if (option.equals("day")) {
                                    altA = cal.get(Calendar.DAY_OF_MONTH);
                                } else if (option.equals("year")) {
                                    altA = cal.get(Calendar.YEAR);
                                } else if (option.equals("hour")) {
                                    altA = cal.get(Calendar.HOUR_OF_DAY);
                                } else if (option.equals("minute")) {
                                    altA = cal.get(Calendar.MINUTE);
                                } else if (option.equals("second")) {
                                    altA = cal.get(Calendar.SECOND);
                                } else {
                                    throw new TMLExpressionException("Option not supported: " + option + ", for type: " + type);
                                }
                                resultList.add(altA);
                            } catch (Exception ue) {
                                throw new TMLExpressionException("Invalid date: " + prop.getValue(), ue);
                            }
                        } else {
                            try {
                                Date a = (Date) prop.getTypedValue();
                                resultList.add(a);
                            } catch (java.lang.Exception pe) {
                                resultList.add(null);
                            }
                        }
                    }
                } else if (type.equals(Property.EXPRESSION_PROPERTY)) {
                    resultList.add(prop.getTypedValue());
                } else {
                    try {
                        resultList.add(value);
                    } catch (Exception e) {
                        throw new TMLExpressionException(e.getMessage(), e);
                    }
                }
            }
            if (!singleMatch)
                return Operand.ofList(resultList);
            else if (!resultList.isEmpty())
                return Operand.ofDynamic(resultList.get(0));
            else if (!exists)
                throw new TMLExpressionException("Property does not exist: " + text);
            else
                return Operand.FALSE;
        }

        private Operand parseImmutablePath(String text, ImmutableMessage rm) {
            if ("".equals(text) || "/@".equals(text)) {
                return Operand.ofImmutable(rm);
            }
            if (text.endsWith("/")) {
                String trunc = text.substring(0, text.length() - 1);
                List<String> parts = Arrays.asList(trunc.split("/"));
                return parseImmutableMessagePath(parts, rm);
            }
            List<String> parts = Arrays.asList(text.split("/"));
            return parseImmutablePath(parts, rm);
        }

        private Operand parseImmutableMessagePath(List<String> path, ImmutableMessage rm) {
            if (path.isEmpty()) {
                return Operand.ofImmutable(rm);
            }
            String first = path.get(0);
            Optional<ImmutableMessage> sub = rm.subMessage(first);
            if (!sub.isPresent()) {
                throw new TMLExpressionException("Missing submessage: " + first);
            }
            List<String> copy = new ArrayList<>(path);
            copy.remove(0);
            return parseImmutableMessagePath(copy, sub.get());
        }

        private Operand parseImmutablePath(List<String> path, ImmutableMessage rm) {
            if (path.size() > 1) {
                Optional<ImmutableMessage> imm = rm.subMessage(path.get(0));
                if (imm.isPresent()) {
                    List<String> parts = new LinkedList<>(path);
                    parts.remove(0);
                    return parseImmutablePath(parts, imm.get());
                }
                return null;
            }
            String type = rm.columnType(path.get(0));
            if (type != null) {
                return Operand.ofCustom(rm.value(path.get(0)).orElse(null), type);
            }
            return Operand.ofDynamic(rm.value(path.get(0)).orElse(null));
        }

        @Override
        public Optional<String> returnType() {
            return Optional.empty();
        }

        @Override
        public String expression() {
            return expression;
        }
    };
}
Also used : Arrays(java.util.Arrays) Date(java.util.Date) NavajoException(com.dexels.navajo.document.NavajoException) Function(java.util.function.Function) ArrayList(java.util.ArrayList) ClockTime(com.dexels.navajo.document.types.ClockTime) TMLExpressionException(com.dexels.navajo.expression.api.TMLExpressionException) Util(com.dexels.navajo.util.Util) Calendar(java.util.Calendar) Operand(com.dexels.navajo.document.Operand) Selection(com.dexels.navajo.document.Selection) LinkedList(java.util.LinkedList) ImmutableMessage(com.dexels.immutable.api.ImmutableMessage) Navajo(com.dexels.navajo.document.Navajo) TipiLink(com.dexels.navajo.expression.api.TipiLink) Access(com.dexels.navajo.script.api.Access) NavajoType(com.dexels.navajo.document.types.NavajoType) Message(com.dexels.navajo.document.Message) ContextExpression(com.dexels.navajo.expression.api.ContextExpression) ImmutableFactory(com.dexels.immutable.factory.ImmutableFactory) List(java.util.List) FunctionClassification(com.dexels.navajo.expression.api.FunctionClassification) Optional(java.util.Optional) Property(com.dexels.navajo.document.Property) MappableTreeNode(com.dexels.navajo.script.api.MappableTreeNode) MappableTreeNode(com.dexels.navajo.script.api.MappableTreeNode) ImmutableMessage(com.dexels.immutable.api.ImmutableMessage) Message(com.dexels.navajo.document.Message) Selection(com.dexels.navajo.document.Selection) Access(com.dexels.navajo.script.api.Access) ArrayList(java.util.ArrayList) TMLExpressionException(com.dexels.navajo.expression.api.TMLExpressionException) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) Property(com.dexels.navajo.document.Property) Optional(java.util.Optional) NavajoType(com.dexels.navajo.document.types.NavajoType) ContextExpression(com.dexels.navajo.expression.api.ContextExpression) Calendar(java.util.Calendar) NavajoException(com.dexels.navajo.document.NavajoException) Navajo(com.dexels.navajo.document.Navajo) ClockTime(com.dexels.navajo.document.types.ClockTime) NavajoException(com.dexels.navajo.document.NavajoException) TMLExpressionException(com.dexels.navajo.expression.api.TMLExpressionException) Date(java.util.Date) LinkedList(java.util.LinkedList) TipiLink(com.dexels.navajo.expression.api.TipiLink) ImmutableMessage(com.dexels.immutable.api.ImmutableMessage)

Aggregations

ContextExpression (com.dexels.navajo.expression.api.ContextExpression)3 FunctionClassification (com.dexels.navajo.expression.api.FunctionClassification)3 MappableTreeNode (com.dexels.navajo.script.api.MappableTreeNode)3 ImmutableMessage (com.dexels.immutable.api.ImmutableMessage)2 Message (com.dexels.navajo.document.Message)2 Navajo (com.dexels.navajo.document.Navajo)2 Operand (com.dexels.navajo.document.Operand)2 Selection (com.dexels.navajo.document.Selection)2 TipiLink (com.dexels.navajo.expression.api.TipiLink)2 NamedExpression (com.dexels.navajo.parser.NamedExpression)2 Access (com.dexels.navajo.script.api.Access)2 ArrayList (java.util.ArrayList)2 Arrays (java.util.Arrays)2 HashMap (java.util.HashMap)2 LinkedList (java.util.LinkedList)2 List (java.util.List)2 Optional (java.util.Optional)2 Function (java.util.function.Function)2 ImmutableFactory (com.dexels.immutable.factory.ImmutableFactory)1 NavajoException (com.dexels.navajo.document.NavajoException)1