package org.wiztools.restclient.ui.reqbody;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.dnd.DropTarget;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.swing.*;
import org.wiztools.commons.FileUtil;
import org.wiztools.restclient.XMLException;
import org.wiztools.restclient.bean.ReqEntity;
import org.wiztools.restclient.bean.ReqEntityByteArray;
import org.wiztools.restclient.bean.ReqEntityByteArrayBean;
import org.wiztools.restclient.ui.FileChooserType;
import org.wiztools.restclient.ui.RCFileView;
import org.wiztools.restclient.ui.RESTUserInterface;
import org.wiztools.restclient.ui.UIUtil;
import org.wiztools.restclient.ui.dnd.DndAction;
import org.wiztools.restclient.ui.dnd.FileDropTargetListener;
import org.wiztools.restclient.util.HexDump;
import org.wiztools.restclient.util.Util;
import org.wiztools.restclient.util.XMLUtil;
/**
*
* @author subwiz
*/
public class ReqBodyPanelByteArray extends JPanel implements ReqBodyPanel {
@Inject private RESTUserInterface rest_ui;
@Inject private ContentTypeCharsetComponent jp_content_type_charset;
private final JButton jb_body = new JButton(UIUtil.getIconFromClasspath(RCFileView.iconBasePath + "load_from_file.png"));
private final JTextArea jta = new JTextArea();
private byte[] body;
private static final int FILE_SIZE_THRESHOLD_LIMIT_MB = 2;
@PostConstruct
protected void init() {
setLayout(new BorderLayout());
JPanel jp_north = new JPanel(new FlowLayout(FlowLayout.LEFT));
jp_north.add(jp_content_type_charset.getComponent());
jb_body.setToolTipText("Select file having body content");
jb_body.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
fileOpen();
}
});
jp_north.add(jb_body);
add(jp_north, BorderLayout.NORTH);
jta.setFont(UIUtil.FONT_MONO_PLAIN);
jta.setEditable(false);
add(new JScrollPane(jta), BorderLayout.CENTER);
// DnD:
FileDropTargetListener l = new FileDropTargetListener();
l.addDndAction(new DndAction() {
@Override
public void onDrop(List<File> files) {
fileOpen(files.get(0));
}
});
new DropTarget(jta, l);
new DropTarget(jb_body, l);
}
private void fileOpen() {
File f = rest_ui.getOpenFile(FileChooserType.OPEN_REQUEST_BODY);
fileOpen(f);
}
private void fileOpen(File f) {
if(f == null){ // Pressed cancel?
return;
}
if(!f.canRead()){
JOptionPane.showMessageDialog(rest_ui.getFrame(),
"File not readable: " + f.getAbsolutePath(),
"IO Error",
JOptionPane.ERROR_MESSAGE);
return;
}
final String mime = FileUtil.getMimeType(f);
if(!mime.equals("content/unknown")) {
final String origContentType = jp_content_type_charset.getContentType().getContentType();
if(!mime.equals(origContentType)) {
final int result = JOptionPane.showConfirmDialog(rest_ui.getFrame(),
"The content-type selected (" + origContentType + ") does NOT match\n"
+ "the computed file mime type (" + mime + ")\n"
+ "Do you want to update the content-type to `" + mime + "'?",
"Mime-type mismatch correction",
JOptionPane.YES_NO_OPTION);
if(result == JOptionPane.YES_OPTION) {
// Set content type
jp_content_type_charset.setContentType(mime);
// Check if XML content type:
if(XMLUtil.XML_MIME.equals(mime)){
try{
String charset = XMLUtil.getDocumentCharset(f);
if(charset != null && !(charset.equals(jp_content_type_charset.getCharsetString()))) {
final int charsetYesNo = JOptionPane.showConfirmDialog(rest_ui.getFrame(),
"Change charset to `" + charset + "'?",
"Change charset?",
JOptionPane.YES_NO_OPTION);
if(charsetYesNo == JOptionPane.YES_OPTION) {
jp_content_type_charset.setCharset(Charset.forName(charset));
}
}
}
catch(IOException ex){
// Do nothing!
}
catch(XMLException ex){
// Do nothing!
}
}
}
}
}
final long fileSizeMB = f.length() / (1024l*1024l);
if(fileSizeMB > FILE_SIZE_THRESHOLD_LIMIT_MB) {
final int yesNoOption = JOptionPane.showConfirmDialog(rest_ui.getFrame(),
"File size is more than " + FILE_SIZE_THRESHOLD_LIMIT_MB + " MB."
+ "\nBigger files are recommended to be configured using the File body."
+ "\nDo you want to continue loading?",
"File exceeds threshold size",
JOptionPane.YES_NO_OPTION);
if(yesNoOption == JOptionPane.NO_OPTION) {
return;
}
}
try {
byte[] data = FileUtil.getContentAsBytes(f);
body = data;
jta.setText(HexDump.getHexDataDumpAsString(data));
jta.setCaretPosition(0);
}
catch(IOException ex) {
rest_ui.getView().doError(Util.getStackTrace(ex));
}
}
@Override
public void enableBody() {
jp_content_type_charset.enableComponent();
jb_body.setEnabled(true);
jta.setEnabled(true);
}
@Override
public void disableBody() {
jp_content_type_charset.disableComponent();
jb_body.setEnabled(false);
jta.setEnabled(false);
}
@Override
public void setEntity(ReqEntity entity) {
if(entity instanceof ReqEntityByteArray) {
ReqEntityByteArray e = (ReqEntityByteArray) entity;
// content-type charset
jp_content_type_charset.setContentTypeCharset(e.getContentType());
// Set body:
body = e.getBody();
jta.setText(HexDump.getHexDataDumpAsString(e.getBody()));
}
}
@Override
public ReqEntity getEntity() {
ReqEntityByteArrayBean out = new ReqEntityByteArrayBean(body,
jp_content_type_charset.getContentType());
return out;
}
@Override
public Component getComponent() {
return this;
}
@Override
public void clear() {
jp_content_type_charset.clear();
body = null;
jta.setText("");
}
}