001package jmri.jmrit.beantable;
002
003import javax.annotation.CheckForNull;
004import javax.annotation.Nonnull;
005import javax.swing.*;
006
007import jmri.CollectingReporter;
008import jmri.InstanceManager;
009import jmri.Manager;
010import jmri.NamedBean;
011import jmri.Reportable;
012import jmri.Reporter;
013import jmri.ReporterManager;
014
015import org.slf4j.Logger;
016import org.slf4j.LoggerFactory;
017
018/**
019 * Data model for a Reporter Table.
020 * Code originally within ReporterTableAction.
021 *
022 * @author Bob Jacobsen Copyright (C) 2003
023 * @author Steve Young Copyright (C) 2021
024 */
025public class ReporterTableDataModel extends BeanTableDataModel<Reporter> {
026
027    public static final int LASTREPORTCOL = NUMCOLUMN;
028
029    public ReporterTableDataModel(Manager<Reporter> mgr){
030        super();
031        setManager(mgr);
032    }
033
034    private ReporterManager reporterManager;
035
036    /**
037     * {@inheritDoc}
038     */
039    @Override
040    @CheckForNull
041    public String getValue(String name) {
042        Reporter r = getManager().getBySystemName(name);
043        if (r == null) {
044            return "";
045        }
046        if (r instanceof CollectingReporter) {
047            java.util.Collection<?> collection = ((CollectingReporter) r).getCollection();
048            if (collection != null) {
049                Object[] items = collection.toArray();
050                if (items.length > 0) {
051                    StringBuilder sb = new StringBuilder();
052                    for (Object item : items) {
053                        String str = formatReport(item);
054                        if (str != null) {
055                            if (sb.length() > 0) {
056                                if (sb.charAt(sb.length() - 1) == ' ') {
057                                    sb.append("+ ");
058                                } else {
059                                    sb.append(" + ");
060                                }
061                            }
062                            sb.append(str);
063                        }
064                    }
065                    return sb.length() > 0 ? sb.toString() : null;
066                }
067            }
068            return null;
069        }
070        return formatReport(r.getCurrentReport());
071    }
072
073    @CheckForNull
074    private String formatReport(Object value) {
075        if (value == null) {
076            return null;
077        } else if (value instanceof Reportable) {
078            return ((Reportable) value).toReportString();
079        } else {
080            return value.toString();
081        }
082    }
083
084    /**
085     * {@inheritDoc}
086     */
087    @Override
088    public final void setManager(Manager<Reporter> rm) {
089        if (!(rm instanceof ReporterManager)) {
090            return;
091        }
092        getManager().removePropertyChangeListener(this);
093        if (sysNameList != null) {
094            for (int i = 0; i < sysNameList.size(); i++) {
095                // if object has been deleted, it's not here; ignore it
096                NamedBean b = getBySystemName(sysNameList.get(i));
097                if (b != null) {
098                    b.removePropertyChangeListener(this);
099                }
100            }
101        }
102        reporterManager = (ReporterManager) rm;
103        getManager().addPropertyChangeListener(this);
104        updateNameList();
105    }
106
107    /**
108     * {@inheritDoc}
109     */
110    @Override
111    public ReporterManager getManager() {
112        return ( reporterManager == null ? InstanceManager.getDefault(ReporterManager.class): reporterManager);
113    }
114
115    /**
116     * {@inheritDoc}
117     */
118    @Override
119    public Reporter getBySystemName(@Nonnull String name) {
120        return getManager().getBySystemName(name);
121    }
122
123    /**
124     * {@inheritDoc}
125     */
126    @Override
127    public Reporter getByUserName(@Nonnull String name) {
128        return getManager().getByUserName(name);
129    }
130
131    /**
132     * {@inheritDoc}
133     */
134    @Override
135    protected String getMasterClassName() {
136        return ReporterTableAction.class.getName();
137    }
138
139    /**
140     * {@inheritDoc}
141     */
142    @Override
143    public void clickOn(Reporter t) {
144        // don't do anything on click; not used in this class, because
145        // we override setValueAt
146    }
147
148    /**
149     * {@inheritDoc}
150     */
151    @Override
152    public void setValueAt(Object value, int row, int col) {
153        switch (col) {
154            case VALUECOL:
155                getBySystemName(sysNameList.get(row)).setReport(value);
156                fireTableRowsUpdated(row, row);
157                break;
158            case LASTREPORTCOL: // do nothing
159                break;
160            default:
161                super.setValueAt(value, row, col);
162                break;
163        }
164    }
165
166    /**
167     * {@inheritDoc}
168     */
169    @Override
170    public int getColumnCount() {
171        return LASTREPORTCOL + getPropertyColumnCount() +1;
172    }
173
174    /**
175     * {@inheritDoc}
176     */
177    @Override
178    public String getColumnName(int col) {
179        switch (col) {
180            case VALUECOL:
181                return Bundle.getMessage("LabelReport");
182            case LASTREPORTCOL:
183                return Bundle.getMessage("LabelLastReport");
184            default:
185                return super.getColumnName(col);
186        }
187    }
188
189    /**
190     * {@inheritDoc}
191     */
192    @Override
193    public Class<?> getColumnClass(int col) {
194        switch (col) {
195            case VALUECOL:
196            case LASTREPORTCOL:
197                return String.class;
198            default:
199                return super.getColumnClass(col);
200        }
201    }
202
203    /**
204     * {@inheritDoc}
205     */
206    @Override
207    public boolean isCellEditable(int row, int col) {
208        if (col == LASTREPORTCOL) {
209            return false;
210        } else
211        return super.isCellEditable(row, col);
212    }
213
214    /**
215     * {@inheritDoc}
216     */
217    @Override
218    public Object getValueAt(int row, int col) {
219        if (col == LASTREPORTCOL) {
220
221            String name = sysNameList.get(row);
222            Reporter r = getManager().getBySystemName(name);
223            if (r == null) {
224                return "";
225            }
226            return formatReport(r.getLastReport());
227        } else
228        return super.getValueAt(row, col);
229    }
230
231    /**
232     * {@inheritDoc}
233     */
234    @Override
235    public int getPreferredWidth(int col) {
236        if (col == LASTREPORTCOL) {
237            return super.getPreferredWidth(VALUECOL);
238        } else
239        return super.getPreferredWidth(col);
240    }
241
242    /**
243     * {@inheritDoc}
244     */
245    @Override
246    public void configValueColumn(JTable table) {
247        // value column isn't button, so config is null
248    }
249
250    /**
251     * {@inheritDoc}
252     */
253    @Override
254    protected boolean matchPropertyName(java.beans.PropertyChangeEvent e) {
255        return true;
256        // return (e.getPropertyName().indexOf("Report")>=0);
257    }
258
259    /**
260     * {@inheritDoc}
261     */
262    @Override
263    public JButton configureButton() {
264        log.error("configureButton should not have been called");
265        return null;
266    }
267
268    private static final Logger log = LoggerFactory.getLogger(ReporterTableDataModel.class);
269
270}