source: main/trunk/greenstone3/src/java/org/greenstone/admin/guiext/PropertiesStep.java@ 25635

Last change on this file since 25635 was 25635, checked in by sjm84, 12 years ago

Fixing Greenstone 3's use (or lack thereof) of generics, this was done automatically so we may want to change it over time. This change will also auto-format any files that have not already been formatted.

File size: 17.3 KB
Line 
1package org.greenstone.admin.guiext;
2
3import javax.crypto.Cipher;
4import javax.crypto.KeyGenerator;
5import javax.crypto.SecretKey;
6
7import javax.crypto.spec.SecretKeySpec;
8
9import javax.swing.AbstractCellEditor;
10import javax.swing.BorderFactory;
11import javax.swing.ImageIcon;
12import javax.swing.JButton;
13import javax.swing.JFileChooser;
14import javax.swing.JFrame;
15import javax.swing.JLabel;
16import javax.swing.JOptionPane;
17import javax.swing.JPanel;
18import javax.swing.JPasswordField;
19import javax.swing.JScrollPane;
20import javax.swing.JTable;
21import javax.swing.JTextField;
22import javax.swing.SwingConstants;
23
24import javax.swing.event.DocumentListener;
25import javax.swing.event.DocumentEvent;
26
27import javax.swing.table.AbstractTableModel;
28import javax.swing.table.TableCellEditor;
29import javax.swing.table.TableColumn;
30import javax.swing.table.TableModel;
31
32import java.awt.event.ActionListener;
33import java.awt.event.ActionEvent;
34import java.awt.event.KeyListener;
35import java.awt.event.KeyEvent;
36
37import java.awt.BorderLayout;
38import java.awt.Color;
39import java.awt.Component;
40import java.awt.Font;
41import java.awt.GridLayout;
42
43import java.util.Properties;
44import java.util.Arrays;
45import java.util.HashMap;
46
47import java.io.File;
48import java.io.FileInputStream;
49import java.io.FileOutputStream;
50
51import org.w3c.dom.Element;
52
53import org.greenstone.util.Configuration;
54import org.greenstone.admin.LoggedMessageArea;
55
56public class PropertiesStep extends Step
57{
58 OptionList[] _optionLists = null;
59 JTable[] _tables = null;
60 OptionList[] _modifiedOptionLists = null;
61
62 HashMap<OptionList, PropertyTable> _optionListTableMap = new HashMap<OptionList, PropertyTable>();
63
64 public PropertiesStep(Element propertiesStepElement, SequenceList parent)
65 {
66 super(propertiesStepElement, parent);
67
68 if(propertiesStepElement != null){
69 ExtensionInformation info = _parent.getParent();
70
71 Element[] optionListElements = ExtXMLHelper.getMultipleChildElements(propertiesStepElement, ExtXMLHelper.OPTION_LIST, true);
72
73 if(optionListElements != null){
74
75 _optionLists = new OptionList[optionListElements.length];
76 _modifiedOptionLists = new OptionList[optionListElements.length];
77
78 for(int i = 0; i < optionListElements.length; i++){
79 _optionLists[i] = new OptionList(optionListElements[i], this, false);
80 _modifiedOptionLists[i] = new OptionList(optionListElements[i], this, true);
81 }
82 }
83 else{
84 System.err.println("This properties <" + ExtXMLHelper.STEP + "> element has no <" + ExtXMLHelper.OPTION_LIST + "> elements");
85 }
86 }
87 else{
88 System.err.println("This properties <" + ExtXMLHelper.STEP + "> element is null" );
89 }
90
91 _button.addActionListener(new PropertiesButtonListener());
92 }
93
94 public void setPropertiesToDefaults()
95 {
96 for(int i = 0; i < _optionLists.length; i++){
97 Option[] _modifiedOptions = _modifiedOptionLists[i].getOptions();
98 Option[] _defaultOptions = _optionLists[i].getOptions();
99
100 for(int j = 0; j < _defaultOptions.length; j++){
101 _modifiedOptions[j].setValue(_defaultOptions[j].getValue());
102 }
103 }
104 }
105
106 public JTable getTableFromOptionList(OptionList list)
107 {
108 return _optionListTableMap.get(list);
109 }
110
111 public class PropertiesButtonListener implements ActionListener
112 {
113 public void actionPerformed(ActionEvent e)
114 {
115 ExtensionInformation extension = _parent.getParent();
116
117 String fileStem = extension.getFileStem();
118
119 JPanel mainPanel = new JPanel();
120 mainPanel.setBorder(BorderFactory.createLoweredBevelBorder());
121 mainPanel.setBackground(Configuration.getColor("coloring.workspace_selection_background"));
122 mainPanel.setForeground(Configuration.getColor("coloring.workspace_selection_foreground"));
123 mainPanel.setLayout(new BorderLayout());
124
125 JPanel tablePanel = new JPanel(new GridLayout(_optionLists.length, 1));
126
127 if(_tables == null){
128 _tables = new JTable[_optionLists.length];
129 }
130 for(int i = 0; i < _optionLists.length; i++){
131 OptionList currentList = _modifiedOptionLists[i];
132
133 JLabel singleTableLabel = new JLabel(currentList.getLabel());
134 singleTableLabel.setHorizontalAlignment(SwingConstants.CENTER);
135 singleTableLabel.setFont(new Font("Arial", Font.BOLD, 13));
136
137 JPanel singleTablePanel = new JPanel();
138 singleTablePanel.setLayout(new BorderLayout());
139 singleTablePanel.add(singleTableLabel, BorderLayout.NORTH);
140
141 Option[] options = currentList.getOptions();
142
143 CustomTableModel tableModel = new CustomTableModel(new String[]{"Setting", "Value", "Check"}, options);
144 PropertyTable propertiesTable = new PropertyTable(tableModel, currentList);
145 TableColumn column = propertiesTable.getColumnModel().getColumn(2);
146 column.setPreferredWidth(32);
147 column.setMinWidth(32);
148 column.setMaxWidth(32);
149 column.setResizable(false);
150
151 _optionListTableMap.put(currentList, propertiesTable);
152
153 //The line below is necessary as the default grid colour on mac is white, which makes the lines invisible.
154 propertiesTable.setGridColor(Color.BLACK);
155
156 if(_tables[i] == null){
157 _tables[i] = propertiesTable;
158 }
159
160 //The line below is a workaround for a bug in the JTable class that does not store properties if focus is given to another component.
161 propertiesTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
162
163 singleTablePanel.add(propertiesTable, BorderLayout.CENTER);
164
165 tablePanel.add(singleTablePanel);
166 }
167
168 JButton defaultsButton = new JButton("Restore default settings");
169 defaultsButton.addActionListener(new DefaultSettingsButtonListener());
170
171 JButton saveButton = new JButton("Save");
172 saveButton.addActionListener(new SaveButtonListener());
173
174 JPanel buttonPanel = new JPanel();
175 buttonPanel.setLayout(new GridLayout(1, 2));
176 buttonPanel.add(saveButton);
177 buttonPanel.add(defaultsButton);
178
179 mainPanel.setBorder(BorderFactory.createEmptyBorder(10,20,10,20));
180 mainPanel.setBackground(Configuration.getColor("coloring.workspace_selection_background"));
181 mainPanel.setForeground(Configuration.getColor("coloring.workspace_selection_foreground"));
182 mainPanel.add(tablePanel, BorderLayout.CENTER);
183 mainPanel.add(buttonPanel, BorderLayout.SOUTH);
184
185 _parent.getParent().changeExtPane(mainPanel);
186 }
187 }
188
189 public class BrowseButtonListener implements ActionListener
190 {
191 Option _option = null;
192 JTextField _path = null;
193 JFileChooser _browser = null;
194
195 public BrowseButtonListener(Option option, JTextField path)
196 {
197 _option = option;
198 _path = path;
199 _browser = new JFileChooser();
200 }
201
202 public void actionPerformed(ActionEvent e)
203 {
204 if(e.getActionCommand().equals("edit")){
205 if(_option.getType().equalsIgnoreCase("folderbrowse")){
206 _browser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
207 }
208 int returnValue = _browser.showOpenDialog(null);
209
210 if(returnValue == JFileChooser.APPROVE_OPTION){
211 _option.setValue(_browser.getSelectedFile().getAbsolutePath());
212 _path.setText(_option.getValue());
213 }
214 }
215 }
216 }
217
218 public class PathBoxListener implements DocumentListener
219 {
220 Option _option = null;
221 JTextField _path = null;
222
223 public PathBoxListener(Option option, JTextField path)
224 {
225 _option = option;
226 _path = path;
227 }
228
229 public void changedUpdate(DocumentEvent e)
230 {
231 _option.setValue(_path.getText());
232 }
233
234 public void insertUpdate(DocumentEvent e)
235 {
236 _option.setValue(_path.getText());
237 }
238
239 public void removeUpdate(DocumentEvent e)
240 {
241 _option.setValue(_path.getText());
242 }
243 }
244
245 public class PasswordOKButtonListener implements ActionListener
246 {
247 JPasswordField _password = null;
248 JPasswordField _confirm = null;
249 Option _option = null;
250 JFrame _passwordFrame = null;
251
252 public PasswordOKButtonListener(JPasswordField password, JPasswordField confirm, Option option, JFrame passwordFrame)
253 {
254 _password = password;
255 _confirm = confirm;
256 _option = option;
257 _passwordFrame = passwordFrame;
258 }
259
260 public void actionPerformed(ActionEvent e)
261 {
262 if(Arrays.equals(_password.getPassword(), _confirm.getPassword())){
263 try{
264 _option.setValue(new String(encrypt(_password.getPassword())));
265 }
266 catch(Exception ex){
267 System.err.println("Error encrypting password");
268 }
269 _passwordFrame.dispose();
270 }
271 else{
272 JOptionPane.showMessageDialog(null, "The passwords you entered do not match.");
273 _password.setText("");
274 _confirm.setText("");
275 }
276 }
277 }
278
279 public static char[] encrypt(char[] value) throws Exception
280 {
281 byte[] salt = {'T', 'p'};
282 int count = 20;
283
284 KeyGenerator keygen = KeyGenerator.getInstance("AES");
285 SecretKey secretKey = keygen.generateKey();
286 byte[] raw = secretKey.getEncoded();
287 SecretKeySpec secretKeySpec = new SecretKeySpec(raw, "AES");
288
289 Cipher cipher = Cipher.getInstance("AES");
290 cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
291
292 byte[] encryptedPassword = cipher.doFinal((new String(value)).getBytes("UTF-8"));
293
294 return new String(encryptedPassword).toCharArray();
295 }
296
297 public class PasswordCancelButtonListener implements ActionListener
298 {
299 JFrame _passwordFrame = new JFrame();
300
301 public PasswordCancelButtonListener(JFrame passwordFrame)
302 {
303 _passwordFrame = passwordFrame;
304 }
305
306 public void actionPerformed(ActionEvent e)
307 {
308 _passwordFrame.dispose();
309 }
310 }
311
312 public class PasswordFieldListener implements ActionListener
313 {
314 JPasswordField _password = new JPasswordField(10);
315 JPasswordField _confirm = new JPasswordField(10);
316 JFrame _passwordFrame = new JFrame("Enter password");
317
318 public PasswordFieldListener(Option option)
319 {
320 JButton okButton = new JButton("Change");
321 JButton cancelButton = new JButton("Cancel");
322
323 okButton.addActionListener(new PasswordOKButtonListener(_password, _confirm, option, _passwordFrame));
324 cancelButton.addActionListener(new PasswordCancelButtonListener(_passwordFrame));
325
326 _passwordFrame.getContentPane().setLayout(new GridLayout(3,2));
327 _passwordFrame.getContentPane().add(new JLabel("Password:"));
328 _passwordFrame.getContentPane().add(_password);
329 _passwordFrame.getContentPane().add(new JLabel("Confirm:"));
330 _passwordFrame.getContentPane().add(_confirm);
331 _passwordFrame.getContentPane().add(okButton);
332 _passwordFrame.getContentPane().add(cancelButton);
333 _passwordFrame.pack();
334 }
335
336 public void actionPerformed(ActionEvent e)
337 {
338 _password.setText("");
339 _confirm.setText("");
340 _passwordFrame.setLocationRelativeTo(null);
341 _passwordFrame.setVisible(true);
342 }
343 }
344
345 public class PasswordEditor extends AbstractCellEditor implements TableCellEditor
346 {
347 JButton _onClickButton = new JButton("Change Password?");
348
349 public PasswordEditor(Option option)
350 {
351 _onClickButton.addActionListener(new PasswordFieldListener(option));
352 }
353
354 public Object getCellEditorValue()
355 {
356 return "";
357 }
358
359 public Component getTableCellEditorComponent(JTable table, Object path, boolean isSelected, int row, int column)
360 {
361 return _onClickButton;
362 }
363 }
364
365 public class BrowseEditor extends AbstractCellEditor implements TableCellEditor
366 {
367 JPanel _browserPanel = null;
368 JTextField _path = null;
369 JButton _browserButton = null;
370 Option _option = null;
371 String _type = null;
372
373 public BrowseEditor(Option option, String type)
374 {
375 _option = option;
376 _type = type;
377
378 _path = new JTextField(_option.getValue());
379 _path.getDocument().addDocumentListener(new PathBoxListener(_option, _path));
380
381 _browserButton = new JButton("Browse");
382 _browserButton.setActionCommand("edit");
383 _browserButton.addActionListener(new BrowseButtonListener(_option, _path));
384 _browserButton.setBorderPainted(false);
385
386 _browserPanel = new JPanel();
387 _browserPanel.setLayout(new BorderLayout());
388 _browserPanel.add(_path, BorderLayout.CENTER);
389 _browserPanel.add(_browserButton, BorderLayout.EAST);
390 }
391
392 public Object getCellEditorValue()
393 {
394 _path.setText(_option.getValue());
395 return _option.getValue();
396 }
397
398 public Component getTableCellEditorComponent(JTable table, Object path, boolean isSelected, int row, int column)
399 {
400 return _browserPanel;
401 }
402 }
403
404 public class PropertyTable extends JTable
405 {
406 OptionList _properties = null;
407 TableCellEditor[] _editors = null;
408
409 public PropertyTable(TableModel tm, OptionList properties)
410 {
411 super(tm);
412 _properties = properties;
413
414 Option[] options = _properties.getOptions();
415 _editors = new TableCellEditor[options.length];
416
417 for(int i = 0; i < options.length; i++){
418 Option currentOption = options[i];
419
420 if(currentOption.getType().equals("filebrowse")){
421 _editors[i] = new BrowseEditor(currentOption, "file");
422 }
423 else if(currentOption.getType().equals("folderbrowse")){
424 _editors[i] = new BrowseEditor(currentOption, "folder");
425 }
426 else if(currentOption.getType().equals("password")){
427 _editors[i] = new PasswordEditor(currentOption);
428 }
429 else{
430 _editors[i] = null;
431 }
432 }
433 }
434
435 public TableCellEditor getCellEditor(int row, int column)
436 {
437 if(column == 1 && row < _editors.length && _editors[row] != null){
438 return _editors[row];
439 }
440 return super.getCellEditor(row, column);
441 }
442 }
443
444 public class SaveButtonListener implements ActionListener
445 {
446 public void actionPerformed(ActionEvent e)
447 {
448 for(int i = 0; i < _optionLists.length; i++){
449 OptionList currentOptionList = _modifiedOptionLists[i];
450 Option[] currentOptions = currentOptionList.getOptions();
451
452 Properties newProperties = new Properties();
453 File propertiesFile = null;
454 if(currentOptionList.getFilename().equals("")){
455 propertiesFile = new File(_parent.getParent().getExtensionDirectory() + System.getProperty("file.separator") + "build.properties");
456 }
457 else{
458 propertiesFile = new File(_parent.getParent().getExtensionDirectory() + System.getProperty("file.separator") + currentOptionList.getFilename());
459 }
460
461 if(propertiesFile.exists()){
462 try{
463 newProperties.load(new FileInputStream(propertiesFile));
464 }
465 catch(Exception ex){
466 System.err.println("Could not load properties file before saving to it, existing values will be removed. Possible reasons for this include: \n - Invalid properties file format\n - File is write protected");
467 }
468 }
469
470 for(int j = 0; j < currentOptions.length; j++){
471 Option currentOption = currentOptions[j];
472 if(currentOptionList.getId().equals("")){
473 newProperties.setProperty(currentOption.getId(), currentOption.getValue());
474 }
475 else{
476 newProperties.setProperty(currentOptionList.getId() + "." + currentOption.getId(), currentOption.getValue());
477 }
478 }
479
480 try{
481 if(currentOptionList.getFilename().equals("")){
482 newProperties.store(new FileOutputStream(_parent.getParent().getExtensionDirectory() + System.getProperty("file.separator") + "build.properties"), null);
483 }
484 else{
485 newProperties.store(new FileOutputStream(_parent.getParent().getExtensionDirectory() + System.getProperty("file.separator") + currentOptionList.getFilename()), null);
486 }
487 }
488 catch(Exception ex){
489 System.err.println("Could not save to properties file.");
490 }
491 }
492
493 _parent.registerStepCompletion(PropertiesStep.this);
494 }
495 }
496
497 public class DefaultSettingsButtonListener implements ActionListener
498 {
499 public void actionPerformed(ActionEvent e)
500 {
501 for(int i = 0; i < _tables.length; i++){
502 JTable currentTable = _tables[i];
503 Option[] currentDefaultOptions = _optionLists[i].getOptions();
504
505 for(int j = 0; j < currentDefaultOptions.length; j++){
506 Option currentOption = currentDefaultOptions[j];
507 currentTable.setValueAt(currentOption.getValue(), j, 1);
508 }
509
510 currentTable.revalidate();
511 currentTable.repaint();
512 }
513 }
514 }
515
516 public class CustomTableModel extends AbstractTableModel
517 {
518 private String[] _columnNames = null;
519 private Option[] _data = null;
520 private ImageIcon[] _images = null;
521
522 public CustomTableModel(String[] columnNames, Option[] data){
523 _columnNames = columnNames;
524 _data = data;
525
526 _images = new ImageIcon[_data.length];
527 for(int i = 0; i < _data.length; i++){
528 _images[i] = _data[i].getImage();
529 }
530 }
531
532 public int getColumnCount() {
533 return _columnNames.length;
534 }
535
536 public int getRowCount() {
537 return _data.length;
538 }
539
540 public String getColumnName(int col) {
541 return _columnNames[col];
542 }
543
544 public Object getValueAt(int row, int col) {
545 if(col == 0){
546 return _data[row].getName();
547 }
548 else if(col == 1){
549 if(_data[row].getType().equals("password") && !_data[row].getValue().equals("")){
550 return "Password Set";
551 }
552 else if(_data[row].getType().equals("password") && _data[row].getValue().equals("")){
553 return "No Password Set";
554 }
555
556 return _data[row].getValue();
557 }
558 else if(col == 2){
559 return _data[row].getImage();
560 }
561 else{
562 return null;
563 }
564 }
565
566
567 public Class<? extends Object> getColumnClass(int c) {
568 return getValueAt(0, c).getClass();
569 }
570
571 public boolean isCellEditable(int row, int col) {
572 if (col == 1) {
573 return true;
574 } else {
575 return false;
576 }
577 }
578
579 public void setValueAt(Object value, int row, int col) {
580 Option o = _data[row];
581 if(isCellEditable(row, col) && !o.getType().equals("password")){
582 o.setValue((String)value);
583
584 if(o.isCheckable()){
585 _images[row] = o.getImage();
586 }
587 }
588 fireTableDataChanged();
589 }
590 }
591}
Note: See TracBrowser for help on using the repository browser.