• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

evolvedbinary / elemental / 982

29 Apr 2025 08:34PM UTC coverage: 56.409% (+0.007%) from 56.402%
982

push

circleci

adamretter
[feature] Improve README.md badges

28451 of 55847 branches covered (50.94%)

Branch coverage included in aggregate %.

77468 of 131924 relevant lines covered (58.72%)

0.59 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/exist-core/src/main/java/org/exist/client/TriggersDialog.java
1
/*
2
 * Elemental
3
 * Copyright (C) 2024, Evolved Binary Ltd
4
 *
5
 * admin@evolvedbinary.com
6
 * https://www.evolvedbinary.com | https://www.elemental.xyz
7
 *
8
 * Use of this software is governed by the Business Source License 1.1
9
 * included in the LICENSE file and at www.mariadb.com/bsl11.
10
 *
11
 * Change Date: 2028-04-27
12
 *
13
 * On the date above, in accordance with the Business Source License, use
14
 * of this software will be governed by the Apache License, Version 2.0.
15
 *
16
 * Additional Use Grant: Production use of the Licensed Work for a permitted
17
 * purpose. A Permitted Purpose is any purpose other than a Competing Use.
18
 * A Competing Use means making the Software available to others in a commercial
19
 * product or service that: substitutes for the Software; substitutes for any
20
 * other product or service we offer using the Software that exists as of the
21
 * date we make the Software available; or offers the same or substantially
22
 * similar functionality as the Software.
23
 *
24
 * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
25
 *       The original license header is included below.
26
 *
27
 * =====================================================================
28
 *
29
 * eXist-db Open Source Native XML Database
30
 * Copyright (C) 2001 The eXist-db Authors
31
 *
32
 * info@exist-db.org
33
 * http://www.exist-db.org
34
 *
35
 * This library is free software; you can redistribute it and/or
36
 * modify it under the terms of the GNU Lesser General Public
37
 * License as published by the Free Software Foundation; either
38
 * version 2.1 of the License, or (at your option) any later version.
39
 *
40
 * This library is distributed in the hope that it will be useful,
41
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
42
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
43
 * Lesser General Public License for more details.
44
 *
45
 * You should have received a copy of the GNU Lesser General Public
46
 * License along with this library; if not, write to the Free Software
47
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
48
 */
49
package org.exist.client;
50

51
import java.awt.Component;
52
import java.awt.GridBagConstraints;
53
import java.awt.GridBagLayout;
54
import java.awt.Insets;
55
import java.awt.event.WindowAdapter;
56
import java.awt.event.WindowEvent;
57
import java.awt.event.WindowListener;
58
import java.util.ArrayList;
59
import java.util.List;
60
import javax.swing.Box;
61
import javax.swing.DefaultCellEditor;
62
import javax.swing.JButton;
63
import javax.swing.JCheckBox;
64
import javax.swing.JComboBox;
65
import javax.swing.JFrame;
66
import javax.swing.JLabel;
67
import javax.swing.JOptionPane;
68
import javax.swing.JPanel;
69
import javax.swing.JTable;
70
import javax.swing.ListSelectionModel;
71
import javax.swing.border.TitledBorder;
72
import javax.swing.table.AbstractTableModel;
73
import javax.swing.table.TableCellRenderer;
74
import org.exist.security.PermissionDeniedException;
75
import org.exist.xmldb.XmldbURI;
76
import org.xmldb.api.base.Collection;
77
import org.xmldb.api.base.XMLDBException;
78

79
/**
80
 * Dialog for viewing and editing Triggers in the Admin Client 
81
 *
82
 * @author <a href="mailto:adam@evolvedbinary.com">Adam Retter</a>
83
 */
84
class TriggersDialog extends JFrame {
85

86
    private static final long serialVersionUID = 1L;
87

88
    private CollectionXConf cx = null;
×
89

90
    private JComboBox cmbCollections;
91

92
    private JTable tblTriggers;
93
    private TriggersTableModel triggersModel;
94

95
    private InteractiveClient client;
96

97
    public TriggersDialog(final String title, final InteractiveClient client) {
98
        super(title);
×
99
        this.client = client;
×
100
        this.setIconImage(InteractiveClient.getElementalIcon(getClass()).getImage());
×
101
        //capture the frame's close event
102
        final WindowListener windowListener = new WindowAdapter() {
×
103
            @Override
104
            public void windowClosing(final WindowEvent e) {
105
                saveChanges();
×
106

107
                TriggersDialog.this.setVisible(false);
×
108
                TriggersDialog.this.dispose();
×
109
            }
×
110
        };
111
        
112
        this.addWindowListener(windowListener);
×
113

114
        //draw the GUI
115
        setupComponents();
×
116

117
        //Get the indexes for the root collection
118
        actionGetTriggers(XmldbURI.ROOT_COLLECTION);
×
119
    }
×
120

121
    private void setupComponents() {
122
        //Dialog Content Panel
123
        final GridBagLayout grid = new GridBagLayout();
×
124
        getContentPane().setLayout(grid);
×
125

126
        //Constraints for Layout
127
        final GridBagConstraints c = new GridBagConstraints();
×
128
        c.insets = new Insets(2, 2, 2, 2);
×
129

130
        //collection label
131
        final JLabel label = new JLabel(Messages.getString("TriggersDialog.Collection"));
×
132
        c.gridx = 0;
×
133
        c.gridy = 0;
×
134
        c.gridwidth = 1;
×
135
        c.anchor = GridBagConstraints.WEST;
×
136
        c.fill = GridBagConstraints.NONE;
×
137
        grid.setConstraints(label, c);
×
138
        getContentPane().add(label);
×
139

140
        //get the collections but not system collections
141
        final List<PrettyXmldbURI> alCollections = new ArrayList<>();
×
142
        
143
        try {
144
            final Collection root = client.getCollection(XmldbURI.ROOT_COLLECTION);
×
145
            final List<PrettyXmldbURI> alAllCollections = getCollections(root, new ArrayList<>());
×
146
            for (PrettyXmldbURI alAllCollection : alAllCollections) {
×
147
                //TODO : use XmldbURIs !
148
                if (!alAllCollection.toString().contains(XmldbURI.CONFIG_COLLECTION)) {
×
149
                    alCollections.add(alAllCollection);
×
150
                }
151
            }
152
        } catch(final XMLDBException e) {
×
153
            ClientFrame.showErrorMessage(e.getMessage(), e);
×
154
            return;
×
155
        }
156
        
157
        //Create a combobox listing the collections
158
        cmbCollections = new JComboBox(alCollections.toArray());
×
159
        cmbCollections.addActionListener(e -> {
×
160
            saveChanges();
×
161

162
            final JComboBox cb = (JComboBox)e.getSource();
×
163
            actionGetTriggers(cb.getSelectedItem().toString());
×
164
        });
×
165
        
166
        c.gridx = 1;
×
167
        c.gridy = 0;
×
168
        c.gridwidth = 1;
×
169
        c.anchor = GridBagConstraints.WEST;
×
170
        c.fill = GridBagConstraints.HORIZONTAL;
×
171
        c.weightx = 1;
×
172
        grid.setConstraints(cmbCollections, c);
×
173
        getContentPane().add(cmbCollections);
×
174

175
        //Panel to hold controls relating to the Triggers Index
176
        final JPanel panelTriggers = new JPanel();
×
177
        panelTriggers.setBorder(new TitledBorder(Messages.getString("TriggersDialog.Triggers")));
×
178
        final GridBagLayout panelTriggersGrid = new GridBagLayout();
×
179
        panelTriggers.setLayout(panelTriggersGrid);
×
180

181
        //Table to hold the Triggers with Sroll bar
182
        triggersModel = new TriggersTableModel();
×
183
        tblTriggers = new JTable(triggersModel);
×
184
        tblTriggers.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN);
×
185
        tblTriggers.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
×
186

187
        //Toolbar with add/delete buttons for Triggers
188
        final Box triggersToolbarBox = Box.createHorizontalBox();
×
189
        //add button
190
        final JButton btnAddTrigger = new JButton(Messages.getString("TriggersDialog.addbutton"));
×
191
        btnAddTrigger.addActionListener(e -> actionAddTrigger());
×
192
        triggersToolbarBox.add(btnAddTrigger);
×
193
        
194
        //delete button
195
        final JButton btnDeleteTrigger = new JButton(Messages.getString("TriggersDialog.deletebutton"));
×
196
        btnDeleteTrigger.addActionListener(e -> actionDeleteTrigger());
×
197
        triggersToolbarBox.add(btnDeleteTrigger);
×
198
        c.gridx = 0;
×
199
        c.gridy = 4;
×
200
        c.gridwidth = 2;
×
201
        c.anchor = GridBagConstraints.CENTER;
×
202
        c.fill = GridBagConstraints.BOTH;
×
203
        c.weightx = 0;
×
204
        c.weighty = 0;
×
205
        panelTriggersGrid.setConstraints(triggersToolbarBox, c);
×
206
        panelTriggers.add(triggersToolbarBox);
×
207

208
        //add triggers panel to content frame
209
        c.gridx = 0;
×
210
        c.gridy = 1;
×
211
        c.gridwidth = 2;
×
212
        c.anchor = GridBagConstraints.WEST;
×
213
        c.fill = GridBagConstraints.BOTH;
×
214
        c.weightx = 1;
×
215
        c.weighty = 1;
×
216
        grid.setConstraints(panelTriggers, c);
×
217
        getContentPane().add(panelTriggers);
×
218

219
        pack();
×
220
    }
×
221

222
    //if changes have been made, allows the user to save them
223
    private void saveChanges() {
224
        //the collection has been changed
225
        if(cx.hasChanged()) {
×
226
            //ask the user if they would like to save the changes
227
            final int result = JOptionPane.showConfirmDialog(getContentPane(), "The configuration for the collection has changed, would you like to save the changes?", "Save Changes", JOptionPane.YES_NO_OPTION);
×
228

229
            if(result == JOptionPane.YES_OPTION) {
×
230
                //save the collection.xconf changes
231
                if(cx.Save()) {
×
232
                    //save ok
233
                    JOptionPane.showMessageDialog(getContentPane(), "Your changes have been saved.");
×
234
                } else {
×
235
                    //save failed
236
                    JOptionPane.showMessageDialog(getContentPane(), "Unable to save changes!");
×
237
                }
238
            }
239
        }
240
    }
×
241

242
    //THIS IS A COPY FROM ClientFrame
243
    //TODO: share this code between the two classes
244
    private List<PrettyXmldbURI> getCollections(final Collection root, final List<PrettyXmldbURI> collectionsList) throws XMLDBException {
245
        collectionsList.add(new PrettyXmldbURI(XmldbURI.create(root.getName())));
×
246
        Collection child;
247
        for (String childCollection : root.listChildCollections()) {
×
248
            try {
249
                child = root.getChildCollection(childCollection);
×
250
            } catch (final XMLDBException xmldbe) {
×
251
                if (xmldbe.getCause() instanceof PermissionDeniedException) {
×
252
                    continue;
×
253
                } else {
254
                    throw xmldbe;
×
255
                }
256
            }
257
            getCollections(child, collectionsList);
×
258
        }
259
        return collectionsList;
×
260
    }
261

262
    private void actionAddTrigger() {
263
        triggersModel.addRow();
×
264
    }
×
265

266
    private void actionDeleteTrigger() {
267
        final int iSelectedRow = tblTriggers.getSelectedRow();
×
268
        if(iSelectedRow > -1 ) {
×
269
            triggersModel.removeRow(iSelectedRow);
×
270
        }
271
    }
×
272

273
    //Displays the indexes when a collection is selection
274
    private void actionGetTriggers(final String collectionName) {
275
        try {
276
            cx = new CollectionXConf(collectionName, client);
×
277
            triggersModel.fireTableDataChanged();
×
278
        } catch(final XMLDBException xmldbe) {
×
279
            ClientFrame.showErrorMessage(xmldbe.getMessage(), xmldbe);
×
280
        }
281

282
    }
×
283

284
    public static class CheckBoxCellRenderer extends JCheckBox implements TableCellRenderer {
285
        private static final long serialVersionUID = 1L;
286

287
        public CheckBoxCellRenderer() {
×
288
            setHorizontalAlignment(JLabel.CENTER);
×
289
        }
×
290
    
291
        @Override
292
        public Component getTableCellRendererComponent(final JTable table, final Object value, final boolean isSelected, final boolean hasFocus, final int row, final int column) {
293
            if(isSelected) {
×
294
                setForeground(table.getSelectionForeground());
×
295
                //super.setBackground(table.getSelectionBackground());
296
                setBackground(table.getSelectionBackground());
×
297
            } else {
×
298
                setForeground(table.getForeground());
×
299
                setBackground(table.getBackground());
×
300
            }
301
    
302
            // Set the state
303
            setSelected((value != null && (Boolean) value));
×
304
            return this;
×
305
        }
306
    }
307

308
    public static class CheckBoxCellEditor extends DefaultCellEditor {
309
        private static final long serialVersionUID = 1L;
310

311
        public CheckBoxCellEditor() {
312
            super(new JCheckBox());
×
313
        }
×
314
    }
315

316
    class TriggersTableModel extends AbstractTableModel {
317
        private static final long serialVersionUID = 1L;
318

319
        private final String[] columnNames = new String[] { "class", "Parameters" };
×
320

321
        public TriggersTableModel() {
×
322
            super();
×
323
            fireTableDataChanged();
×
324
        }
×
325

326
        /* (non-Javadoc)
327
        * @see javax.swing.table.TableModel#isCellEditable()
328
        */
329
        @Override
330
        public void setValueAt(final Object aValue, final int rowIndex, final int columnIndex) {
331
            String triggerClass = null;
×
332

333
            if(columnIndex == 0) {
×
334
                //trigger class name has been updated
335
                triggerClass = (String)aValue;
×
336
            }
337

338
            cx.updateTrigger(rowIndex, triggerClass, null);
×
339
            fireTableCellUpdated(rowIndex, columnIndex);
×
340
        }
×
341

342
        public void removeRow(final int rowIndex) {
343
            cx.deleteTrigger(rowIndex);
×
344
            fireTableRowsDeleted(rowIndex, rowIndex);
×
345
        }
×
346

347
        public void addRow() {        
348
            cx.addTrigger("", null);
×
349
            fireTableRowsInserted(getRowCount(), getRowCount() + 1);
×
350
            final ListSelectionModel selectionModel = tblTriggers.getSelectionModel();
×
351
            selectionModel.setSelectionInterval(getRowCount() -1, getRowCount() -1);
×
352
        }
×
353

354
        /* (non-Javadoc)
355
        * @see javax.swing.table.TableModel#isCellEditable()
356
        */
357
        @Override
358
        public boolean isCellEditable(final int rowIndex, final int columnIndex) {
359
            return true;
×
360
        }
361

362
        /* (non-Javadoc)
363
        * @see javax.swing.table.TableModel#getColumnCount()
364
        */
365
        @Override
366
        public int getColumnCount() {
367
            return columnNames.length;
×
368
        }
369

370
        /* (non-Javadoc)
371
         * @see javax.swing.table.TableModel#getColumnName(int)
372
         */
373
        @Override
374
        public String getColumnName(final int column) {
375
            return columnNames[column];
×
376
        }
377

378
        /* (non-Javadoc)
379
         * @see javax.swing.table.TableModel#getRowCount()
380
         */
381
        @Override
382
        public int getRowCount() {
383
            return cx != null ? cx.getTriggerCount() : 0;
×
384
        }
385

386
        /* (non-Javadoc)
387
         * @see javax.swing.table.TableModel#getValueAt(int, int)
388
         */
389
        @Override
390
        public Object getValueAt(final int rowIndex, final int columnIndex) {
391
            return switch (columnIndex) {
×
392
                /* class */
393
                case 0 -> cx.getTrigger(rowIndex).getTriggerClass();
×
394
                default -> null;
×
395
            };
396
        }
397
    }
398
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc