001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018:
019: package org.apache.jmeter.protocol.http.gui;
020:
021: import java.awt.BorderLayout;
022: import java.awt.Component;
023: import java.awt.Dimension;
024: import java.awt.event.ActionEvent;
025: import java.awt.event.ActionListener;
026: import java.io.File;
027: import java.io.IOException;
028:
029: import javax.swing.BorderFactory;
030: import javax.swing.DefaultCellEditor;
031: import javax.swing.JButton;
032: import javax.swing.JPanel;
033: import javax.swing.JPasswordField;
034: import javax.swing.JScrollPane;
035: import javax.swing.JTable;
036: import javax.swing.ListSelectionModel;
037: import javax.swing.border.Border;
038: import javax.swing.border.EmptyBorder;
039: import javax.swing.table.AbstractTableModel;
040: import javax.swing.table.TableCellEditor;
041: import javax.swing.table.TableCellRenderer;
042: import javax.swing.table.TableColumn;
043:
044: import org.apache.jmeter.config.gui.AbstractConfigGui;
045: import org.apache.jmeter.gui.util.FileDialoger;
046: import org.apache.jmeter.protocol.http.control.AuthManager;
047: import org.apache.jmeter.protocol.http.control.Authorization;
048: import org.apache.jmeter.testelement.TestElement;
049: import org.apache.jmeter.util.JMeterUtils;
050: import org.apache.jorphan.logging.LoggingManager;
051: import org.apache.log.Logger;
052:
053: /**
054: * Handles input for determining if authentication services are required for a
055: * Sampler. It also understands how to get AuthManagers for the files that the
056: * user selects.
057: */
058: public class AuthPanel extends AbstractConfigGui implements
059: ActionListener {
060: private static final long serialVersionUID = -9214884465261470761L;
061:
062: private static final Logger log = LoggingManager
063: .getLoggerForClass();
064:
065: private static final String ADD_COMMAND = "Add"; //$NON-NLS-1$
066:
067: private static final String DELETE_COMMAND = "Delete"; //$NON-NLS-1$
068:
069: private static final String LOAD_COMMAND = "Load"; //$NON-NLS-1$
070:
071: private static final String SAVE_COMMAND = "Save"; //$NON-NLS-1$
072:
073: private InnerTableModel tableModel;
074:
075: /**
076: * A table to show the authentication information.
077: */
078: private JTable authTable;
079:
080: private JButton addButton;
081:
082: private JButton deleteButton;
083:
084: private JButton loadButton;
085:
086: private JButton saveButton;
087:
088: /**
089: * Default Constructor.
090: */
091: public AuthPanel() {
092: tableModel = new InnerTableModel();
093: init();
094: }
095:
096: public TestElement createTestElement() {
097: AuthManager authMan = tableModel.manager;
098: configureTestElement(authMan);
099: return (TestElement) authMan.clone();
100: }
101:
102: /**
103: * Modifies a given TestElement to mirror the data in the gui components.
104: *
105: * @see org.apache.jmeter.gui.JMeterGUIComponent#modifyTestElement(TestElement)
106: */
107: public void modifyTestElement(TestElement el) {
108: if (authTable.isEditing()) {
109: authTable.getCellEditor().stopCellEditing();
110: }
111: el.clear();
112: el.addTestElement((TestElement) tableModel.manager.clone());
113: configureTestElement(el);
114: }
115:
116: /**
117: * Implements JMeterGUIComponent.clear
118: */
119: public void clearGui() {
120: super .clearGui();
121:
122: tableModel.clearData();
123: deleteButton.setEnabled(false);
124: saveButton.setEnabled(false);
125: }
126:
127: public void configure(TestElement el) {
128: super .configure(el);
129: tableModel.manager.clear();
130: tableModel.manager.addTestElement((AuthManager) el.clone());
131: if (tableModel.getRowCount() != 0) {
132: deleteButton.setEnabled(true);
133: saveButton.setEnabled(true);
134: }
135: }
136:
137: public String getLabelResource() {
138: return "auth_manager_title"; //$NON-NLS-1$
139: }
140:
141: /**
142: * Shows the main authentication panel for this object.
143: */
144: public void init() {
145: setLayout(new BorderLayout());
146: setBorder(makeBorder());
147:
148: add(makeTitlePanel(), BorderLayout.NORTH);
149: add(createAuthTablePanel(), BorderLayout.CENTER);
150: }
151:
152: public void actionPerformed(ActionEvent e) {
153: String action = e.getActionCommand();
154:
155: if (action.equals(DELETE_COMMAND)) {
156: if (tableModel.getRowCount() > 0) {
157: // If a table cell is being edited, we must cancel the editing
158: // before deleting the row.
159: if (authTable.isEditing()) {
160: TableCellEditor cellEditor = authTable
161: .getCellEditor(authTable.getEditingRow(),
162: authTable.getEditingColumn());
163: cellEditor.cancelCellEditing();
164: }
165:
166: int rowSelected = authTable.getSelectedRow();
167:
168: if (rowSelected != -1) {
169: tableModel.removeRow(rowSelected);
170: tableModel.fireTableDataChanged();
171:
172: // Disable the DELETE and SAVE buttons if no rows remaining
173: // after delete.
174: if (tableModel.getRowCount() == 0) {
175: deleteButton.setEnabled(false);
176: saveButton.setEnabled(false);
177: }
178:
179: // Table still contains one or more rows, so highlight
180: // (select) the appropriate one.
181: else {
182: int rowToSelect = rowSelected;
183:
184: if (rowSelected >= tableModel.getRowCount()) {
185: rowToSelect = rowSelected - 1;
186: }
187:
188: authTable.setRowSelectionInterval(rowToSelect,
189: rowToSelect);
190: }
191: }
192: }
193: } else if (action.equals(ADD_COMMAND)) {
194: // If a table cell is being edited, we should accept the current
195: // value and stop the editing before adding a new row.
196: if (authTable.isEditing()) {
197: TableCellEditor cellEditor = authTable.getCellEditor(
198: authTable.getEditingRow(), authTable
199: .getEditingColumn());
200: cellEditor.stopCellEditing();
201: }
202:
203: tableModel.addNewRow();
204: tableModel.fireTableDataChanged();
205:
206: // Enable the DELETE and SAVE buttons if they are currently
207: // disabled.
208: if (!deleteButton.isEnabled()) {
209: deleteButton.setEnabled(true);
210: }
211: if (!saveButton.isEnabled()) {
212: saveButton.setEnabled(true);
213: }
214:
215: // Highlight (select) the appropriate row.
216: int rowToSelect = tableModel.getRowCount() - 1;
217: authTable.setRowSelectionInterval(rowToSelect, rowToSelect);
218: } else if (action.equals(LOAD_COMMAND)) {
219: try {
220: final String[] _txt = { ".txt" }; //$NON-NLS-1$
221: File tmp = FileDialoger.promptToOpenFile(_txt)
222: .getSelectedFile();
223: if (tmp != null) {
224: tableModel.manager.addFile(tmp.getAbsolutePath());
225: tableModel.fireTableDataChanged();
226:
227: if (tableModel.getRowCount() > 0) {
228: deleteButton.setEnabled(true);
229: saveButton.setEnabled(true);
230: }
231: }
232: } catch (IOException ex) {
233: log.error("", ex);
234: } catch (NullPointerException err) {// TODO WHY?
235: }
236: } else if (action.equals(SAVE_COMMAND)) {
237: try {
238: File tmp = FileDialoger.promptToSaveFile("auth.txt")
239: .getSelectedFile();
240: if (tmp != null) {
241: tableModel.manager.save(tmp.getAbsolutePath());
242: }
243: } catch (IOException ex) {
244: log.error("", ex);
245: } catch (NullPointerException err) {// TODO WHY?
246: }
247: }
248: }
249:
250: public JPanel createAuthTablePanel() {
251: // create the JTable that holds auth per row
252: authTable = new JTable(tableModel);
253: authTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
254: authTable.setPreferredScrollableViewportSize(new Dimension(100,
255: 70));
256:
257: TableColumn passwordColumn = authTable.getColumnModel()
258: .getColumn(AuthManager.COL_PASSWORD);
259: passwordColumn.setCellEditor(new DefaultCellEditor(
260: new JPasswordField()));
261: passwordColumn.setCellRenderer(new PasswordCellRenderer());
262:
263: JPanel panel = new JPanel(new BorderLayout(0, 5));
264: panel.setBorder(BorderFactory.createTitledBorder(BorderFactory
265: .createEtchedBorder(), JMeterUtils
266: .getResString("auths_stored"))); //$NON-NLS-1$
267: panel.add(new JScrollPane(authTable));
268: panel.add(createButtonPanel(), BorderLayout.SOUTH);
269: return panel;
270: }
271:
272: private JButton createButton(String resName, char mnemonic,
273: String command, boolean enabled) {
274: JButton button = new JButton(JMeterUtils.getResString(resName));
275: button.setMnemonic(mnemonic);
276: button.setActionCommand(command);
277: button.setEnabled(enabled);
278: button.addActionListener(this );
279: return button;
280: }
281:
282: private JPanel createButtonPanel() {
283: boolean tableEmpty = (tableModel.getRowCount() == 0);
284:
285: addButton = createButton("add", 'A', ADD_COMMAND, true); //$NON-NLS-1$
286: deleteButton = createButton(
287: "delete", 'D', DELETE_COMMAND, !tableEmpty); //$NON-NLS-1$
288: loadButton = createButton("load", 'L', LOAD_COMMAND, true); //$NON-NLS-1$
289: saveButton = createButton(
290: "save", 'S', SAVE_COMMAND, !tableEmpty); //$NON-NLS-1$
291:
292: // Button Panel
293: JPanel buttonPanel = new JPanel();
294: buttonPanel.add(addButton);
295: buttonPanel.add(deleteButton);
296: buttonPanel.add(loadButton);
297: buttonPanel.add(saveButton);
298: return buttonPanel;
299: }
300:
301: private static class InnerTableModel extends AbstractTableModel {
302: private static final long serialVersionUID = 4638155137475747946L;
303: AuthManager manager;
304:
305: public InnerTableModel(AuthManager man) {
306: manager = man;
307: }
308:
309: public InnerTableModel() {
310: manager = new AuthManager();
311: }
312:
313: public void clearData() {
314: manager.clear();
315: fireTableDataChanged();
316: }
317:
318: public void removeRow(int row) {
319: manager.remove(row);
320: }
321:
322: public void addNewRow() {
323: manager.addAuth();
324: }
325:
326: public boolean isCellEditable(int row, int column) {
327: // all table cells are editable
328: return true;
329: }
330:
331: public Class getColumnClass(int column) {
332: return getValueAt(0, column).getClass();
333: }
334:
335: /**
336: * Required by table model interface.
337: */
338: public int getRowCount() {
339: return manager.getAuthObjects().size();
340: }
341:
342: /**
343: * Required by table model interface.
344: */
345: public int getColumnCount() {
346: return manager.getColumnCount();
347: }
348:
349: /**
350: * Required by table model interface.
351: */
352: public String getColumnName(int column) {
353: return manager.getColumnName(column);
354: }
355:
356: /**
357: * Required by table model interface.
358: */
359: public Object getValueAt(int row, int column) {
360: Authorization auth = manager.getAuthObjectAt(row);
361:
362: switch (column) {
363: case AuthManager.COL_URL:
364: return auth.getURL();
365: case AuthManager.COL_USERNAME:
366: return auth.getUser();
367: case AuthManager.COL_PASSWORD:
368: return auth.getPass();
369: case AuthManager.COL_DOMAIN:
370: return auth.getDomain();
371: case AuthManager.COL_REALM:
372: return auth.getRealm();
373: default:
374: return null;
375: }
376: }
377:
378: public void setValueAt(Object value, int row, int column) {
379: Authorization auth = manager.getAuthObjectAt(row);
380: log.debug("Setting auth value: " + value);
381: switch (column) {
382: case AuthManager.COL_URL:
383: auth.setURL((String) value);
384: break;
385: case AuthManager.COL_USERNAME:
386: auth.setUser((String) value);
387: break;
388: case AuthManager.COL_PASSWORD:
389: auth.setPass((String) value);
390: break;
391: case AuthManager.COL_DOMAIN:
392: auth.setDomain((String) value);
393: break;
394: case AuthManager.COL_REALM:
395: auth.setRealm((String) value);
396: break;
397: default:
398: break;
399: }
400: }
401: }
402:
403: private static class PasswordCellRenderer extends JPasswordField
404: implements TableCellRenderer {
405: private static final long serialVersionUID = 5169856333827579927L;
406: private Border myBorder;
407:
408: public PasswordCellRenderer() {
409: super ();
410: myBorder = new EmptyBorder(1, 2, 1, 2);
411: setOpaque(true);
412: setBorder(myBorder);
413: }
414:
415: public Component getTableCellRendererComponent(JTable table,
416: Object value, boolean isSelected, boolean hasFocus,
417: int row, int column) {
418: setText((String) value);
419:
420: setBackground(isSelected && !hasFocus ? table
421: .getSelectionBackground() : table.getBackground());
422: setForeground(isSelected && !hasFocus ? table
423: .getSelectionForeground() : table.getForeground());
424:
425: setFont(table.getFont());
426:
427: return this;
428: }
429: }
430: }
|