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        addEvaluateReferenceFunction(functionClasses);
039
040        return functionClasses;
041    }
042
043    @Override
044    public Set<Constant> getConstants() {
045        return new HashSet<>();
046    }
047
048    @Override
049    public String getConstantDescription() {
050        // This module doesn't define any constants
051        return null;
052    }
053
054    private void addGetLogixNGTableFunction(Set<Function> functionClasses) {
055        functionClasses.add(new AbstractFunction(this, "getLogixNGTable", Bundle.getMessage("NamedBean.getLogixNGTable_Descr")) {
056            @Override
057            public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList)
058                    throws JmriException {
059
060                if (parameterList.size() != 1) {
061                    throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1));
062                }
063
064                Object value = parameterList.get(0).calculate(symbolTable);
065                if (value == null) return null;
066
067                String s = TypeConversionUtil.convertToString(value, false);
068                if (s.isEmpty()) return null;
069
070                return InstanceManager.getDefault(NamedTableManager.class).getNamedBean(s);
071            }
072        });
073    }
074
075    private void addReadMemoryFunction(Set<Function> functionClasses) {
076        functionClasses.add(new AbstractFunction(this, "readMemory", Bundle.getMessage("NamedBean.readMemory_Descr")) {
077            @Override
078            public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList)
079                    throws JmriException {
080
081                if (parameterList.size() != 1) {
082                    throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1));
083                }
084
085                Object value = parameterList.get(0).calculate(symbolTable);
086                if (value == null) return null;
087
088                String s = TypeConversionUtil.convertToString(value, false);
089                if (s.isEmpty()) return null;
090
091                Memory m = InstanceManager.getDefault(MemoryManager.class).getNamedBean(s);
092                if (m == null) return null;
093                return m.getValue();
094            }
095        });
096    }
097
098    private void addEvaluateMemoryFunction(Set<Function> functionClasses) {
099        functionClasses.add(new AbstractFunction(this, "evaluateMemory", Bundle.getMessage("NamedBean.evaluateMemory_Descr")) {
100            @Override
101            public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList)
102                    throws JmriException {
103
104                if (parameterList.size() != 1) {
105                    throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1));
106                }
107
108                Object value = parameterList.get(0).calculate(symbolTable);
109                if (value == null) return null;
110
111                String s = TypeConversionUtil.convertToString(value, false);
112                if (s.isEmpty()) return null;
113
114                Memory m = InstanceManager.getDefault(MemoryManager.class).getNamedBean(s);
115                if (m == null) return null;
116                value = m.getValue();
117
118                if ((value instanceof String) && ReferenceUtil.isReference((String)value)) {
119                    return ReferenceUtil.getReference(symbolTable, (String)value);
120                }
121
122                return value;
123            }
124        });
125    }
126
127    private void addWriteMemoryFunction(Set<Function> functionClasses) {
128        functionClasses.add(new AbstractFunction(this, "writeMemory", Bundle.getMessage("NamedBean.writeMemory_Descr")) {
129            @Override
130            public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList)
131                    throws JmriException {
132
133                if (parameterList.size() != 2) {
134                    throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1));
135                }
136
137                Object memoryName = parameterList.get(0).calculate(symbolTable);
138                if (memoryName == null) return null;
139
140                String s = TypeConversionUtil.convertToString(memoryName, false);
141                if (s.isEmpty()) return null;
142
143                Memory m = InstanceManager.getDefault(MemoryManager.class).getNamedBean(s);
144                if (m == null) return null;
145
146                Object value = parameterList.get(1).calculate(symbolTable);
147                m.setValue(value);
148
149                return value;
150            }
151        });
152    }
153
154    private void addEvaluateReferenceFunction(Set<Function> functionClasses) {
155        functionClasses.add(new AbstractFunction(this, "evaluateReference", Bundle.getMessage("NamedBean.evaluateReference_Descr")) {
156            @Override
157            public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList)
158                    throws JmriException {
159
160                if (parameterList.size() != 1) {
161                    throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1));
162                }
163
164                Object value = parameterList.get(0).calculate(symbolTable);
165                if (value == null) return null;
166
167                String s = TypeConversionUtil.convertToString(value, false);
168                if (s.isEmpty()) return null;
169
170                if (ReferenceUtil.isReference(s)) {
171                    return ReferenceUtil.getReference(symbolTable, s);
172                }
173
174                return value;
175            }
176        });
177    }
178
179}