001package jmri.jmrit.logixng.util;
002
003import java.beans.PropertyChangeEvent;
004import java.beans.PropertyVetoException;
005import java.beans.VetoableChangeListener;
006import java.util.HashMap;
007import java.util.Locale;
008import java.util.Map;
009
010import javax.annotation.Nonnull;
011
012import jmri.*;
013import jmri.jmrit.logixng.*;
014import jmri.jmrit.logixng.implementation.AbstractBase;
015import jmri.jmrit.logixng.util.parser.*;
016import jmri.jmrit.logixng.util.parser.RecursiveDescentParser;
017import jmri.util.TypeConversionUtil;
018
019/**
020 * Select table for LogixNG actions and expressions.
021 * @author Daniel Bergqvist (C) 2022
022 */
023public class LogixNG_SelectTable implements VetoableChangeListener {
024
025    private final AbstractBase _base;
026    private final InUse _inUse;
027
028    private NamedBeanAddressing _tableNameAddressing = NamedBeanAddressing.Direct;
029    private NamedBeanHandle<NamedTable> _tableHandle;
030    private String _tableNameReference = "";
031    private NamedBeanHandle<Memory> _tableNameMemoryHandle;
032    private String _tableNameLocalVariable = "";
033    private String _tableNameFormula = "";
034    private ExpressionNode _tableNameExpressionNode;
035    private LogixNG_SelectTable _tableNameSelectTable;
036
037    private NamedBeanAddressing _tableRowAddressing = NamedBeanAddressing.Direct;
038    private String _tableRowName = "";
039    private String _tableRowReference = "";
040    private NamedBeanHandle<Memory> _tableRowMemoryHandle;
041    private String _tableRowLocalVariable = "";
042    private String _tableRowFormula = "";
043    private ExpressionNode _tableRowExpressionNode;
044    private LogixNG_SelectTable _tableRowSelectTable;
045
046    private NamedBeanAddressing _tableColumnAddressing = NamedBeanAddressing.Direct;
047    private String _tableColumnName = "";
048    private String _tableColumnReference = "";
049    private NamedBeanHandle<Memory> _tableColumnMemoryHandle;
050    private String _tableColumnLocalVariable = "";
051    private String _tableColumnFormula = "";
052    private ExpressionNode _tableColumnExpressionNode;
053    private LogixNG_SelectTable _tableColumnSelectTable;
054
055
056    public LogixNG_SelectTable(AbstractBase base, InUse inUse) {
057        _base = base;
058        _inUse = inUse;
059    }
060
061
062    public void copy(LogixNG_SelectTable copy) throws ParserException {
063        copy.setTableNameAddressing(_tableNameAddressing);
064        if (_tableHandle != null) copy.setTable(_tableHandle);
065        copy.setTableNameLocalVariable(_tableNameLocalVariable);
066        copy.setTableNameReference(_tableNameReference);
067        copy.setTableNameMemory(_tableNameMemoryHandle);
068        copy.setTableNameFormula(_tableNameFormula);
069        if (_tableNameSelectTable != null) {
070            _tableNameSelectTable.copy(copy._tableNameSelectTable);
071        }
072
073        copy.setTableRowAddressing(_tableRowAddressing);
074        copy.setTableRowName(_tableRowName);
075        copy.setTableRowLocalVariable(_tableRowLocalVariable);
076        copy.setTableRowReference(_tableRowReference);
077        copy.setTableRowMemory(_tableRowMemoryHandle);
078        copy.setTableRowFormula(_tableRowFormula);
079        if (_tableRowSelectTable != null) {
080            _tableRowSelectTable.copy(copy._tableRowSelectTable);
081        }
082
083        copy.setTableColumnAddressing(_tableColumnAddressing);
084        copy.setTableColumnName(_tableColumnName);
085        copy.setTableColumnLocalVariable(_tableColumnLocalVariable);
086        copy.setTableColumnReference(_tableColumnReference);
087        copy.setTableColumnMemory(_tableColumnMemoryHandle);
088        copy.setTableColumnFormula(_tableColumnFormula);
089        if (_tableColumnSelectTable != null) {
090            _tableColumnSelectTable.copy(copy._tableColumnSelectTable);
091        }
092    }
093
094    public void setTableNameAddressing(@Nonnull NamedBeanAddressing addressing) {
095        this._tableNameAddressing = addressing;
096        synchronized(this) {
097            if ((_tableNameAddressing == NamedBeanAddressing.Table) && (_tableNameSelectTable == null)) {
098                _tableNameSelectTable = new LogixNG_SelectTable(_base, _inUse);
099            }
100        }
101    }
102
103    public NamedBeanAddressing getTableNameAddressing() {
104        return _tableNameAddressing;
105    }
106
107    public void setTable(@Nonnull NamedBeanHandle<NamedTable> handle) {
108        _base.assertListenersAreNotRegistered(log, "setTable");
109        _tableHandle = handle;
110        InstanceManager.getDefault(NamedTableManager.class).addVetoableChangeListener(this);
111    }
112
113    public void setTable(@Nonnull NamedTable table) {
114        _base.assertListenersAreNotRegistered(log, "setTable");
115        setTable(InstanceManager.getDefault(NamedBeanHandleManager.class)
116                .getNamedBeanHandle(table.getDisplayName(), table));
117    }
118
119    public void removeTable() {
120        _base.assertListenersAreNotRegistered(log, "setTable");
121        if (_tableHandle != null) {
122            InstanceManager.getDefault(NamedTableManager.class).removeVetoableChangeListener(this);
123            _tableHandle = null;
124        }
125    }
126
127    public NamedBeanHandle<NamedTable> getTable() {
128        return _tableHandle;
129    }
130
131    public void setTableNameReference(@Nonnull String reference) {
132        if ((! reference.isEmpty()) && (! ReferenceUtil.isReference(reference))) {
133            throw new IllegalArgumentException("The reference \"" + reference + "\" is not a valid reference");
134        }
135        _tableNameReference = reference;
136    }
137
138    public String getTableNameReference() {
139        return _tableNameReference;
140    }
141
142    public void setTableNameMemory(@Nonnull String memoryName) {
143        Memory memory = InstanceManager.getDefault(MemoryManager.class).getMemory(memoryName);
144        if (memory != null) {
145            setTableNameMemory(memory);
146        } else {
147            removeTableNameMemory();
148            log.warn("memory \"{}\" is not found", memoryName);
149        }
150    }
151
152    public void setTableNameMemory(@Nonnull NamedBeanHandle<Memory> handle) {
153        _tableNameMemoryHandle = handle;
154        addRemoveVetoListener();
155    }
156
157    public void setTableNameMemory(@Nonnull Memory memory) {
158        setTableNameMemory(InstanceManager.getDefault(NamedBeanHandleManager.class)
159                .getNamedBeanHandle(memory.getDisplayName(), memory));
160    }
161
162    public void removeTableNameMemory() {
163        if (_tableNameMemoryHandle != null) {
164            _tableNameMemoryHandle = null;
165            addRemoveVetoListener();
166        }
167    }
168
169    public NamedBeanHandle<Memory> getTableNameMemory() {
170        return _tableNameMemoryHandle;
171    }
172
173    public void setTableNameLocalVariable(@Nonnull String localVariable) {
174        _tableNameLocalVariable = localVariable;
175    }
176
177    public String getTableNameLocalVariable() {
178        return _tableNameLocalVariable;
179    }
180
181    public void setTableNameFormula(@Nonnull String formula) throws ParserException {
182        _tableNameFormula = formula;
183        parseTableNameFormula();
184    }
185
186    public String getTableNameFormula() {
187        return _tableNameFormula;
188    }
189
190    private void parseTableNameFormula() throws ParserException {
191        if (_tableNameAddressing == NamedBeanAddressing.Formula) {
192            Map<String, Variable> variables = new HashMap<>();
193
194            RecursiveDescentParser parser = new RecursiveDescentParser(variables);
195            _tableNameExpressionNode = parser.parseExpression(_tableNameFormula);
196        } else {
197            _tableNameExpressionNode = null;
198        }
199    }
200
201    public LogixNG_SelectTable getSelectTableName() {
202        synchronized(this) {
203            if (_tableNameSelectTable == null) {
204                _tableNameSelectTable = new LogixNG_SelectTable(_base, _inUse);
205            }
206        }
207        return _tableNameSelectTable;
208    }
209
210    public void setTableRowAddressing(@Nonnull NamedBeanAddressing addressing) {
211        this._tableRowAddressing = addressing;
212        synchronized(this) {
213            if ((_tableRowAddressing == NamedBeanAddressing.Table) && (_tableRowSelectTable == null)) {
214                _tableRowSelectTable = new LogixNG_SelectTable(_base, _inUse);
215            }
216        }
217    }
218
219    public NamedBeanAddressing getTableRowAddressing() {
220        return _tableRowAddressing;
221    }
222
223    /**
224     * Get name of row
225     * @return name
226     */
227    public String getTableRowName() {
228        return _tableRowName;
229    }
230
231    /**
232     * Set name of column
233     * @param rowName name
234     */
235    public void setTableRowName(@Nonnull String rowName) {
236        _tableRowName = rowName;
237    }
238
239    public void setTableRowReference(@Nonnull String reference) {
240        if ((! reference.isEmpty()) && (! ReferenceUtil.isReference(reference))) {
241            throw new IllegalArgumentException("The reference \"" + reference + "\" is not a valid reference");
242        }
243        _tableRowReference = reference;
244    }
245
246    public String getTableRowReference() {
247        return _tableRowReference;
248    }
249
250    public void setTableRowMemory(@Nonnull String memoryName) {
251        Memory memory = InstanceManager.getDefault(MemoryManager.class).getMemory(memoryName);
252        if (memory != null) {
253            setTableRowMemory(memory);
254        } else {
255            removeTableRowMemory();
256            log.warn("memory \"{}\" is not found", memoryName);
257        }
258    }
259
260    public void setTableRowMemory(@Nonnull NamedBeanHandle<Memory> handle) {
261        _tableRowMemoryHandle = handle;
262        addRemoveVetoListener();
263    }
264
265    public void setTableRowMemory(@Nonnull Memory memory) {
266        setTableRowMemory(InstanceManager.getDefault(NamedBeanHandleManager.class)
267                .getNamedBeanHandle(memory.getDisplayName(), memory));
268    }
269
270    public void removeTableRowMemory() {
271        if (_tableRowMemoryHandle != null) {
272            _tableRowMemoryHandle = null;
273            addRemoveVetoListener();
274        }
275    }
276
277    public NamedBeanHandle<Memory> getTableRowMemory() {
278        return _tableRowMemoryHandle;
279    }
280
281    public void setTableRowLocalVariable(@Nonnull String localVariable) {
282        _tableRowLocalVariable = localVariable;
283    }
284
285    public String getTableRowLocalVariable() {
286        return _tableRowLocalVariable;
287    }
288
289    public void setTableRowFormula(@Nonnull String formula) throws ParserException {
290        _tableRowFormula = formula;
291        parseTableRowFormula();
292    }
293
294    public String getTableRowFormula() {
295        return _tableRowFormula;
296    }
297
298    private void parseTableRowFormula() throws ParserException {
299        if (_tableRowAddressing == NamedBeanAddressing.Formula) {
300            Map<String, Variable> variables = new HashMap<>();
301
302            RecursiveDescentParser parser = new RecursiveDescentParser(variables);
303            _tableRowExpressionNode = parser.parseExpression(_tableRowFormula);
304        } else {
305            _tableRowExpressionNode = null;
306        }
307    }
308
309    public LogixNG_SelectTable getSelectTableRow() {
310        synchronized(this) {
311            if (_tableRowSelectTable == null) {
312                _tableRowSelectTable = new LogixNG_SelectTable(_base, _inUse);
313            }
314        }
315        return _tableRowSelectTable;
316    }
317
318    public void setTableColumnAddressing(@Nonnull NamedBeanAddressing addressing) {
319        this._tableColumnAddressing = addressing;
320        synchronized(this) {
321            if ((_tableColumnAddressing == NamedBeanAddressing.Table) && (_tableColumnSelectTable == null)) {
322                _tableColumnSelectTable = new LogixNG_SelectTable(_base, _inUse);
323            }
324        }
325    }
326
327    public NamedBeanAddressing getTableColumnAddressing() {
328        return _tableColumnAddressing;
329    }
330
331    public void setTableColumnReference(@Nonnull String reference) {
332        if ((! reference.isEmpty()) && (! ReferenceUtil.isReference(reference))) {
333            throw new IllegalArgumentException("The reference \"" + reference + "\" is not a valid reference");
334        }
335        _tableColumnReference = reference;
336    }
337
338    public String getTableColumnReference() {
339        return _tableColumnReference;
340    }
341
342    public void setTableColumnMemory(@Nonnull String memoryName) {
343        Memory memory = InstanceManager.getDefault(MemoryManager.class).getMemory(memoryName);
344        if (memory != null) {
345            setTableColumnMemory(memory);
346        } else {
347            removeTableColumnMemory();
348            log.warn("memory \"{}\" is not found", memoryName);
349        }
350    }
351
352    public void setTableColumnMemory(@Nonnull NamedBeanHandle<Memory> handle) {
353        _tableColumnMemoryHandle = handle;
354        addRemoveVetoListener();
355    }
356
357    public void setTableColumnMemory(@Nonnull Memory memory) {
358        setTableColumnMemory(InstanceManager.getDefault(NamedBeanHandleManager.class)
359                .getNamedBeanHandle(memory.getDisplayName(), memory));
360    }
361
362    public void removeTableColumnMemory() {
363        if (_tableColumnMemoryHandle != null) {
364            _tableColumnMemoryHandle = null;
365            addRemoveVetoListener();
366        }
367    }
368
369    public NamedBeanHandle<Memory> getTableColumnMemory() {
370        return _tableColumnMemoryHandle;
371    }
372
373    public void setTableColumnLocalVariable(@Nonnull String localVariable) {
374        _tableColumnLocalVariable = localVariable;
375    }
376
377    public String getTableColumnLocalVariable() {
378        return _tableColumnLocalVariable;
379    }
380
381    public void setTableColumnFormula(@Nonnull String formula) throws ParserException {
382        _tableColumnFormula = formula;
383        parseTableColumnFormula();
384    }
385
386    public String getTableColumnFormula() {
387        return _tableColumnFormula;
388    }
389
390    private void parseTableColumnFormula() throws ParserException {
391        if (_tableColumnAddressing == NamedBeanAddressing.Formula) {
392            Map<String, Variable> variables = new HashMap<>();
393
394            RecursiveDescentParser parser = new RecursiveDescentParser(variables);
395            _tableColumnExpressionNode = parser.parseExpression(_tableColumnFormula);
396        } else {
397            _tableColumnExpressionNode = null;
398        }
399    }
400
401    /**
402     * Get name of column
403     * @return name
404     */
405    public String getTableColumnName() {
406        return _tableColumnName;
407    }
408
409    /**
410     * Set name of column
411     * @param columnName name
412     */
413    public void setTableColumnName(@Nonnull String columnName) {
414        _tableColumnName = columnName;
415    }
416
417    public LogixNG_SelectTable getSelectTableColumn() {
418        synchronized(this) {
419            if (_tableColumnSelectTable == null) {
420                _tableColumnSelectTable = new LogixNG_SelectTable(_base, _inUse);
421            }
422        }
423        return _tableColumnSelectTable;
424    }
425
426    private void addRemoveVetoListener() {
427        if ((_tableNameMemoryHandle != null) || (_tableRowMemoryHandle != null) || (_tableColumnMemoryHandle != null)) {
428            InstanceManager.getDefault(MemoryManager.class).addVetoableChangeListener(this);
429        } else {
430            InstanceManager.getDefault(MemoryManager.class).removeVetoableChangeListener(this);
431        }
432    }
433
434    @Override
435    public void vetoableChange(java.beans.PropertyChangeEvent evt) throws java.beans.PropertyVetoException {
436        if ("CanDelete".equals(evt.getPropertyName()) && _inUse.isInUse()) { // No I18N
437            if (evt.getOldValue() instanceof NamedTable) {
438                if (evt.getOldValue().equals(getTable().getBean())) {
439                    throw new PropertyVetoException(_base.getDisplayName(), evt);
440                }
441            }
442            if (evt.getOldValue() instanceof Memory) {
443                boolean doVeto = false;
444                if ((_tableNameAddressing == NamedBeanAddressing.Memory) && (_tableNameMemoryHandle != null) && evt.getOldValue().equals(_tableNameMemoryHandle.getBean())) {
445                    doVeto = true;
446                }
447                if ((_tableRowAddressing == NamedBeanAddressing.Memory) && (_tableRowMemoryHandle != null) && evt.getOldValue().equals(_tableRowMemoryHandle.getBean())) {
448                    doVeto = true;
449                }
450                if ((_tableColumnAddressing == NamedBeanAddressing.Memory) && (_tableColumnMemoryHandle != null) && evt.getOldValue().equals(_tableColumnMemoryHandle.getBean())) {
451                    doVeto = true;
452                }
453                if (doVeto) {
454                    PropertyChangeEvent e = new PropertyChangeEvent(this, "DoNotDelete", null, null);
455                    throw new PropertyVetoException(Bundle.getMessage("MemoryInUseMemoryExpressionVeto", _base.getDisplayName()), e); // NOI18N
456                }
457            }
458        } else if ("DoDelete".equals(evt.getPropertyName())) { // No I18N
459            if (evt.getOldValue() instanceof NamedTable) {
460                if (evt.getOldValue().equals(getTable().getBean())) {
461                    removeTable();
462                }
463            }
464            if (evt.getOldValue() instanceof Memory) {
465                if (evt.getOldValue().equals(_tableNameMemoryHandle.getBean())) {
466                    removeTableNameMemory();
467                }
468                if (evt.getOldValue().equals(_tableRowMemoryHandle.getBean())) {
469                    removeTableRowMemory();
470                }
471                if (evt.getOldValue().equals(_tableColumnMemoryHandle.getBean())) {
472                    removeTableColumnMemory();
473                }
474            }
475        }
476    }
477
478    private NamedTable evaluateTableBean(ConditionalNG conditionalNG) throws JmriException {
479
480        if (_tableNameAddressing == NamedBeanAddressing.Direct) {
481            return _tableHandle != null ? _tableHandle.getBean() : null;
482        } else {
483            String name;
484
485            switch (_tableNameAddressing) {
486                case Reference:
487                    name = ReferenceUtil.getReference(
488                            conditionalNG.getSymbolTable(), _tableNameReference);
489                    break;
490
491                case Memory:
492                    name = TypeConversionUtil
493                            .convertToString(_tableNameMemoryHandle.getBean().getValue(), false);
494                    break;
495
496                case LocalVariable:
497                    SymbolTable symbolTable = conditionalNG.getSymbolTable();
498                    name = TypeConversionUtil
499                            .convertToString(symbolTable.getValue(_tableNameLocalVariable), false);
500                    break;
501
502                case Formula:
503                    name = _tableNameExpressionNode  != null
504                            ? TypeConversionUtil.convertToString(
505                                    _tableNameExpressionNode .calculate(
506                                            conditionalNG.getSymbolTable()), false)
507                            : null;
508                    break;
509
510                case Table:
511                    name = TypeConversionUtil.convertToString(
512                            _tableNameSelectTable.evaluateTableData(conditionalNG), false);
513                    break;
514
515                default:
516                    throw new IllegalArgumentException("invalid _addressing state: " + _tableNameAddressing.name());
517            }
518
519            NamedTable table = null;
520            if (name != null) {
521                table = InstanceManager.getDefault(NamedTableManager.class)
522                        .getNamedBean(name);
523            }
524            return table;
525        }
526    }
527
528    private String evaluateTableRow(ConditionalNG conditionalNG) throws JmriException {
529
530        switch (_tableRowAddressing) {
531            case Direct:
532                return _tableRowName;
533
534            case Reference:
535                return ReferenceUtil.getReference(
536                        conditionalNG.getSymbolTable(), _tableRowReference);
537
538            case Memory:
539                return TypeConversionUtil
540                        .convertToString(_tableRowMemoryHandle.getBean().getValue(), false);
541
542            case LocalVariable:
543                SymbolTable symbolTable = conditionalNG.getSymbolTable();
544                return TypeConversionUtil
545                        .convertToString(symbolTable.getValue(_tableRowLocalVariable), false);
546
547            case Formula:
548                return _tableRowExpressionNode != null
549                        ? TypeConversionUtil.convertToString(
550                                _tableRowExpressionNode.calculate(
551                                        conditionalNG.getSymbolTable()), false)
552                        : null;
553
554                case Table:
555                    return TypeConversionUtil.convertToString(
556                            _tableRowSelectTable.evaluateTableData(conditionalNG), false);
557
558            default:
559                throw new IllegalArgumentException("invalid _addressing state: " + _tableRowAddressing.name());
560        }
561    }
562
563    private String evaluateTableColumn(ConditionalNG conditionalNG) throws JmriException {
564
565        switch (_tableColumnAddressing) {
566            case Direct:
567                return _tableColumnName;
568
569            case Reference:
570                return ReferenceUtil.getReference(
571                        conditionalNG.getSymbolTable(), _tableColumnReference);
572
573            case Memory:
574                return TypeConversionUtil
575                        .convertToString(_tableColumnMemoryHandle.getBean().getValue(), false);
576
577            case LocalVariable:
578                SymbolTable symbolTable = conditionalNG.getSymbolTable();
579                return TypeConversionUtil
580                        .convertToString(symbolTable.getValue(_tableColumnLocalVariable), false);
581
582            case Formula:
583                return _tableColumnExpressionNode != null
584                        ? TypeConversionUtil.convertToString(
585                                _tableColumnExpressionNode.calculate(
586                                        conditionalNG.getSymbolTable()), false)
587                        : null;
588
589                case Table:
590                    return TypeConversionUtil.convertToString(
591                            _tableColumnSelectTable.evaluateTableData(conditionalNG), false);
592
593            default:
594                throw new IllegalArgumentException("invalid _addressing state: " + _tableColumnAddressing.name());
595        }
596    }
597
598    public Object evaluateTableData(ConditionalNG conditionalNG) throws JmriException {
599        return evaluateTableBean(conditionalNG).getCell(
600                evaluateTableRow(conditionalNG), evaluateTableColumn(conditionalNG));
601    }
602
603    public void evaluateAndSetTableData(ConditionalNG conditionalNG, Object value)
604            throws JmriException {
605        evaluateTableBean(conditionalNG).setCell(
606                value,
607                evaluateTableRow(conditionalNG),
608                evaluateTableColumn(conditionalNG));
609    }
610
611    public String getTableNameDescription(Locale locale) {
612        String namedBean;
613
614        String memoryName;
615        if (_tableNameMemoryHandle != null) {
616            memoryName = _tableNameMemoryHandle.getName();
617        } else {
618            memoryName = Bundle.getMessage(locale, "BeanNotSelected");
619        }
620
621        switch (_tableNameAddressing) {
622            case Direct:
623                String tableName;
624                if (_tableHandle != null) {
625                    tableName = _tableHandle.getBean().getDisplayName();
626                } else {
627                    tableName = Bundle.getMessage(locale, "BeanNotSelected");
628                }
629                namedBean = Bundle.getMessage(locale, "AddressByDirect", tableName);
630                break;
631
632            case Reference:
633                namedBean = Bundle.getMessage(locale, "AddressByReference", _tableNameReference);
634                break;
635
636            case Memory:
637                namedBean = Bundle.getMessage(locale, "AddressByMemory", memoryName);
638                break;
639
640            case LocalVariable:
641                namedBean = Bundle.getMessage(locale, "AddressByLocalVariable", _tableNameLocalVariable);
642                break;
643
644            case Formula:
645                namedBean = Bundle.getMessage(locale, "AddressByFormula", _tableNameFormula);
646                break;
647
648            case Table:
649                namedBean = Bundle.getMessage(
650                        locale,
651                        "AddressByTable",
652                        _tableNameSelectTable.getTableNameDescription(locale),
653                        _tableNameSelectTable.getTableRowDescription(locale),
654                        _tableNameSelectTable.getTableColumnDescription(locale));
655                break;
656
657            default:
658                throw new IllegalArgumentException("invalid _tableNameAddressing: " + _tableNameAddressing.name());
659        }
660        return namedBean;
661    }
662
663    public String getTableRowDescription(Locale locale) {
664        String row;
665
666        String memoryName;
667        if (_tableRowMemoryHandle != null) {
668            memoryName = _tableRowMemoryHandle.getName();
669        } else {
670            memoryName = Bundle.getMessage(locale, "BeanNotSelected");
671        }
672
673        switch (_tableRowAddressing) {
674            case Direct:
675                row = Bundle.getMessage(locale, "AddressByDirect", _tableRowName);
676                break;
677
678            case Reference:
679                row = Bundle.getMessage(locale, "AddressByReference", _tableRowReference);
680                break;
681
682            case Memory:
683                row = Bundle.getMessage(locale, "AddressByMemory", memoryName);
684                break;
685
686            case LocalVariable:
687                row = Bundle.getMessage(locale, "AddressByLocalVariable", _tableRowLocalVariable);
688                break;
689
690            case Formula:
691                row = Bundle.getMessage(locale, "AddressByFormula", _tableRowFormula);
692                break;
693
694            case Table:
695                row = Bundle.getMessage(
696                        locale,
697                        "AddressByTable",
698                        _tableRowSelectTable.getTableNameDescription(locale),
699                        _tableRowSelectTable.getTableRowDescription(locale),
700                        _tableRowSelectTable.getTableColumnDescription(locale));
701                break;
702
703            default:
704                throw new IllegalArgumentException("invalid _tableRowAddressing: " + _tableRowAddressing.name());
705        }
706        return row;
707    }
708
709    public String getTableColumnDescription(Locale locale) {
710        String column;
711
712        String memoryName;
713        if (_tableColumnMemoryHandle != null) {
714            memoryName = _tableColumnMemoryHandle.getName();
715        } else {
716            memoryName = Bundle.getMessage(locale, "BeanNotSelected");
717        }
718
719        switch (_tableColumnAddressing) {
720            case Direct:
721                column = Bundle.getMessage(locale, "AddressByDirect", _tableColumnName);
722                break;
723
724            case Reference:
725                column = Bundle.getMessage(locale, "AddressByReference", _tableColumnReference);
726                break;
727
728            case Memory:
729                column = Bundle.getMessage(locale, "AddressByMemory", memoryName);
730                break;
731
732            case LocalVariable:
733                column = Bundle.getMessage(locale, "AddressByLocalVariable", _tableColumnLocalVariable);
734                break;
735
736            case Formula:
737                column = Bundle.getMessage(locale, "AddressByFormula", _tableColumnFormula);
738                break;
739
740            case Table:
741                column = Bundle.getMessage(
742                        locale,
743                        "AddressByTable",
744                        _tableColumnSelectTable.getTableNameDescription(locale),
745                        _tableColumnSelectTable.getTableRowDescription(locale),
746                        _tableColumnSelectTable.getTableColumnDescription(locale));
747                break;
748
749            default:
750                throw new IllegalArgumentException("invalid _tableRowAddressing: " + _tableColumnAddressing.name());
751        }
752        return column;
753    }
754
755    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogixNG_SelectTable.class);
756}