/* * SoapUI, Copyright (C) 2004-2016 SmartBear Software * * Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent * versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * * http://ec.europa.eu/idabc/eupl * * Unless required by applicable law or agreed to in writing, software distributed under the Licence is * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the Licence for the specific language governing permissions and limitations * under the Licence. */ package com.eviware.soapui.support.editor.inspectors.attachments; import com.eviware.soapui.SoapUI; import com.eviware.soapui.impl.support.actions.ShowOnlineHelpAction; import com.eviware.soapui.impl.wsdl.AttachmentContainer; import com.eviware.soapui.impl.wsdl.MutableAttachmentContainer; import com.eviware.soapui.impl.wsdl.support.HelpUrls; import com.eviware.soapui.impl.wsdl.support.PathUtils; import com.eviware.soapui.impl.wsdl.support.WsdlAttachment; import com.eviware.soapui.model.iface.Attachment; import com.eviware.soapui.model.iface.MessagePart.AttachmentPart; import com.eviware.soapui.support.StringUtils; import com.eviware.soapui.support.Tools; import com.eviware.soapui.support.UISupport; import com.eviware.soapui.support.components.JXToolBar; import com.eviware.soapui.support.swing.JTableFactory; import javax.swing.AbstractListModel; import javax.swing.ComboBoxModel; import javax.swing.DefaultCellEditor; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JFileChooser; import javax.swing.JTable; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import java.awt.Component; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.dnd.DnDConstants; import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; import java.awt.dnd.DropTargetListener; import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.net.MalformedURLException; import java.util.List; /** * Utility Panel for displaying a table of attachments * * @author emibre */ public class AttachmentsPanel extends javax.swing.JPanel { private DropTarget dropTarget; private FileTransferHandler fileTransferHandler; private AttachmentsTableModel tableModel; private JFileChooser fc; private final AttachmentContainer container; private JButton exportBtn; private JButton reloadBtn; /** * Creates new form FileTableList */ public AttachmentsPanel(AttachmentContainer container) { this.container = container; initComponents(); initFileTransfer(); } public void release() { tableModel.release(); if (attachmentPartCellEditor != null) { attachmentPartCellEditor.release(); } } private void initFileTransfer() { if (container instanceof MutableAttachmentContainer) { fileTransferHandler = new FileTransferHandler(tableModel); fileTable.setDragEnabled(true); fileTable.setTransferHandler(fileTransferHandler); dropTarget = new DropTarget(); dropTarget.setActive(true); try { dropTarget.addDropTargetListener(new DropTargetListener() { public void dragEnter(DropTargetDragEvent dtde) { } public void dragExit(DropTargetEvent dte) { } public void dragOver(DropTargetDragEvent dtde) { } @SuppressWarnings("unchecked") public void drop(DropTargetDropEvent dtde) { try { dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); Transferable trans = dtde.getTransferable(); List<File> files = (List<File>) trans.getTransferData(DataFlavor.javaFileListFlavor); for (File f : files) { System.out.println("Dropping file: " + f.getName()); Boolean retval = UISupport.confirmOrCancel("Cache attachment in request?", "Att Attachment"); if (retval == null) { return; } tableModel.addFile(f, retval); } } catch (Exception e) { SoapUI.logError(e); } } public void dropActionChanged(DropTargetDragEvent dtde) { } }); } catch (Exception e) { SoapUI.logError(e); } jScrollPane1.getViewport().setDropTarget(dropTarget); } } private void initComponents() { jScrollPane1 = new javax.swing.JScrollPane(); tableModel = new AttachmentsTableModel(container); fileTable = JTableFactory.getInstance().makeJTable(tableModel); if (container instanceof MutableAttachmentContainer) { attachmentPartCellEditor = new AttachmentPartCellEditor(); fileTable.getColumnModel().getColumn(3).setCellEditor(attachmentPartCellEditor); } setLayout(new java.awt.BorderLayout()); jScrollPane1.setViewportView(fileTable); add(jScrollPane1, java.awt.BorderLayout.CENTER); jPanel1 = UISupport.createSmallToolbar(); if (container instanceof MutableAttachmentContainer) { addFileBtn = UISupport.createToolbarButton(UISupport.createImageIcon("/add.png")); removeBtn = UISupport.createToolbarButton(UISupport.createImageIcon("/delete.png")); reloadBtn = UISupport.createToolbarButton(UISupport.createImageIcon("/reload_properties.gif")); addFileBtn.setToolTipText("Adds an attachment"); addFileBtn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { addFileBtnActionPerformed(evt); } }); jPanel1.addFixed(addFileBtn); removeBtn.setToolTipText("Removes the selected attachment"); removeBtn.setEnabled(false); removeBtn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { removeBtnActionPerformed(evt); } }); jPanel1.addFixed(removeBtn); reloadBtn.setToolTipText("Reloads the selected attachment"); reloadBtn.setEnabled(false); reloadBtn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { reloadBtnActionPerformed(evt); } }); jPanel1.addFixed(reloadBtn); } exportBtn = UISupport.createToolbarButton(UISupport.createImageIcon("/export.png")); exportBtn.setToolTipText("Exports the selected attachment to a file"); exportBtn.setEnabled(false); exportBtn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { exportBtnActionPerformed(evt); } }); jPanel1.addFixed(exportBtn); jPanel1.addGlue(); jPanel1.addFixed(UISupport.createToolbarButton(new ShowOnlineHelpAction(HelpUrls.ATTACHMENTS_HELP_URL))); add(jPanel1, java.awt.BorderLayout.NORTH); fileTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { if (removeBtn != null) { removeBtn.setEnabled(fileTable.getSelectedRowCount() > 0); reloadBtn.setEnabled(fileTable.getSelectedRowCount() > 0); } exportBtn.setEnabled(fileTable.getSelectedRowCount() > 0); } }); fileTable.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.getClickCount() < 2) { return; } int ix = fileTable.getSelectedRow(); if (ix == -1) { return; } Attachment attachment = container.getAttachmentAt(ix); if (attachment.isCached()) { String name = attachment.getName(); try { name = StringUtils.createFileName(name, '-'); File tempFile = File.createTempFile("attachment-" + name, "." + ContentTypeHandler.getExtensionForContentType(attachment.getContentType())); exportAttachment(tempFile, attachment, false); } catch (Exception e1) { UISupport.showErrorMessage(e1); } } else { Tools.openURL(attachment.getUrl()); } } }); } protected void exportBtnActionPerformed(ActionEvent evt) { File file = UISupport.getFileDialogs().saveAs(this, "Export Attachment.."); while (file != null && file.exists() && !UISupport.confirm("File " + file.getName() + " exists, overwrite?", "Export Attachment")) { file = UISupport.getFileDialogs().saveAs(this, "Export Attachment.."); } if (file != null) { Attachment attachment = tableModel.getAttachmentAt(fileTable.getSelectedRow()); try { exportAttachment(file, attachment, true); } catch (Exception e) { UISupport.showErrorMessage(e); } } } private void exportAttachment(File file, Attachment attachment, boolean showOpenQuery) throws FileNotFoundException, IOException, Exception, MalformedURLException { FileOutputStream out = new FileOutputStream(file); long total = Tools.writeAll(out, attachment.getInputStream()); out.close(); if (!showOpenQuery || UISupport.confirm("Written [" + total + "] bytes to " + file.getName() + ", open in browser?", "Saved File")) { Tools.openURL(file.toURI().toURL().toString()); } } protected void reloadBtnActionPerformed(ActionEvent evt) { int selectedRow = fileTable.getSelectedRow(); if (selectedRow == -1) { return; } WsdlAttachment attachment = (WsdlAttachment) tableModel.getAttachmentAt(selectedRow); if (attachment == null) { return; } File file = UISupport.getFileDialogs().open(this, "Reload Attachment..", "*", "Any File", attachment.getUrl()); if (file != null) { Boolean retval = UISupport.confirmOrCancel("Cache attachment in request?", "Reload Attachment"); if (retval == null) { return; } try { attachment.reload(file, retval); tableModel.fireTableRowsUpdated(selectedRow, selectedRow); } catch (IOException e) { UISupport.showErrorMessage(e); } } } private void addFileBtnActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_addFileBtnActionPerformed if (fc == null) { fc = new JFileChooser(); } String root = PathUtils.getExpandedResourceRoot(container.getModelItem()); if (StringUtils.hasContent(root)) { fc.setCurrentDirectory(new File(root)); } int returnVal = fc.showOpenDialog(this); if (returnVal == JFileChooser.APPROVE_OPTION) { File file = fc.getSelectedFile(); Boolean retval = UISupport.confirmOrCancel("Cache attachment in request?", "Add Attachment"); if (retval == null) { return; } try { tableModel.addFile(file, retval); } catch (IOException e) { UISupport.showErrorMessage(e); } } else { System.out.println("Open command cancelled by user."); } }// GEN-LAST:event_addFileBtnActionPerformed private void removeBtnActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_removeBtnActionPerformed if (UISupport.confirm("Remove selected attachments?", "Remove Attachments")) { tableModel.removeAttachment(fileTable.getSelectedRows()); } }// GEN-LAST:event_removeBtnActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton addFileBtn; private JTable fileTable; private JXToolBar jPanel1; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JButton removeBtn; private AttachmentPartCellEditor attachmentPartCellEditor; // End of variables declaration//GEN-END:variables private class AttachmentPartCellEditor extends DefaultCellEditor { public AttachmentPartCellEditor() { super(new JComboBox(new PartsComboBoxModel())); } public void release() { ((PartsComboBoxModel) ((JComboBox) editorComponent).getModel()).release(); } public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { PartsComboBoxModel model = ((PartsComboBoxModel) ((JComboBox) editorComponent).getModel()); ((JComboBox) editorComponent).setModel(model.init(tableModel.getAttachmentAt(row))); return super.getTableCellEditorComponent(table, value, isSelected, row, column); } } private final class PartsComboBoxModel extends AbstractListModel implements ComboBoxModel, PropertyChangeListener { private Attachment attachment; private AttachmentPart[] parts; public PartsComboBoxModel() { container.addAttachmentsChangeListener(this); } public void release() { container.removeAttachmentsChangeListener(this); } public PartsComboBoxModel init(Attachment attachment) { this.attachment = attachment; int previousPartsCount = parts == null ? 0 : parts.length; parts = container.getDefinedAttachmentParts(); if (previousPartsCount < parts.length) { fireIntervalAdded(this, previousPartsCount, parts.length); } else if (previousPartsCount > parts.length) { fireIntervalRemoved(this, parts.length - 1, previousPartsCount); } fireContentsChanged(this, 0, parts.length - 1); return this; } public Object getElementAt(int index) { return parts == null ? null : parts[index].getName(); } public int getSize() { return parts == null ? 0 : parts.length; } public Object getSelectedItem() { return attachment == null ? null : attachment.getPart(); } public void setSelectedItem(Object anItem) { if (attachment != null) { attachment.setPart((String) anItem); } } public void propertyChange(PropertyChangeEvent arg0) { // delete our current one? if (arg0.getOldValue() == attachment && arg0.getNewValue() == null) { attachment = null; parts = null; } } } }