001package jmri.jmrit.logixng.util.parser;
002
003import java.lang.reflect.Array;
004import java.util.*;
005
006import jmri.JmriException;
007import jmri.jmrit.logixng.SymbolTable;
008import jmri.util.TypeConversionUtil;
009
010/**
011 * A parsed expression
012 *
013 * @author Daniel Bergqvist 2021
014 */
015public class ExpressionNodeArray implements ExpressionNodeWithParameter {
016
017    private final ExpressionNode _exprNode;
018
019    public ExpressionNodeArray(ExpressionNode exprNode) throws FunctionNotExistsException {
020        _exprNode = exprNode;
021    }
022
023    @SuppressWarnings("unchecked")
024    @Override
025    public Object calculate(Object parameter, SymbolTable symbolTable) throws JmriException {
026        if (parameter == null) throw new NullPointerException("Parameter is null");
027
028        int index = (int) TypeConversionUtil.convertToLong(_exprNode.calculate(symbolTable));
029
030        // JSON array node
031        if (parameter instanceof com.fasterxml.jackson.databind.node.ArrayNode) {
032            return ((com.fasterxml.jackson.databind.node.ArrayNode)parameter).get(index);
033        }
034
035        if (parameter.getClass().isArray()) {
036            return Array.get(parameter, index);
037        } else if (parameter instanceof List) {
038            return ((List<Object>)parameter).get(index);
039        } else {
040            throw new IllegalArgumentException("Parameter is not a List nor an array");
041        }
042    }
043
044    /** {@inheritDoc} */
045    @Override
046    public boolean canBeAssigned() {
047        // We don't know so we assume that it is.
048        return true;
049    }
050
051    /**
052     * Assign a value to this expression from a parameter.
053     * @param parameter the parameter
054     * @param symbolTable the symbol table
055     * @param value the value to assign
056     * @throws jmri.JmriException if an error occurs
057     */
058    @SuppressWarnings("unchecked")
059    @Override
060    public void assignValue(Object parameter, SymbolTable symbolTable, Object value) throws JmriException {
061        int index = (int) TypeConversionUtil.convertToLong(_exprNode.calculate(symbolTable));
062
063        if (parameter == null) throw new NullPointerException("Parameter is null");
064
065        if (parameter.getClass().isArray()) {
066            Array.set(parameter, index, value);
067        } else if (parameter instanceof List) {
068            ((List<Object>)parameter).set(index, value);
069        } else {
070            throw new IllegalArgumentException("Parameter is not a List nor an array");
071        }
072    }
073
074    /** {@inheritDoc} */
075    @Override
076    public String getDefinitionString() {
077        StringBuilder str = new StringBuilder();
078        str.append("[");
079        str.append(_exprNode.getDefinitionString());
080        str.append("]");
081        return str.toString();
082    }
083
084}