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 }