001package jmri.jmrit.logixng.util.parser.functions;
002
003import java.util.*;
004
005import jmri.JmriException;
006import jmri.jmrit.logixng.SymbolTable;
007import jmri.jmrit.logixng.util.parser.*;
008
009import org.openide.util.lookup.ServiceProvider;
010
011/**
012 * Implementation of common functions.
013 *
014 * @author Daniel Bergqvist 2024
015 */
016@ServiceProvider(service = FunctionFactory.class)
017public class CommonFunctions implements FunctionFactory {
018
019    @Override
020    public String getModule() {
021        return "Common";
022    }
023
024    @Override
025    public Set<Function> getFunctions() {
026        Set<Function> functionClasses = new HashSet<>();
027
028        addLengthFunction(functionClasses);
029
030        return functionClasses;
031    }
032
033    @Override
034    public Set<Constant> getConstants() {
035        return new HashSet<>();
036    }
037
038    @Override
039    public String getConstantDescription() {
040        // This module doesn't define any constants
041        return null;
042    }
043
044    private void addLengthFunction(Set<Function> functionClasses) {
045        functionClasses.add(new AbstractFunction(this, "length", Bundle.getMessage("Common.length_Descr")) {
046            @SuppressWarnings("rawtypes")   // We don't know the generic types of Collection and Map in this method
047            @Override
048            public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList)
049                    throws CalculateException, JmriException {
050                if (parameterList.size() != 1) {
051                    throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters1", getName(), 1));
052                }
053
054                Object parameter = parameterList.get(0).calculate(symbolTable);
055
056                if (parameter == null) {
057                    throw new NullPointerException("Parameter is null");
058                } else if (parameter instanceof String) {
059                    return ((String)parameter).length();
060                } else if (parameter.getClass().isArray()) {
061                    return ((Object[])parameter).length;
062                } else if (parameter instanceof Collection) {
063                    return ((Collection)parameter).size();
064                } else if (parameter instanceof Map) {
065                    return ((Map)parameter).size();
066                }
067
068                throw new IllegalArgumentException("Parameter is not a String, Array, List, Set or Map: "+parameter.getClass().getName());
069            }
070        });
071    }
072
073}