001package jmri.jmrit.logixng.util.parser.functions;
002
003import java.util.*;
004
005import jmri.InstanceManager;
006import jmri.JmriException;
007import jmri.Memory;
008import jmri.MemoryManager;
009import jmri.jmrit.logixng.NamedTableManager;
010import jmri.jmrit.logixng.SymbolTable;
011import jmri.jmrit.logixng.util.ReferenceUtil;
012import jmri.jmrit.logixng.util.parser.*;
013import jmri.util.TypeConversionUtil;
014
015import org.openide.util.lookup.ServiceProvider;
016
017/**
018 * Implementation of NamedBean functions.
019 *
020 * @author Daniel Bergqvist 2020
021 */
022@ServiceProvider(service = FunctionFactory.class)
023public class NamedBeanFunctions implements FunctionFactory {
024
025    @Override
026    public String getModule() {
027        return "NamedBean";
028    }
029
030    @Override
031    public Set<Function> getFunctions() {
032        Set<Function> functionClasses = new HashSet<>();
033
034        addGetLogixNGTableFunction(functionClasses);
035        addReadMemoryFunction(functionClasses);
036        addEvaluateMemoryFunction(functionClasses);
037        addWriteMemoryFunction(functionClasses);
038
039        return functionClasses;
040    }
041
042    @Override
043    public Set<Constant> getConstants() {
044        return new HashSet<>();
045    }
046
047    @Override
048    public String getConstantDescription() {
049        // This module doesn't define any constants
050        return null;
051    }
052
053    private void addGetLogixNGTableFunction(Set<Function> functionClasses) {
054        functionClasses.add(new AbstractFunction(this, "getLogixNGTable", Bundle.getMessage("NamedBean.getLogixNGTable_Descr")) {
055            @Override
056            public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList)
057                    throws JmriException {
058
059                if (parameterList.size() != 1) {
060                    throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1));
061                }
062
063                Object value = parameterList.get(0).calculate(symbolTable);
064                if (value == null) return null;
065
066                String s = TypeConversionUtil.convertToString(value, false);
067                if (s.isEmpty()) return null;
068
069                return InstanceManager.getDefault(NamedTableManager.class).getNamedBean(s);
070            }
071        });
072    }
073
074    private void addReadMemoryFunction(Set<Function> functionClasses) {
075        functionClasses.add(new AbstractFunction(this, "readMemory", Bundle.getMessage("NamedBean.readMemory_Descr")) {
076            @Override
077            public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList)
078                    throws JmriException {
079
080                if (parameterList.size() != 1) {
081                    throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1));
082                }
083
084                Object value = parameterList.get(0).calculate(symbolTable);
085                if (value == null) return null;
086
087                String s = TypeConversionUtil.convertToString(value, false);
088                if (s.isEmpty()) return null;
089
090                Memory m = InstanceManager.getDefault(MemoryManager.class).getNamedBean(s);
091                if (m == null) return null;
092                return m.getValue();
093            }
094        });
095    }
096
097    private void addEvaluateMemoryFunction(Set<Function> functionClasses) {
098        functionClasses.add(new AbstractFunction(this, "evaluateMemory", Bundle.getMessage("NamedBean.evaluateMemory_Descr")) {
099            @Override
100            public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList)
101                    throws JmriException {
102
103                if (parameterList.size() != 1) {
104                    throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1));
105                }
106
107                Object value = parameterList.get(0).calculate(symbolTable);
108                if (value == null) return null;
109
110                String s = TypeConversionUtil.convertToString(value, false);
111                if (s.isEmpty()) return null;
112
113                Memory m = InstanceManager.getDefault(MemoryManager.class).getNamedBean(s);
114                if (m == null) return null;
115                value = m.getValue();
116
117                if ((value instanceof String) && ReferenceUtil.isReference((String)value)) {
118                    return ReferenceUtil.getReference(symbolTable, (String)value);
119                }
120
121                return value;
122            }
123        });
124    }
125
126    private void addWriteMemoryFunction(Set<Function> functionClasses) {
127        functionClasses.add(new AbstractFunction(this, "writeMemory", Bundle.getMessage("NamedBean.writeMemory_Descr")) {
128            @Override
129            public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList)
130                    throws JmriException {
131
132                if (parameterList.size() != 2) {
133                    throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1));
134                }
135
136                Object memoryName = parameterList.get(0).calculate(symbolTable);
137                if (memoryName == null) return null;
138
139                String s = TypeConversionUtil.convertToString(memoryName, false);
140                if (s.isEmpty()) return null;
141
142                Memory m = InstanceManager.getDefault(MemoryManager.class).getNamedBean(s);
143                if (m == null) return null;
144
145                Object value = parameterList.get(1).calculate(symbolTable);
146                m.setValue(value);
147
148                return value;
149            }
150        });
151    }
152
153}