View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2007 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
11   */
12  
13  package com.eviware.soapui.impl.wsdl.panels.attachments;
14  
15  import java.awt.Component;
16  import java.awt.Toolkit;
17  import java.awt.datatransfer.DataFlavor;
18  import java.awt.datatransfer.Transferable;
19  import java.awt.dnd.DnDConstants;
20  import java.awt.dnd.DropTarget;
21  import java.awt.dnd.DropTargetDragEvent;
22  import java.awt.dnd.DropTargetDropEvent;
23  import java.awt.dnd.DropTargetEvent;
24  import java.awt.dnd.DropTargetListener;
25  import java.awt.event.ActionEvent;
26  import java.awt.event.MouseAdapter;
27  import java.awt.event.MouseEvent;
28  import java.beans.PropertyChangeEvent;
29  import java.beans.PropertyChangeListener;
30  import java.io.File;
31  import java.io.FileOutputStream;
32  import java.io.IOException;
33  import java.util.List;
34  
35  import javax.swing.AbstractListModel;
36  import javax.swing.ComboBoxModel;
37  import javax.swing.DefaultCellEditor;
38  import javax.swing.JButton;
39  import javax.swing.JComboBox;
40  import javax.swing.JFileChooser;
41  import javax.swing.JTable;
42  import javax.swing.event.ListSelectionEvent;
43  import javax.swing.event.ListSelectionListener;
44  
45  import com.eviware.soapui.SoapUI;
46  import com.eviware.soapui.impl.wsdl.WsdlAttachmentPart;
47  import com.eviware.soapui.impl.wsdl.WsdlRequest;
48  import com.eviware.soapui.impl.wsdl.actions.support.ShowOnlineHelpAction;
49  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
50  import com.eviware.soapui.model.iface.Attachment;
51  import com.eviware.soapui.support.Tools;
52  import com.eviware.soapui.support.UISupport;
53  import com.eviware.soapui.support.components.JXToolBar;
54  
55  /***
56   * Utility Panel for displaying a table of attachments
57   * 
58   * @author emibre
59   */
60  
61  public class AttachmentPanel extends javax.swing.JPanel
62  {
63  	private DropTarget dropTarget;
64  	private FileTransferHandler fileTransferHandler;
65  	private RequestAttachmentTableModel tableModel;
66  	private JFileChooser fc;
67  	private final WsdlRequest request;
68  	boolean allowChange = false;
69  	boolean isRequest = false;
70  	private JButton exportBtn;
71  
72  	/*** Creates new form FileTableList */
73  	public AttachmentPanel(WsdlRequest request, boolean isRequest)
74  	{
75  		this.request = request;
76  		this.allowChange = isRequest;
77  		this.isRequest = isRequest;
78  		initComponents();
79  		initFileTransfer();
80  	}
81  	
82  	public void release()
83  	{
84  		tableModel.release();
85  		if( attachmentPartCellEditor != null )
86  			attachmentPartCellEditor.release();
87  	}
88  
89  	private void initFileTransfer()
90  	{
91  		if (allowChange)
92  		{
93  			fileTransferHandler = new FileTransferHandler(tableModel);
94  			fileTable.setDragEnabled(true);
95  			fileTable.setTransferHandler(fileTransferHandler);
96  
97  			dropTarget = new DropTarget();
98  			dropTarget.setActive(true);
99  			try
100 			{
101 				dropTarget.addDropTargetListener(new DropTargetListener()
102 				{
103 					public void dragEnter(DropTargetDragEvent dtde)
104 					{
105 					}
106 
107 					public void dragExit(DropTargetEvent dte)
108 					{
109 					}
110 
111 					public void dragOver(DropTargetDragEvent dtde)
112 					{
113 					}
114 
115 					@SuppressWarnings("unchecked")
116 					public void drop(DropTargetDropEvent dtde)
117 					{
118 						try
119 						{
120 							dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
121 							Transferable trans = dtde.getTransferable();
122 							List<File> files = (List<File>) trans.getTransferData(DataFlavor.javaFileListFlavor);
123 							for (File f : files)
124 							{
125 								System.out.println("Dropping file: " + f.getName());
126 
127 								Boolean retval = UISupport.confirmOrCancel("Cache attachment in request?", "Att Attachment");
128 								if (retval == null)
129 									return;
130 
131 								tableModel.addFile(f, retval);
132 							}
133 
134 						}
135 						catch (Exception e)
136 						{
137 							SoapUI.logError( e );
138 						}
139 					}
140 
141 					public void dropActionChanged(DropTargetDragEvent dtde)
142 					{
143 					}
144 				});
145 			}
146 			catch (Exception e)
147 			{
148 				SoapUI.logError( e );
149 			}
150 
151 			jScrollPane1.getViewport().setDropTarget(dropTarget);
152 		}
153 	}
154 
155 	private void initComponents()
156 	{
157 		jScrollPane1 = new javax.swing.JScrollPane();
158 		tableModel = new RequestAttachmentTableModel(request, isRequest);
159 		fileTable = new JTable(tableModel);
160 
161 		if (isRequest)
162 		{
163 			attachmentPartCellEditor = new AttachmentPartCellEditor();
164 			fileTable.getColumnModel().getColumn(3).setCellEditor(attachmentPartCellEditor);
165 		}
166 
167 		setLayout(new java.awt.BorderLayout());
168 		jScrollPane1.setViewportView(fileTable);
169 
170 		add(jScrollPane1, java.awt.BorderLayout.CENTER);
171 
172 		jPanel1 = UISupport.createToolbar();
173 		
174 		if (allowChange)
175 		{
176 			addFileBtn = new javax.swing.JButton();
177 			removeBtn = new javax.swing.JButton();
178 
179 			addFileBtn.setText("Add file");
180 			addFileBtn.addActionListener(new java.awt.event.ActionListener()
181 			{
182 				public void actionPerformed(java.awt.event.ActionEvent evt)
183 				{
184 					addFileBtnActionPerformed(evt);
185 				}
186 			});
187 
188 			jPanel1.addFixed(addFileBtn);
189 
190 			removeBtn.setText("Remove selected");
191 			removeBtn.setEnabled(false);
192 			removeBtn.addActionListener(new java.awt.event.ActionListener()
193 			{
194 				public void actionPerformed(java.awt.event.ActionEvent evt)
195 				{
196 					removeBtnActionPerformed(evt);
197 				}
198 			});
199 
200 			jPanel1.addFixed(removeBtn);
201 		}
202 
203 		exportBtn = new javax.swing.JButton();
204 		exportBtn.setText("Export selected");
205 		exportBtn.setEnabled(false);
206 		exportBtn.addActionListener(new java.awt.event.ActionListener()
207 		{
208 			public void actionPerformed(java.awt.event.ActionEvent evt)
209 			{
210 				exportBtnActionPerformed(evt);
211 			}
212 		});
213 
214 		jPanel1.addFixed(exportBtn);
215 		jPanel1.addGlue();
216 		jPanel1.addFixed( UISupport.createToolbarButton( new ShowOnlineHelpAction(HelpUrls.ATTACHMENTS_HELP_URL)));
217 		add(jPanel1, java.awt.BorderLayout.SOUTH);
218 
219 		fileTable.getSelectionModel().addListSelectionListener(new ListSelectionListener()
220 		{
221 			public void valueChanged(ListSelectionEvent e)
222 			{
223 				if( removeBtn != null )
224 					removeBtn.setEnabled(fileTable.getSelectedRowCount() > 0);
225 				
226 				exportBtn.setEnabled(fileTable.getSelectedRowCount() > 0);
227 			}
228 		});
229 		
230 		fileTable.addMouseListener(new MouseAdapter()
231 		{
232 			public void mouseClicked(MouseEvent e)
233 			{
234 				if (e.getClickCount() < 2)
235 					return;
236 
237 				int ix = fileTable.getSelectedRow();
238 				if (ix == -1)
239 					return;
240 
241 				Attachment attachment = isRequest ? request.getAttachmentAt(ix)
242 						: request.getResponse().getAttachments()[ix];
243 				String url = attachment.getUrl();
244 				if (url != null)
245 				{
246 					Tools.openURL(url);
247 				}
248 				else
249 				{
250 					Toolkit.getDefaultToolkit().beep();
251 				}
252 			}
253 		});
254 	}
255 
256 	protected void exportBtnActionPerformed( ActionEvent evt )
257 	{
258 		File file = UISupport.getFileDialogs().saveAs( this, "Export Attachment.." );
259 		while( file != null && file.exists() && 
260 				 !UISupport.confirm( "File " + file.getName() + " exists, overwrite?", "Export Attachment" ))
261 		{
262 			file = UISupport.getFileDialogs().saveAs( this, "Export Attachment.." );
263 		}
264 		
265 		if( file != null )
266 		{
267 			Attachment attachment = tableModel.getAttachmentAt(fileTable.getSelectedRow());
268 			try
269 			{
270 				FileOutputStream out = new FileOutputStream( file );
271 				
272 				long total = Tools.writeAll( out, attachment.getInputStream() );
273 				out.close();
274 				UISupport.showInfoMessage( "Written [" + total + "] bytes to " + file.getName() );
275 			}
276 			catch( Exception e )
277 			{
278 				UISupport.showErrorMessage( e );
279 			}
280 		}
281 	}
282 
283 	private void addFileBtnActionPerformed(java.awt.event.ActionEvent evt)
284 	{// GEN-FIRST:event_addFileBtnActionPerformed
285 		if (fc == null)
286 			fc = new JFileChooser();
287 
288 		int returnVal = fc.showOpenDialog(this);
289 
290 		if (returnVal == JFileChooser.APPROVE_OPTION)
291 		{
292 			File file = fc.getSelectedFile();
293 			Boolean retval = UISupport.confirmOrCancel("Cache attachment in request?", "Att Attachment");
294 			if (retval == null)
295 				return;
296 			try
297 			{
298 				tableModel.addFile(file, retval);
299 			}
300 			catch (IOException e)
301 			{
302 				UISupport.showErrorMessage(e);
303 			}
304 		}
305 		else
306 		{
307 			System.out.println("Open command cancelled by user.");
308 		}
309 	}// GEN-LAST:event_addFileBtnActionPerformed
310 
311 	private void removeBtnActionPerformed(java.awt.event.ActionEvent evt)
312 	{// GEN-FIRST:event_removeBtnActionPerformed
313 		if (UISupport.confirm("Remove selected attachments?", "Remove Attachments"))
314 			tableModel.removeAttachment(fileTable.getSelectedRows());
315 	}// GEN-LAST:event_removeBtnActionPerformed
316 
317 	// Variables declaration - do not modify//GEN-BEGIN:variables
318 	private javax.swing.JButton addFileBtn;
319 	private JTable fileTable;
320 	private JXToolBar jPanel1;
321 	private javax.swing.JScrollPane jScrollPane1;
322 	private javax.swing.JButton removeBtn;
323 	private AttachmentPartCellEditor attachmentPartCellEditor;
324 
325 	// End of variables declaration//GEN-END:variables
326 
327 	private class AttachmentPartCellEditor extends DefaultCellEditor
328 	{
329 		public AttachmentPartCellEditor()
330 		{
331 			super(new JComboBox(new PartsComboBoxModel()));
332 		}
333 
334 		public void release()
335 		{
336 			((PartsComboBoxModel) ((JComboBox) editorComponent).getModel()).release();
337 		}
338 
339 		public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column)
340 		{
341 			((PartsComboBoxModel) ((JComboBox) editorComponent).getModel()).init(tableModel.getAttachmentAt(row));
342 			return super.getTableCellEditorComponent(table, value, isSelected, row, column);
343 		}
344 	}
345 
346 	private final class PartsComboBoxModel extends AbstractListModel implements ComboBoxModel, PropertyChangeListener
347 	{
348 		private Attachment attachment;
349 		private WsdlAttachmentPart[] parts;
350 		
351 		public PartsComboBoxModel()
352 		{
353 			request.addPropertyChangeListener( this );
354 		}
355 
356 		public void release()
357 		{
358 			request.removePropertyChangeListener( this );
359 		}
360 
361 		public void init(Attachment attachment)
362 		{
363 			System.out.println( "Initializing parts..");
364 			this.attachment = attachment;
365 			parts = request.getDefinedAttachmentParts();
366 		}
367 
368 		public Object getElementAt(int index)
369 		{
370 			return parts == null ? null : parts[index].getName();
371 		}
372 
373 		public int getSize()
374 		{
375 			return parts == null ? 0 : parts.length;
376 		}
377 
378 		public Object getSelectedItem()
379 		{
380 			return attachment == null ? null : attachment.getPart();
381 		}
382 
383 		public void setSelectedItem(Object anItem)
384 		{
385 			if (attachment != null)
386 				attachment.setPart((String) anItem);
387 		}
388 
389 		public void propertyChange( PropertyChangeEvent arg0 )
390 		{
391 			if( arg0.getPropertyName().equals( WsdlRequest.ATTACHMENTS_PROPERTY ))
392 			{
393 				// delete our current one?
394 				if( arg0.getOldValue() == attachment && arg0.getNewValue() == null )
395 				{
396 					attachment = null;
397 					parts = null;
398 				}
399 			}
400 		}
401 	}
402 }