1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package com.gridsystems.config.modules.tomcat;
25
26 import java.awt.Color;
27 import java.awt.Component;
28 import java.awt.Dimension;
29 import java.awt.EventQueue;
30 import java.awt.Font;
31 import java.awt.GridBagConstraints;
32 import java.awt.GridBagLayout;
33 import java.awt.Insets;
34 import java.awt.event.ActionEvent;
35 import java.awt.event.ActionListener;
36 import java.awt.event.FocusEvent;
37 import java.awt.event.FocusListener;
38 import java.util.ArrayList;
39 import java.util.Iterator;
40 import java.util.MissingResourceException;
41 import java.util.ResourceBundle;
42
43 import javax.swing.DefaultCellEditor;
44 import javax.swing.JButton;
45 import javax.swing.JComboBox;
46 import javax.swing.JComponent;
47 import javax.swing.JLabel;
48 import javax.swing.JPanel;
49 import javax.swing.JScrollPane;
50 import javax.swing.JTable;
51 import javax.swing.JTextField;
52 import javax.swing.SwingUtilities;
53 import javax.swing.event.ListSelectionEvent;
54 import javax.swing.event.ListSelectionListener;
55 import javax.swing.table.AbstractTableModel;
56 import javax.swing.table.DefaultTableCellRenderer;
57 import javax.swing.table.DefaultTableColumnModel;
58 import javax.swing.table.TableCellRenderer;
59 import javax.swing.table.TableColumn;
60 import javax.swing.table.TableColumnModel;
61
62
63
64
65
66
67
68 public class ConnectorEditor extends JPanel {
69
70
71
72 private static final int COMPONENT_WIDTH = 200;
73
74
75
76
77 private static final int COMPONENT_HEIGHT = 100;
78
79
80
81
82 private static final int FIXED_COLUMN_WIDTH = 70;
83
84
85
86
87 private static final Font BUTTON_FONT = Font.decode("Dialog-PLAIN-11");
88
89
90
91
92 private static ResourceBundle bundle = ResourceBundle
93 .getBundle(TomcatConfigurator.BUNDLE);
94
95
96
97
98 private JTable table;
99
100
101
102
103 private JScrollPane scroller;
104
105
106
107
108 private JButton btnAdd;
109
110
111
112
113 private JButton btnRemove;
114
115
116
117
118 private Runnable changeCallback;
119
120
121
122
123 public ConnectorEditor() {
124 super();
125 init();
126 }
127
128
129
130
131 private void init() {
132 this.setLayout(new GridBagLayout());
133
134 table = new JTable();
135 table.getSelectionModel().addListSelectionListener(new ConnectorSelectionListener());
136 scroller = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
137 JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
138
139 btnAdd = new JButton(getString("ConnectorEditor.btnAdd.text"));
140 btnRemove = new JButton(getString("ConnectorEditor.btnRemove.text"));
141
142 btnAdd.setFont(BUTTON_FONT);
143 btnRemove.setFont(BUTTON_FONT);
144
145 btnAdd.addActionListener(new ActionListener() {
146 public void actionPerformed(ActionEvent event) {
147 addConnector();
148 }
149 });
150
151 btnRemove.addActionListener(new ActionListener() {
152 public void actionPerformed(ActionEvent event) {
153 removeConnector();
154 }
155 });
156
157 this.add(scroller, new GridBagConstraints(0, 0, 2, 1, 1.0, 1.0,
158 GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 2, 0), 0, 0));
159 this.add(btnAdd, new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0,
160 GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
161 this.add(btnRemove, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0,
162 GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 2, 0, 0), 0, 0));
163
164 this.setPreferredSize(new Dimension(COMPONENT_WIDTH, COMPONENT_HEIGHT));
165 }
166
167
168
169
170 public void addConnector() {
171 ConnectorModel model = (ConnectorModel)table.getModel();
172 model.newConnector();
173 runCallback();
174 }
175
176
177
178
179 public void removeConnector() {
180 int row = table.getSelectedRow();
181 if (row != -1) {
182 ConnectorModel model = (ConnectorModel)table.getModel();
183 model.deleteConnector(row);
184 runCallback();
185 }
186 }
187
188
189
190
191
192
193 public void setConnectors(Connector[] list) {
194 table.setModel(new ConnectorModel(list));
195 setupTable(table);
196 }
197
198
199
200
201
202
203 public Connector[] getConnectors() {
204 ConnectorModel model = (ConnectorModel)table.getModel();
205 Connector[] c = new Connector[model.list.size()];
206 model.list.toArray(c);
207 return c;
208 }
209
210
211
212
213
214
215 private void setupTable(JTable table) {
216 TableColumnModel cmodel = new DefaultTableColumnModel();
217 TableCellRenderer renderer = new ConnectorCellRenderer();
218
219 TableColumn c = new TableColumn(0);
220 c.setHeaderValue(getString("ConnectorEditor.table.colName"));
221 c.setResizable(true);
222 c.setCellRenderer(renderer);
223 c.setCellEditor(new NameCellEditor());
224 cmodel.addColumn(c);
225
226 c = new TableColumn(1);
227 c.setHeaderValue(getString("ConnectorEditor.table.colScheme"));
228 c.setMinWidth(FIXED_COLUMN_WIDTH);
229 c.setMaxWidth(FIXED_COLUMN_WIDTH);
230 c.setResizable(false);
231 c.setCellRenderer(renderer);
232 c.setCellEditor(new SchemeCellEditor());
233 cmodel.addColumn(c);
234
235 c = new TableColumn(2);
236 c.setHeaderValue(getString("ConnectorEditor.table.colPort"));
237 c.setMinWidth(FIXED_COLUMN_WIDTH);
238 c.setMaxWidth(FIXED_COLUMN_WIDTH);
239 c.setResizable(false);
240 c.setCellRenderer(renderer);
241 c.setCellEditor(new PortCellEditor());
242 cmodel.addColumn(c);
243
244 table.setColumnModel(cmodel);
245 table.setRowHeight(20);
246 }
247
248
249
250
251
252
253 public void setChangeCallback(Runnable callback) {
254 this.changeCallback = callback;
255 }
256
257
258
259
260
261
262 public boolean containSecureConnector() {
263 ConnectorModel model = (ConnectorModel)table.getModel();
264 for (Iterator it = model.list.iterator(); it.hasNext();) {
265 Connector c = (Connector)it.next();
266 if (Connector.HTTPS.equalsIgnoreCase(c.getProtocol())) {
267 return true;
268 }
269 }
270 return false;
271 }
272
273
274
275
276 private void runCallback() {
277 if (changeCallback != null) {
278 SwingUtilities.invokeLater(changeCallback);
279 }
280 }
281
282
283
284
285
286
287
288
289 public static String getString(String key) throws NullPointerException {
290 if (bundle == null) {
291 throw new NullPointerException("Bundle not set");
292 }
293
294 try {
295 return bundle.getString(key);
296 } catch (MissingResourceException e) {
297 return null;
298 }
299 }
300
301
302
303
304
305
306
307 private class ConnectorModel extends AbstractTableModel {
308
309
310
311 private static final int COLUMN_COUNT = 4;
312
313
314
315
316 public ArrayList<Connector> list;
317
318
319
320
321
322
323 public ConnectorModel(Connector[] connectors) {
324 super();
325 this.list = new ArrayList<Connector>();
326
327 int count = connectors == null ? 0 : connectors.length;
328 for (int i = 0; i < count; i++) {
329 this.list.add(connectors[i]);
330 }
331 }
332
333
334
335
336 public int getColumnCount() {
337 return COLUMN_COUNT;
338 }
339
340
341
342
343 public int getRowCount() {
344 return this.list.size();
345 }
346
347
348
349
350 public Object getValueAt(int rowIndex, int columnIndex) {
351 Connector c = (Connector)list.get(rowIndex);
352 return c;
353 }
354
355
356
357
358 public void setValueAt(Object value, int rowIndex, int columnIndex) {
359 Connector c = (Connector)list.get(rowIndex);
360 boolean modified = false;
361 switch (columnIndex) {
362 case 0:
363 modified = !value.equals(c.getName());
364 c.setName(value.toString());
365 break;
366 case 1:
367 modified = !c.getProtocol().equals(value);
368 c.setProtocol((String)value);
369
370 if (Connector.HTTPS.equalsIgnoreCase(c.getProtocol())
371 && c.getPort() == TomcatConfigModel.DEFAULT_HTTP_PORT) {
372 c.setPort(TomcatConfigModel.DEFAULT_HTTPS_PORT);
373 fireTableCellUpdated(rowIndex, 2);
374 }
375 if (Connector.HTTP.equalsIgnoreCase(c.getProtocol())
376 && c.getPort() == TomcatConfigModel.DEFAULT_HTTPS_PORT) {
377 c.setPort(TomcatConfigModel.DEFAULT_HTTP_PORT);
378 fireTableCellUpdated(rowIndex, 2);
379 }
380 break;
381 case 2:
382 try {
383 int port = Integer.parseInt(value.toString());
384 modified = (port != c.getPort());
385 c.setPort(port);
386 } catch (Exception e) { }
387 break;
388 default:
389 break;
390 }
391
392
393 if (modified) {
394 runCallback();
395 }
396 }
397
398
399
400
401 public boolean isCellEditable(int row, int column) {
402 Connector c = (Connector)list.get(row);
403 return c.isUserCreated() || column == 2;
404 }
405
406
407
408
409 public void newConnector() {
410 Connector c = new Connector(getString("ConnectorEditor.unnamed.text"),
411 TomcatConfigModel.DEFAULT_HTTP_PORT, Connector.HTTP);
412
413 boolean changed = true;
414 while (changed) {
415 changed = false;
416 for (Iterator it = list.iterator(); it.hasNext();) {
417 Connector item = (Connector)it.next();
418 if (item.getPort() == c.getPort()) {
419 changed = true;
420 c.setPort(c.getPort() + 1);
421 }
422 }
423 }
424
425 int lastRow = list.size();
426 list.add(c);
427 fireTableRowsInserted(lastRow, lastRow);
428 }
429
430
431
432
433
434
435 public void deleteConnector(int row) {
436 Connector c = (Connector)list.get(row);
437 if (c != null) {
438 list.remove(row);
439 fireTableRowsDeleted(row, row);
440 }
441 }
442 }
443
444
445
446
447
448
449
450 private static class ConnectorCellRenderer extends DefaultTableCellRenderer {
451
452
453
454 private static final int[] ALIGNS = { JLabel.LEFT, JLabel.CENTER, JLabel.RIGHT };
455
456
457
458
459 private static final Color[] BACKGROUNDS = { Color.WHITE, Color.decode("0xFFFFCC") };
460
461
462
463
464
465
466
467
468
469
470
471
472 public Component getTableCellRendererComponent(JTable table, Object value,
473 boolean isSelected, boolean hasFocus, int row, int column) {
474
475 Connector conn = (Connector)value;
476 switch (column) {
477 case 0:
478 value = conn.getName();
479 break;
480 case 1:
481 value = conn.getProtocol();
482 break;
483 case 2:
484 value = String.valueOf(conn.getPort());
485 default:
486 break;
487 }
488
489 JLabel lbl = (JLabel)super.getTableCellRendererComponent(table, value, isSelected,
490 hasFocus, row, column);
491
492 lbl.setHorizontalAlignment(ALIGNS[column]);
493 boolean editable = (conn.isUserCreated() || column == 2);
494 if (!isSelected) {
495 lbl.setBackground(BACKGROUNDS[editable ? 0 : 1]);
496 }
497
498
499
500 if (hasFocus) {
501 final JTable theTable = table;
502 final int theRow = row;
503 final int theCol = editable ? column : 2;
504
505 EventQueue.invokeLater(new Runnable() {
506 public void run() {
507
508 theTable.editCellAt(theRow, theCol);
509
510
511 Component c = theTable.getEditorComponent();
512 if (c != null) {
513 c.requestFocusInWindow();
514 }
515 }
516 });
517 }
518 return lbl;
519 }
520 }
521
522
523
524
525
526
527
528
529 private static class NameCellEditor extends DefaultCellEditor {
530
531
532
533 private static JTextField txt = new JTextField();
534
535
536
537
538 private static ConnectorFocusListener fl = new ConnectorFocusListener();
539
540 static {
541 txt.addFocusListener(fl);
542 }
543
544
545
546
547 public NameCellEditor() {
548 super(txt);
549 }
550
551
552
553
554
555
556
557
558
559
560
561 public Component getTableCellEditorComponent(JTable table, Object value,
562 boolean isSelected, int row, int column) {
563 Connector c = (Connector)value;
564
565 super.getTableCellEditorComponent(table, c.getName(), isSelected, row, column);
566 editorComponent.putClientProperty("cellEditor", this);
567 return editorComponent;
568 }
569 }
570
571
572
573
574
575
576
577 private static class SchemeCellEditor extends DefaultCellEditor {
578
579
580
581
582 private static JComboBox cbox = new JComboBox(Connector.getAvailableProtocols());
583
584 static {
585 cbox.setFont(Font.decode("Dialog-PLAIN-12"));
586 cbox.setFocusable(false);
587 };
588
589
590
591
592 public SchemeCellEditor() {
593 super(cbox);
594 }
595
596
597
598
599
600
601
602
603
604
605
606 public Component getTableCellEditorComponent(JTable table, Object value,
607 boolean isSelected, int row, int column) {
608 Connector c = (Connector)value;
609 value = c.getProtocol();
610 super.getTableCellEditorComponent(table, value, isSelected, row, column);
611 return cbox;
612 }
613 }
614
615
616
617
618
619
620
621 private static class PortCellEditor extends DefaultCellEditor {
622
623
624
625 private static JTextField txt = new JTextField();
626
627
628
629
630 private static ConnectorFocusListener fl = new ConnectorFocusListener();
631
632 static {
633 txt.addFocusListener(fl);
634 }
635
636
637
638
639 public PortCellEditor() {
640 super(txt);
641 }
642
643
644
645
646
647
648
649
650
651
652
653 public Component getTableCellEditorComponent(JTable table, Object value,
654 boolean isSelected, int row, int column) {
655 Connector c = (Connector)value;
656 value = "" + c.getPort();
657 super.getTableCellEditorComponent(table, value, isSelected, row, column);
658 editorComponent.putClientProperty("cellEditor", this);
659 return editorComponent;
660 }
661 }
662
663
664
665
666
667
668
669 private class ConnectorSelectionListener implements ListSelectionListener {
670
671
672
673 public ConnectorSelectionListener() { }
674
675
676
677
678 public void valueChanged(ListSelectionEvent event) {
679 if (!event.getValueIsAdjusting()) {
680 try {
681 ConnectorModel model = (ConnectorModel)table.getModel();
682
683 if (model.list.size() == 1) {
684 btnRemove.setEnabled(false);
685 } else {
686 btnRemove.setEnabled(true);
687 }
688 } catch (Exception e) {
689 btnRemove.setEnabled(false);
690 }
691 }
692 }
693 }
694
695
696
697
698
699
700
701
702 private static class ConnectorFocusListener implements FocusListener {
703
704
705
706
707 public ConnectorFocusListener() { }
708
709
710
711
712 public void focusGained(FocusEvent e) {
713 Component c = e.getComponent();
714 if (c instanceof JTextField) {
715 JTextField field = (JTextField)c;
716 field.selectAll();
717 }
718 }
719
720
721
722
723 public void focusLost(FocusEvent e) {
724 JComponent c = (JComponent)e.getComponent();
725 DefaultCellEditor editor = (DefaultCellEditor)c.getClientProperty("cellEditor");
726 if (editor != null) {
727 editor.stopCellEditing();
728 }
729 }
730 }
731 }