Java tutorial
/* * Copyright 2008 Nick Powers. * This file is part of WSExplorer. * * WSExplorer is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * WSExplorer is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with WSExplorer. If not, see <http://www.gnu.org/licenses/>. */ package com.powers.wsexplorer.gui; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.CancellationException; import java.util.concurrent.CompletionService; import java.util.concurrent.ExecutorCompletionService; import java.util.concurrent.Future; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import javax.xml.soap.SOAPConnection; import org.apache.commons.lang.StringUtils; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.ProgressBar; import org.eclipse.swt.widgets.Scrollable; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.ToolBar; import org.eclipse.swt.widgets.ToolItem; import com.powers.wsexplorer.ws.SimpleIO; import com.powers.wsexplorer.ws.SoapResponse; import com.powers.wsexplorer.ws.SoapSender; import com.powers.wsexplorer.ws.WSUtil; import com.swtdesigner.SWTResourceManager; public class WSExplorer { final static String VERSION = "0.7"; final int CONTROL_A = 'A' - 0x40; // the "control A" character final int CONTROL_S = 'S' - 0x40; // the "control S" character final int CONTROL_F = 'F' - 0x40; // the "control S" character final int CONTROL_Z = 'Z' - 0x40; // the "control Z" character final int CONTROL_Y = 'Y' - 0x40; // the "control Y" character private static final String UTF8 = "UTF-8"; private static final String XML_EXT = "xml"; private static String[] XML_FILTER_EXT = { "*.xml" }; private final static String SAVED_STATE_FILE = "saved_state.txt"; private final static String ENDPOINTS_FILE = "endpoints.txt"; private final static String SOAP_TEMPLATE_FILE = "/SOAPTemplate.xml"; private final static String GPLV3_FILE = "/gpl-3.0.txt"; private final static String SECONDS = "Seconds"; private final static String MILLISECONDS = "Milliseconds"; final static String[] TIMEOUT_CHOICES = { SECONDS, MILLISECONDS }; private transient boolean CancelWasPressed = false; private static SOAPConnection CONNECTION = null; private static final Image CHECK_IMAGE = SWTResourceManager.getImage(WSExplorer.class, "/check.png"); private static final Image X_IMAGE = SWTResourceManager.getImage(WSExplorer.class, "/x.png"); private final Shell shell = new Shell(); private BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10); private ThreadPoolExecutor tpe = new ThreadPoolExecutor(5, 10, 10, TimeUnit.SECONDS, q); private CompletionService ecs = new ExecutorCompletionService(tpe); private SoapSender soapSender = new SoapSender(); private boolean maintainSession = false; private Map<String, String> headers = new HashMap<String, String>(); private AtomicBoolean isSending = new AtomicBoolean(false); private AtomicBoolean shouldStopProgressBar = new AtomicBoolean(false); private List<String> comboItems = getEndpointHistory(); private Map<String, Scrollable> itemsToSaveState = new HashMap<String, Scrollable>(); private Combo endpointCombo; private StyledText responseText; private StyledText requestText; private ProgressBar progressBar; private Label statusText; private Exception statusTextException; private Options options = null; private Button cancelButton = null; private Label timeElapsedLabel; private Label statusLabel; private Label sessionIdLabel; private ToolItem maintSessionButton; private UndoRedoListener requestTextUndoRedoListener = null; /** * Launch the application * @param args */ public static void main(String[] args) { try { WSExplorer window = new WSExplorer(); window.open(); } catch (Exception e) { e.printStackTrace(); } } /** * Open the window */ public void open() { final Display display = Display.getDefault(); shell.setText("WS Explorer"); shell.setLayout(new FormLayout()); shell.setImage(SWTResourceManager.getImage(WSExplorer.class, "/Earth-Scan-16x16.png")); shell.setMinimumSize(new Point(620, 665)); shell.addDisposeListener(new DisposeListener() { public void widgetDisposed(final DisposeEvent e) { tpe.shutdownNow(); saveEndpointsToFile(); saveStateToFile(itemsToSaveState, SAVED_STATE_FILE); // delete any temporary files used to display in 'Browser View' deleteTemporaryFiles(); } }); // Label requestLabel; Label responseLabel; Label wsExplorerLabel; wsExplorerLabel = new Label(shell, SWT.NONE); wsExplorerLabel.setImage(SWTResourceManager.getImage(WSExplorer.class, "/logo.png")); final FormData fd_wsExplorerLabel = new FormData(); fd_wsExplorerLabel.bottom = new FormAttachment(0, 66); fd_wsExplorerLabel.top = new FormAttachment(0, 38); fd_wsExplorerLabel.right = new FormAttachment(0, 218); fd_wsExplorerLabel.left = new FormAttachment(0, 6); wsExplorerLabel.setLayoutData(fd_wsExplorerLabel); wsExplorerLabel.setToolTipText("Web Service Explorer"); wsExplorerLabel.setFont(SWTResourceManager.getFont("", 14, SWT.NONE)); wsExplorerLabel.setText("Web Service Explorer"); endpointCombo = new Combo(shell, SWT.NONE); final FormData fd_endpointCombo = new FormData(); fd_endpointCombo.right = new FormAttachment(100, -140); fd_endpointCombo.bottom = new FormAttachment(0, 117); fd_endpointCombo.top = new FormAttachment(0, 96); fd_endpointCombo.left = new FormAttachment(0, 9); endpointCombo.setLayoutData(fd_endpointCombo); endpointCombo .setToolTipText("Enter Endpoint URL. Right-click to clear a single or all items from the list"); // set the items in the combo from a file if (comboItems.size() > 0) { String[] s = (String[]) comboItems.toArray(new String[comboItems.size()]); endpointCombo.setItems(s); } else { System.out.println("No saved endpoints found"); } Label endpointLabel; endpointLabel = new Label(shell, SWT.NONE); final FormData fd_endpointLabel = new FormData(); fd_endpointLabel.bottom = new FormAttachment(0, 89); fd_endpointLabel.top = new FormAttachment(0, 76); fd_endpointLabel.right = new FormAttachment(0, 51); fd_endpointLabel.left = new FormAttachment(0, 9); endpointLabel.setLayoutData(fd_endpointLabel); endpointLabel.setText("Endpoint"); progressBar = new ProgressBar(shell, SWT.NONE); final FormData fd_progressBar = new FormData(); fd_progressBar.bottom = new FormAttachment(100, -22); fd_progressBar.top = new FormAttachment(100, -39); fd_progressBar.left = new FormAttachment(100, -189); fd_progressBar.right = new FormAttachment(100, -2); progressBar.setLayoutData(fd_progressBar); progressBar.setToolTipText("Progress Of Current Action"); Button sendButton2; sendButton2 = new Button(shell, SWT.NONE); final FormData fd_sendButton2 = new FormData(); fd_sendButton2.bottom = new FormAttachment(100, -30); fd_sendButton2.top = new FormAttachment(100, -53); fd_sendButton2.right = new FormAttachment(0, 69); fd_sendButton2.left = new FormAttachment(0, 9); sendButton2.setLayoutData(fd_sendButton2); sendButton2.setToolTipText("Send The Message"); sendButton2.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { String endpointText = endpointCombo.getText(); if (endpointText == null || endpointText.equals("")) { statusText.setText("endpoint is null or empty"); return; } String msgText = requestText.getText(); if (msgText == null || msgText.equals("")) { statusText.setText("SOAP request is null or empty"); return; } // SAVE TO ENDPOINT URL LIST OF STRINGS boolean save = true; // check if we really want to save this... try { new URL(endpointText); } catch (MalformedURLException me) { // don't save save = false; } if (save) { saveEndpoint(endpointText); } // clear response text responseText.setText(StringUtils.EMPTY); sessionIdLabel.setText(StringUtils.EMPTY); // clear jsession id // clear status image setStatusImage(null); // set status bar... log("Sending..."); statusTextException = null; cancelButton.setEnabled(true); CONNECTION = soapSender.getConnection(); if (isSending.get()) { log("Currently sending a message. You can only send one at a time..."); return; } isSending.set(true); ExecuteWS aExecuteWS = new ExecuteWS(endpointText, msgText, CONNECTION, headers); Future<SoapResponse> executeWsFuture = ecs.submit(aExecuteWS); PopulateResponse aPopulateResponse = new PopulateResponse(shell, responseText, progressBar, statusText, executeWsFuture); ecs.submit(aPopulateResponse); IncrementProgressBar aIncrementProgressBar = new IncrementProgressBar(shell, progressBar, shouldStopProgressBar); ecs.submit(aIncrementProgressBar); IncrementTimeElapsed aIncrementTimeElapsed = new IncrementTimeElapsed(isSending); Future<String> timeElapsedFuture = ecs.submit(aIncrementTimeElapsed); PopulateTimeElapsed aPopulateTimeElapsed = new PopulateTimeElapsed(timeElapsedFuture); ecs.submit(aPopulateTimeElapsed); } }); sendButton2.setText("Send"); final Menu menu = new Menu(shell, SWT.BAR); shell.setMenuBar(menu); final MenuItem newSubmenuMenuItem = new MenuItem(menu, SWT.CASCADE); newSubmenuMenuItem.setText("File"); // main menu final Menu menu_1 = new Menu(newSubmenuMenuItem); newSubmenuMenuItem.setMenu(menu_1); // menu item 1 - OPTIONS final MenuItem optionsMenuItem = new MenuItem(menu_1, SWT.NONE); optionsMenuItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { OptionsDialog od = new OptionsDialog(shell); od.setOptions(options); String resultMessage = (String) od.open(); log(resultMessage); } }); optionsMenuItem.setText("Options"); // menu item 2 - EXIT final MenuItem newItemMenuItem_1 = new MenuItem(menu_1, SWT.NONE); newItemMenuItem_1.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { shell.close(); } }); newItemMenuItem_1.setText("Exit"); // ==== EDIT MENU final MenuItem editMenu = new MenuItem(menu, SWT.CASCADE); editMenu.setText("Edit"); final Menu editSubMenu = new Menu(editMenu); editMenu.setMenu(editSubMenu); final MenuItem findMenuItem = new MenuItem(editSubMenu, SWT.NONE); findMenuItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { FindDialog findDialog = new FindDialog(shell, responseText); findDialog.open(); } }); findMenuItem.setText("Find"); final MenuItem helpMenu = new MenuItem(menu, SWT.CASCADE); helpMenu.setText("Help"); final Menu menu_5 = new Menu(helpMenu); helpMenu.setMenu(menu_5); final MenuItem aboutMenuItem = new MenuItem(menu_5, SWT.NONE); aboutMenuItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { MessageBox mb = new MessageBox(shell, SWT.OK | SWT.ICON_INFORMATION); mb.setText("About WSExplorer"); mb.setMessage("WSExplorer is an open source program written by Nick Powers.\n" + "WSExplorer is protected by the GNU General Public License v3 (http://www.gnu.org/licenses/gpl.html).\n\n" + "Version: " + VERSION + "\n" + "Project Site: http://code.google.com/p/wsexplorer/"); mb.open(); } }); aboutMenuItem.setText("About"); final MenuItem viewLicenseMenuItem = new MenuItem(menu_5, SWT.NONE); viewLicenseMenuItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { TextDialog td = new TextDialog(shell); td.setTitle("GPL License"); td.setText(getText(getClass().getResourceAsStream(GPLV3_FILE))); td.open(); } }); viewLicenseMenuItem.setText("View License"); final MenuItem viewStackTraceMenuItem = new MenuItem(menu_5, SWT.NONE); viewStackTraceMenuItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { if (statusTextException != null) { TextDialog td = new TextDialog(shell); td.setTitle("Stack Trace"); td.setText(getStrackTraceAsString(statusTextException)); td.open(); } } }); viewStackTraceMenuItem.setText("View Stacktrace"); ToolBar toolBar; toolBar = new ToolBar(shell, SWT.NONE); toolBar.setLayoutData(new FormData()); final ToolItem newItemToolItem_5 = new ToolItem(toolBar, SWT.PUSH); newItemToolItem_5.setText("Save"); newItemToolItem_5.setImage(SWTResourceManager.getImage(WSExplorer.class, "/Save-icon.png")); newItemToolItem_5.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { saveToFile(requestText.getText(), XML_EXT); } }); newItemToolItem_5.setToolTipText("Save the text in the Request TextBox"); final ToolItem newItemToolItem_6 = new ToolItem(toolBar, SWT.PUSH); newItemToolItem_6.setImage(SWTResourceManager.getImage(WSExplorer.class, "/Open-icon.png")); newItemToolItem_6.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { FileDialog fd = new FileDialog(shell, SWT.OPEN); fd.setFilterExtensions(XML_FILTER_EXT); fd.open(); if (fd.getFileName() != null && !fd.getFileName().equalsIgnoreCase("")) { String filename = fd.getFilterPath() + "\\" + fd.getFileName(); String text = getText(new File(filename)); requestText.setText(text); } else { log("Did not choose a file"); } } }); newItemToolItem_6.setToolTipText("Load text into the Request TextBox"); newItemToolItem_6.setText("Open"); final ToolItem newItemToolItem_4 = new ToolItem(toolBar, SWT.SEPARATOR); newItemToolItem_4.setText(" "); newItemToolItem_4.setWidth(32); final ToolItem newItemToolItem = new ToolItem(toolBar, SWT.PUSH); newItemToolItem.setImage(SWTResourceManager.getImage(WSExplorer.class, "/Delete-icon.png")); newItemToolItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { requestText.setText(""); responseText.setText(""); } }); newItemToolItem.setToolTipText("Clear All TextBoxes"); newItemToolItem.setText("All"); final ToolItem newItemToolItem_1 = new ToolItem(toolBar, SWT.PUSH); newItemToolItem_1.setImage(SWTResourceManager.getImage(WSExplorer.class, "/Delete-icon.png")); newItemToolItem_1.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { requestText.setText(""); } }); newItemToolItem_1.setToolTipText("Clear Request TextBox"); newItemToolItem_1.setText("Request"); final ToolItem newItemToolItem_2 = new ToolItem(toolBar, SWT.PUSH); newItemToolItem_2.setImage(SWTResourceManager.getImage(WSExplorer.class, "/Delete-icon.png")); newItemToolItem_2.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { responseText.setText(""); } }); newItemToolItem_2.setToolTipText("Clear Response TextBox"); newItemToolItem_2.setText("Response"); ToolItem toolItem = new ToolItem(toolBar, SWT.SEPARATOR); toolItem.setWidth(32); ToolItem headerToolItem = new ToolItem(toolBar, SWT.NONE); headerToolItem.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { HeaderDialog headerDialog = new HeaderDialog(shell, headers); headers = (Map<String, String>) headerDialog.open(); } }); headerToolItem.setText("Headers"); headerToolItem.setImage(SWTResourceManager.getImage(WSExplorer.class, "/headers.png")); maintSessionButton = new ToolItem(toolBar, SWT.CHECK); maintSessionButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { maintainSession = maintSessionButton.getSelection(); if (!maintainSession) { soapSender.clearSessionData(); } } }); maintSessionButton.setToolTipText( "Maintain session between web service calls via JSESSION ID. For a new session, this should not be selected"); maintSessionButton.setText("Session"); maintSessionButton.setImage(SWTResourceManager.getImage(WSExplorer.class, "/maint_session.png")); statusText = new Label(shell, SWT.BORDER); final FormData fd_statusText = new FormData(); fd_statusText.bottom = new FormAttachment(100, 0); fd_statusText.top = new FormAttachment(100, -18); fd_statusText.left = new FormAttachment(0, 0); fd_statusText.right = new FormAttachment(100, 0); statusText.setLayoutData(fd_statusText); statusText .setToolTipText("Status Messages Appear Here. Right-Click for error details (if an error exists)."); statusText.setBackground(SWTResourceManager.getColor(192, 192, 192)); // Popup for Status Text final Menu statusTextPopUpMenu = new Menu(statusText); statusText.setMenu(statusTextPopUpMenu); // View Stack Trace Menu Item final MenuItem seeStackTrace_statusText_menuItem = new MenuItem(statusTextPopUpMenu, SWT.NONE); seeStackTrace_statusText_menuItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { if (statusTextException != null) { TextDialog td = new TextDialog(shell); td.setTitle("Stack Trace"); td.setText(getStrackTraceAsString(statusTextException)); td.open(); } } }); seeStackTrace_statusText_menuItem.setText("See Full Stack Trace"); // Clear Status Menu Item final MenuItem clearStatusText_menuItem = new MenuItem(statusTextPopUpMenu, SWT.NONE); clearStatusText_menuItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { log(""); } }); clearStatusText_menuItem.setText("Clear Status"); final Menu menu_2 = new Menu(endpointCombo); endpointCombo.setMenu(menu_2); final MenuItem newItemMenuItem = new MenuItem(menu_2, SWT.NONE); newItemMenuItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { String s = endpointCombo.getText(); if (s != null && !s.equals("")) { comboItems.remove(s); updateEndpointCombo(""); } } }); newItemMenuItem.setText("Clear Current Item"); final MenuItem newItemMenuItem_2 = new MenuItem(menu_2, SWT.NONE); newItemMenuItem_2.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { MessageBox mb = new MessageBox(shell, SWT.YES | SWT.NO); mb.setText("Clear All Items In Combo Box?"); mb.setMessage("Are you sure you want to clear the entire combo box?"); if (mb.open() == SWT.YES) { comboItems.clear(); updateEndpointCombo(""); log("Cleared combo box"); } } }); newItemMenuItem_2.setText("Clear All Items"); cancelButton = new Button(shell, SWT.NONE); final FormData fd_cancelButton = new FormData(); fd_cancelButton.left = new FormAttachment(100, -252); fd_cancelButton.top = new FormAttachment(100, -43); fd_cancelButton.bottom = new FormAttachment(100, -20); fd_cancelButton.right = new FormAttachment(progressBar, -3, SWT.LEFT); cancelButton.setLayoutData(fd_cancelButton); cancelButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { CancelWasPressed = true; log("Cancelling current operation..."); } }); cancelButton.setToolTipText("Cancel the current operation."); cancelButton.setText("Cancel"); cancelButton.setEnabled(false); timeElapsedLabel = new Label(shell, SWT.NONE); final FormData fd_timeElapsedLabel = new FormData(); fd_timeElapsedLabel.top = new FormAttachment(100, -54); fd_timeElapsedLabel.bottom = new FormAttachment(progressBar, -2, SWT.DEFAULT); fd_timeElapsedLabel.left = new FormAttachment(100, -182); fd_timeElapsedLabel.right = new FormAttachment(100, -2); timeElapsedLabel.setLayoutData(fd_timeElapsedLabel); final SashForm sashForm = new SashForm(shell, SWT.VERTICAL); sashForm.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); final FormData fd_sashForm = new FormData(); fd_sashForm.bottom = new FormAttachment(100, -59); fd_sashForm.right = new FormAttachment(100, -2); fd_sashForm.left = new FormAttachment(0, 7); fd_sashForm.top = new FormAttachment(0, 122); sashForm.setLayoutData(fd_sashForm); final Composite composite = new Composite(sashForm, SWT.NONE); composite.setLayout(new FormLayout()); requestLabel = new Label(composite, SWT.NONE); final FormData fd_requestLabel = new FormData(); fd_requestLabel.bottom = new FormAttachment(0, 16); fd_requestLabel.top = new FormAttachment(0, 3); fd_requestLabel.right = new FormAttachment(0, 43); fd_requestLabel.left = new FormAttachment(0, 3); requestLabel.setLayoutData(fd_requestLabel); requestLabel.setText("Request"); requestText = new StyledText(composite, SWT.V_SCROLL | SWT.MULTI | SWT.H_SCROLL | SWT.BORDER); final FormData fd_requestText = new FormData(); fd_requestText.top = new FormAttachment(0, 19); fd_requestText.bottom = new FormAttachment(100, -4); fd_requestText.left = new FormAttachment(0, 3); fd_requestText.right = new FormAttachment(100, -2); requestText.setLayoutData(fd_requestText); // add undo listener requestTextUndoRedoListener = new UndoRedoListener(requestText, this); requestText.addKeyListener(new KeyAdapter() { public void keyPressed(final KeyEvent e) { if (e.character == CONTROL_A) { requestText.selectAll(); } else if (e.character == CONTROL_S) { saveToFile(requestText.getText(), XML_EXT); } else if (e.character == CONTROL_F) { FindDialog findDialog = new FindDialog(shell, requestText); findDialog.open(); } else if (e.character == CONTROL_Z) { requestTextUndoRedoListener.undo(); } else if (e.character == CONTROL_Y) { requestTextUndoRedoListener.redo(); } } }); requestText.setFont(SWTResourceManager.getFont("Courier New", 10, SWT.NONE)); requestText.addLineStyleListener(new HTMLLineStyler()); final Menu requestPopUpMenu = new Menu(requestText); requestText.setMenu(requestPopUpMenu); addTextOperationsToPopupMenu(requestText, requestPopUpMenu); addSeperator(requestPopUpMenu); final MenuItem openInBrowserView_request_popUp = new MenuItem(requestPopUpMenu, SWT.NONE); openInBrowserView_request_popUp.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { openInBrowserView(requestText.getText()); } }); openInBrowserView_request_popUp.setText("Open In Browser View"); final MenuItem newItemMenuItem_3 = new MenuItem(requestPopUpMenu, SWT.NONE); newItemMenuItem_3.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { String text = getText(getClass().getResourceAsStream(SOAP_TEMPLATE_FILE)); requestText.setText(text); } }); newItemMenuItem_3.setText("Populate With SOAP Template"); // pretty print menu item for request text box final MenuItem prettyPrint_request_popUp = new MenuItem(requestPopUpMenu, SWT.NONE); prettyPrint_request_popUp.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { String text = requestText.getText(); if (text == null || ("").equalsIgnoreCase(text)) { log("Did not pretty print...there is nothing to format!"); return; } String prettyText = null; try { prettyText = WSUtil.prettyPrint(text); requestText.setText(prettyText); log("Text was pretty printed"); } catch (Exception ex) { log("Unable to pretty print due to malformed XML"); } } }); prettyPrint_request_popUp.setText("Pretty Print"); final Composite composite_1 = new Composite(sashForm, SWT.NONE); composite_1.setLayout(new FormLayout()); responseLabel = new Label(composite_1, SWT.NONE); final FormData fd_responseLabel = new FormData(); fd_responseLabel.bottom = new FormAttachment(0, 16); fd_responseLabel.top = new FormAttachment(0, 3); fd_responseLabel.right = new FormAttachment(0, 50); fd_responseLabel.left = new FormAttachment(0, 3); responseLabel.setLayoutData(fd_responseLabel); responseLabel.setText("Response"); responseText = new StyledText(composite_1, SWT.V_SCROLL | SWT.MULTI | SWT.H_SCROLL | SWT.BORDER); final FormData fd_responseText = new FormData(); fd_responseText.top = new FormAttachment(0, 19); fd_responseText.right = new FormAttachment(100, 2); fd_responseText.left = new FormAttachment(0, 3); fd_responseText.bottom = new FormAttachment(100, -7); responseText.setLayoutData(fd_responseText); responseText.addKeyListener(new KeyAdapter() { public void keyPressed(final KeyEvent e) { if (e.character == CONTROL_A) { responseText.selectAll(); } else if (e.character == CONTROL_S) { saveToFile(responseText.getText(), XML_EXT); } else if (e.character == CONTROL_F) { FindDialog findDialog = new FindDialog(shell, responseText); findDialog.open(); } } }); responseText.setFont(SWTResourceManager.getFont("Courier New", 10, SWT.NONE)); responseText.addLineStyleListener(new HTMLLineStyler()); final Menu responsePopUpMenu = new Menu(responseText); responseText.setMenu(responsePopUpMenu); addTextOperationsToPopupMenu(responseText, responsePopUpMenu); addSeperator(responsePopUpMenu); final MenuItem openInBrowserView_response_popUp = new MenuItem(responsePopUpMenu, SWT.NONE); openInBrowserView_response_popUp.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { openInBrowserView(responseText.getText()); } }); openInBrowserView_response_popUp.setText("Open In Browser View"); // pretty print menu item for response text box final MenuItem prettyPrint_response_popUp = new MenuItem(responsePopUpMenu, SWT.NONE); prettyPrint_response_popUp.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { String text = responseText.getText(); if (text == null || ("").equalsIgnoreCase(text)) { log("Did not pretty print...there is nothing to format!"); return; } String prettyText = null; try { prettyText = WSUtil.prettyPrint(text); responseText.setText(prettyText); log("Text was pretty printed"); } catch (Exception ex) { log("Unable to pretty print due to malformed XML"); } } }); prettyPrint_response_popUp.setText("Pretty Print"); final Label label = new Label(shell, SWT.NONE); label.setToolTipText("WS Explorer"); label.setImage(SWTResourceManager.getImage(WSExplorer.class, "/Earth-Scan-icon-128.png")); final FormData fd_label = new FormData(); fd_label.bottom = new FormAttachment(0, 131); fd_label.top = new FormAttachment(0, 3); fd_label.left = new FormAttachment(100, -140); fd_label.right = new FormAttachment(100, -12); label.setLayoutData(fd_label); statusLabel = new Label(shell, SWT.NONE); final FormData fd_sessionIdLabel = new FormData(); fd_sessionIdLabel.bottom = new FormAttachment(100, -26); fd_sessionIdLabel.right = new FormAttachment(0, 108); fd_sessionIdLabel.top = new FormAttachment(100, -57); fd_sessionIdLabel.left = new FormAttachment(sendButton2, 3, SWT.DEFAULT); statusLabel.setLayoutData(fd_sessionIdLabel); sashForm.setWeights(new int[] { 1, 1 }); sessionIdLabel = new Label(shell, SWT.NONE); sessionIdLabel.setForeground(SWTResourceManager.getColor(SWT.COLOR_DARK_GRAY)); FormData sessionIdLabelFormData = new FormData(); sessionIdLabelFormData.right = new FormAttachment(cancelButton, -6); sessionIdLabelFormData.bottom = new FormAttachment(statusText, -4); sessionIdLabelFormData.left = new FormAttachment(statusLabel, 23); sessionIdLabel.setLayoutData(sessionIdLabelFormData); shell.layout(); // =================================================== // do any finishing stuff with fully populated widgets // =================================================== options = getOptions(); if (options.ignoreHostCertificates) { try { soapSender.ignoreCertificates(); } catch (Exception e) { log(e.getMessage(), e); statusTextException = e; e.printStackTrace(); } } //shell.pack(); // =================================================== // done with dealing with fully populated widgets // =================================================== putItemsToSaveState(); loadStateFromFile(SAVED_STATE_FILE, itemsToSaveState); // attach undo/redo listener after initial text is added to window requestText.addExtendedModifyListener(requestTextUndoRedoListener.getListener()); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } } public void setStatusImage(final Boolean status) { shell.getDisplay().asyncExec(new Runnable() { public void run() { if (status == null) { statusLabel.setImage(null); } else if (status) { statusLabel.setImage(CHECK_IMAGE); } else { statusLabel.setImage(X_IMAGE); } } }); } private void saveStateToFile(Map<String, Scrollable> itemsToSave, String filename) { if (itemsToSave == null || StringUtils.isBlank(filename)) { return; } Properties props = new Properties(); Scrollable s = null; Text text = null; StyledText styledText = null; Combo combo = null; String value = null; Set<String> keys = itemsToSave.keySet(); for (String str : keys) { if (StringUtils.isBlank(str)) { continue; } s = itemsToSave.get(str); if (s instanceof Text) { text = (Text) s; } else if (s instanceof StyledText) { styledText = (StyledText) s; } else if (s instanceof Combo) { combo = (Combo) s; } // get the text out of the widget if (text != null) { value = text.getText(); } else if (styledText != null) { value = styledText.getText(); } else if (combo != null) { value = combo.getText(); } if (StringUtils.isNotBlank(value)) { props.put(str, value); } text = null; combo = null; styledText = null; } FileOutputStream fos = null; try { fos = new FileOutputStream(new File(filename)); props.store(fos, "State Saved"); } catch (Exception e) { log("Unable to save state", e); } } private void loadStateFromFile(String filename, Map<String, Scrollable> itemsToSave) { Properties props = new Properties(); File file = new File(filename); if (!file.exists()) { log("No Saved State file (this is fine the first time)"); return; } try { props.load(new FileInputStream(file)); } catch (Exception e) { log("Unable to load state from the file " + filename, e); return; } Scrollable s = null; String value = null; Text text = null; StyledText styledText = null; Combo combo = null; Set<String> keys = itemsToSave.keySet(); for (String key : keys) { value = props.getProperty(key); s = itemsToSave.get(key); // if null or empty, just keep going to the next one if (StringUtils.isBlank(value) || s == null) { continue; } // find the right widget if (s instanceof Text) { text = (Text) s; } else if (s instanceof StyledText) { styledText = (StyledText) s; } else if (s instanceof Combo) { combo = (Combo) s; } // populate the right widget if (text != null) { text.setText(value); } else if (styledText != null) { styledText.setText(value); } else if (combo != null) { combo.setText(value); } text = null; combo = null; styledText = null; } } private void putItemsToSaveState() { itemsToSaveState.put("endpointCombo", endpointCombo); itemsToSaveState.put("requestText", requestText); itemsToSaveState.put("responseText", responseText); } /** * Handles the execution of the call. It's design to be used in a <tt>CompletionService</tt>. * */ public class ExecuteWS implements Callable<SoapResponse> { String endpointURL = null; String soapMessage = null; SOAPConnection connection = null; Map<String, String> requestHeaders = Collections.emptyMap(); public ExecuteWS(String endpointURL, String soapMessage, SOAPConnection connection) { this.endpointURL = endpointURL; this.soapMessage = soapMessage; this.connection = connection; } public ExecuteWS(String endpointURL, String soapMessage, SOAPConnection connection, Map<String, String> requestHeaders) { this.endpointURL = endpointURL; this.soapMessage = soapMessage; this.connection = connection; this.requestHeaders = requestHeaders; } @Override public SoapResponse call() throws Exception { String response = soapSender.sendAndReceiveSOAPMessage(endpointURL, soapMessage, connection, requestHeaders, maintainSession); return new SoapResponse(response, soapSender.jsessionId, soapSender.cookie, soapSender.maintainedSessionFromPreviousCall); } } /** * Handles populating the response text box with the result when the * result is available. It takes the <tt>Future</tt> that is generated * when submitting the <tt>ExecuteWS</tt> Class to the <tt>CompletionService</tt>. */ public class PopulateResponse implements Callable<String> { final Shell shell; final StyledText responseText; final ProgressBar pb; final Label statusText; final Future<SoapResponse> future; public PopulateResponse(Shell shell, StyledText responseText, ProgressBar pb, Label statusText, Future<SoapResponse> future) { super(); this.shell = shell; this.responseText = responseText; this.pb = pb; this.statusText = statusText; this.future = future; } @Override public String call() throws Exception { final StringBuffer statusStringToSet = new StringBuffer(); final StringBuffer responseStringToSet = new StringBuffer(); final StringBuffer jSesionIdToSet = new StringBuffer(); final AtomicBoolean maintainSession = new AtomicBoolean(); while (!future.isDone()) { // check if cancel was clicked... if (CancelWasPressed) { if (CONNECTION != null) { CONNECTION.close(); CONNECTION = null; } cancelSoapSend(future); } else { // sleep Thread.sleep(300); } } isSending.set(false); String text = ""; SoapResponse soapResponse = SoapResponse.EMPTY_SOAP_RESPONSE; try { soapResponse = future.get(); if (soapResponse == null) { soapResponse = SoapResponse.EMPTY_SOAP_RESPONSE; } text = soapResponse.response; } catch (CancellationException e) { statusStringToSet.append("Operation was cancelled successfully"); } // close the connection if it's open if (CONNECTION != null) { CONNECTION.close(); } System.out.println("Text from the call: " + text); if (text != null && !text.equals("") && !CancelWasPressed) { if (text.contains(SoapSender.ERROR_PREFIX)) { statusStringToSet.append(text); responseStringToSet.append("No response was given"); statusTextException = SoapSender.CURRENT_EXCEPTION; setStatusImage(false); } else { responseStringToSet.append(text); jSesionIdToSet.append(soapResponse.jSessionId); maintainSession.set(soapResponse.maintainSessionFromPreviousCall); statusStringToSet.append("Got a response"); setStatusImage(true); } } else { if (!CancelWasPressed) { statusStringToSet.append("Did not get a response back from Service"); setStatusImage(false); } } CancelWasPressed = false; shell.getDisplay().asyncExec(new Runnable() { public void run() { final String text = responseStringToSet.toString(); final String prettyText = WSUtil.prettyPrint(text); responseText.setText(prettyText != null ? prettyText : text); statusText.setText(statusStringToSet.toString()); if (maintainSession.get()) { sessionIdLabel.setText("JSESSIONID: " + jSesionIdToSet); } shouldStopProgressBar.set(true); pb.setSelection(100); cancelButton.setEnabled(false); } }); return ""; } } /** * Increments the progress bar a little bit at a time until * a process is finished. It stops at 90 so that is isn't * reporting %100 when a task isn't finished. */ public class IncrementProgressBar implements Callable<String> { ProgressBar pb = null; Shell shell = null; AtomicBoolean shouldStopProgressBar = null; public IncrementProgressBar(Shell shell, ProgressBar pb, AtomicBoolean shouldStopProgressBar) { this.shell = shell; this.pb = pb; this.shouldStopProgressBar = shouldStopProgressBar; } @Override public String call() throws Exception { final int inc = 4; final long sleepTime = 250; shouldStopProgressBar.set(false); shell.getDisplay().syncExec(new Runnable() { public void run() { pb.setSelection(0); } }); while (!shouldStopProgressBar.get()) { shell.getDisplay().syncExec(new Runnable() { public void run() { if (pb.getSelection() >= 100) { pb.setSelection(0); } else { pb.setSelection(pb.getSelection() + inc); } // else { // shouldStopProgressBar.set(true); // } } }); Thread.sleep(sleepTime); } shouldStopProgressBar.set(false); return ""; } } /** * Increments the elapsed time counter until sending is done. * @author np3849 * */ public class IncrementTimeElapsed implements Callable<String> { AtomicBoolean isSending = null; Calendar now = Calendar.getInstance(); public IncrementTimeElapsed(AtomicBoolean isSending) { this.isSending = isSending; } @Override public String call() throws Exception { String timeString = ""; final long sleepTime = 1000; // update while we are trying to send while (isSending.get()) { timeString = setTimeElapsed(now); Thread.sleep(sleepTime); } return timeString; } } /** * Populates the elapsed time in the status bar. * @author np3849 * */ public class PopulateTimeElapsed implements Callable<String> { Future<String> timeElapsedFuture = null; PopulateTimeElapsed(Future<String> timeElapsedFuture) { this.timeElapsedFuture = timeElapsedFuture; } @Override public String call() throws Exception { log(" - " + timeElapsedFuture.get(), true); return ""; } } /** * Put text in the label at the bottom of the * screen. * @param t Text to display on the bottom label */ public void log(final String t) { shell.getDisplay().asyncExec(new Runnable() { public void run() { if (t == null) { return; } statusText.setText(t); } }); } public void log(final String t, final Exception e) { shell.getDisplay().asyncExec(new Runnable() { public void run() { statusText.setText(t); statusTextException = e; } }); } public void log(final String t, final boolean append) { shell.getDisplay().asyncExec(new Runnable() { public void run() { if (append) { statusText.setText(statusText.getText() + " " + t); } else { statusText.setText(t); } } }); } /** * Sets the timeElapsedLabel with time since 'started' * @param started */ public String setTimeElapsed(Calendar started) { Calendar c = Calendar.getInstance(); long start = started.getTimeInMillis(); long now = c.getTimeInMillis(); long elapsedMillis = now - start; int elapsedSeconds = (int) elapsedMillis / 1000; int elapsedMins = (int) elapsedMillis / (60 * 1000); int elapsedHours = (int) elapsedMillis / (60 * 60 * 1000); if (elapsedMins > 0) { elapsedSeconds -= (elapsedMins * 60); } // make it roll if (elapsedHours > 0) { elapsedMins -= (elapsedHours * 60); } // make it roll // format our String StringBuffer sb = new StringBuffer(); sb.append("Elapsed Time: "); String timeType = null; if (elapsedSeconds == 1) { timeType = " Second"; } else { timeType = " Seconds"; } if (elapsedHours > 0) { sb.append(elapsedHours); sb.append("."); if (elapsedHours == 1 && elapsedMins == 1 && elapsedSeconds == 1) { timeType = " Hour"; } else { timeType = " Hours"; } } if (elapsedMins > 0) { sb.append(elapsedMins); sb.append("."); if (elapsedMins == 1 && elapsedSeconds == 1) { timeType = " Minute"; } else { timeType = " Minutes"; } } sb.append(elapsedSeconds); sb.append(timeType); setTimeElapsedLabel(sb.toString()); return sb.toString(); } private void setTimeElapsedLabel(final String time) { shell.getDisplay().asyncExec(new Runnable() { public void run() { timeElapsedLabel.setText(time); } }); } /** * Gets all the text from the given file. * @param is InputStream to get the text from * @return the contents of the file */ public String getText(InputStream is) { StringBuilder sb = new StringBuilder(); String line = null; try { BufferedReader reader = new BufferedReader(new InputStreamReader(is, UTF8)); while ((line = reader.readLine()) != null) { sb.append(line); sb.append("\n"); } } catch (Exception e) { e.printStackTrace(); return null; } // removes last \n return sb.substring(0, sb.length() - 1); } /** * Gets all the text from the given file. * @param f File to get the text from * @return the contents of the file */ public String getText(File f) { StringBuilder sb = new StringBuilder(); String line = null; try { BufferedReader reader = new BufferedReader(new FileReader(f)); while ((line = reader.readLine()) != null) { sb.append(line); sb.append("\n"); } } catch (Exception e) { e.printStackTrace(); return null; } // removes last \n return sb.substring(0, sb.length() - 1); } /** * Get the history from the properties file. * @return list of saved endpoints */ public List<String> getEndpointHistory() { List<String> l = new ArrayList<String>(); String line = null; BufferedReader br = SimpleIO.openFileForInput(ENDPOINTS_FILE); try { if (br != null) { while ((line = br.readLine()) != null) { l.add(line); } } } catch (IOException e) { return null; } return l; } /** * Saves the endpoint in the combo box and our internal data structure. * * @param s endpoint String to be saved. */ public void saveEndpoint(String s) { if (!comboItems.contains(s)) { comboItems.add(s); } updateEndpointCombo(s); } /** * Updates the endpoint combo box with the internal data structure. * It also sets the recently entered text to still be displayed as the * selected text in the combo box (otherwise it would be blank). * * @param s String to populate the currently selected text */ public void updateEndpointCombo(String s) { String[] sArray = (String[]) comboItems.toArray(new String[comboItems.size()]); endpointCombo.setItems(sArray); endpointCombo.setText(s); } /** * Saves the endpoints in the internal data structure to a file, * one-per-line. */ public void saveEndpointsToFile() { PrintWriter pw = null; try { pw = SimpleIO.openFileForOutput(ENDPOINTS_FILE); } catch (Exception e) { e.printStackTrace(); return; } for (String s : comboItems) { pw.println(s); } SimpleIO.close(pw); } public void deleteTemporaryFiles() { File f = new File("."); File deleteFile = null; String[] files = f.list(new TempFileFilter()); for (int i = 0; i < files.length; i++) { deleteFile = new File(files[i]); if (deleteFile != null) { deleteFile.delete(); } deleteFile = null; } } /** * Opens the text given inside a browser view as XML. * @param text */ public void openInBrowserView(String text) { if (text == null || text.equals("")) { log("Didn't open browser view because there is nothing to display"); return; } // create web page file String fname = Calendar.getInstance().getTime().getTime() + ".tmp.xml"; PrintWriter pw = null; try { pw = SimpleIO.openFileForOutput(fname); } catch (Exception e1) { log("Caught exception: " + e1.getMessage()); return; } pw.println(text); SimpleIO.close(pw); BrowserDialog bd = new BrowserDialog(shell); File f = new File(fname); String path = f.getAbsolutePath(); bd.setURL(path); bd.open(); } public String getStrackTraceAsString(Throwable t) { if (t == null) { return null; } final Writer result = new StringWriter(); final PrintWriter printWriter = new PrintWriter(result); t.printStackTrace(printWriter); return result.toString(); } public Options getOptions() { Options o = new Options(); Properties options = GUIUtil.readPropertiesFile(OptionsDialog.OPTIONS_FILE); if (options != null) { o.ignoreHostCertificates = Boolean.valueOf((String) options.get(Options.IGNORE_HOST_CERTIFICATS_KEY)); // add any more options... } return o; } public void saveToFile(String text) { FileDialog fd = new FileDialog(shell, SWT.SAVE); fd.open(); if (fd.getFileName() != null && !fd.getFileName().equalsIgnoreCase("")) { String filename = fd.getFilterPath() + "\\" + fd.getFileName(); PrintWriter pw = null; try { pw = SimpleIO.openFileForOutput(filename); } catch (Exception e1) { log(e1.getMessage()); return; } pw.println(text); SimpleIO.close(pw); log("Saved file '" + fd.getFileName() + "'"); } } public void saveToFile(String text, String ext) { FileDialog fd = new FileDialog(shell, SWT.SAVE); fd.setFilterExtensions(new String[] { "*." + ext }); fd.open(); if (fd.getFileName() != null && !fd.getFileName().equalsIgnoreCase("")) { String filename = fd.getFilterPath() + "\\" + fd.getFileName(); PrintWriter pw = null; try { pw = SimpleIO.openFileForOutput(filename); } catch (Exception e1) { log(e1.getMessage()); return; } pw.println(text); SimpleIO.close(pw); log("Saved file '" + fd.getFileName() + "'"); } } /** * Cancel the current sending operation. * @param future */ public void cancelSoapSend(Future<SoapResponse> future) { future.cancel(true); } public void setCancelButton(final boolean enable) { shell.getDisplay().asyncExec(new Runnable() { public void run() { cancelButton.setEnabled(enable); } }); } /** * Add the normal cut,copy,paste operations. These go away once the menu is customized. * @param text the text widget that will be modified when the menu items are clicked * @param popupMenu the popup menu to add the items */ private void addTextOperationsToPopupMenu(final StyledText text, final Menu popupMenu) { // Cut final MenuItem cutTextPopUpMenu = new MenuItem(popupMenu, SWT.NONE); cutTextPopUpMenu.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { text.cut(); } }); cutTextPopUpMenu.setText("Cut"); // Copy final MenuItem copyTextPopUpMenu = new MenuItem(popupMenu, SWT.NONE); copyTextPopUpMenu.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { text.copy(); } }); copyTextPopUpMenu.setText("Copy"); // Paste final MenuItem pasteTextPopUpMenu = new MenuItem(popupMenu, SWT.NONE); pasteTextPopUpMenu.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { text.paste(); } }); pasteTextPopUpMenu.setText("Paste"); // Select All final MenuItem selectAllTextPopUpMenu = new MenuItem(popupMenu, SWT.NONE); selectAllTextPopUpMenu.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { text.selectAll(); } }); selectAllTextPopUpMenu.setText("Select All"); // Clear All final MenuItem clearAllTextPopUpMenu = new MenuItem(popupMenu, SWT.NONE); clearAllTextPopUpMenu.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { text.setText(StringUtils.EMPTY); } }); clearAllTextPopUpMenu.setText("Clear All"); } /** * Add a seperator to the menu. * @param popupMenu */ private void addSeperator(Menu popupMenu) { new MenuItem(popupMenu, SWT.SEPARATOR); } }