Java tutorial
/* * SoapUI, copyright (C) 2004-2011 smartbear.com * * SoapUI is free software; you can redistribute it and/or modify it under the * terms of version 2.1 of the GNU Lesser General Public License as published by * the Free Software Foundation. * * SoapUI 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 Lesser General Public License for more details at gnu.org. */ package com.eviware.soapui.support.components; import com.eviware.soapui.SoapUI; import com.eviware.soapui.impl.rest.panels.request.views.html.HttpHtmlResponseView; import com.eviware.soapui.impl.rest.support.RestUtils; import com.eviware.soapui.impl.wsdl.submit.transports.http.support.methods.ExtendedGetMethod; import com.eviware.soapui.impl.wsdl.support.http.HttpClientSupport; import com.eviware.soapui.impl.wsdl.support.http.ProxyUtils; import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase; import com.eviware.soapui.impl.wsdl.teststeps.HttpTestRequest; import com.eviware.soapui.impl.wsdl.teststeps.HttpTestRequestStep; import com.eviware.soapui.impl.wsdl.teststeps.registry.HttpRequestStepFactory; import com.eviware.soapui.model.propertyexpansion.PropertyExpander; import com.eviware.soapui.model.propertyexpansion.PropertyExpansionContext; import com.eviware.soapui.model.settings.Settings; import com.eviware.soapui.settings.ProxySettings; import com.eviware.soapui.settings.WebRecordingSettings; import com.eviware.soapui.support.StringUtils; import com.eviware.soapui.support.Tools; import com.eviware.soapui.support.UISupport; import com.eviware.soapui.support.types.StringList; import com.eviware.soapui.support.types.StringToStringsMap; import com.eviware.soapui.support.xml.XmlUtils; import com.teamdev.jxbrowser.*; import com.teamdev.jxbrowser.cookie.HttpCookieStorage; import com.teamdev.jxbrowser.events.*; import com.teamdev.jxbrowser.gecko.xpcom.XPCOM; import com.teamdev.jxbrowser.gecko.xpcom.XPCOMManager; import com.teamdev.jxbrowser.mozilla.MozillaBrowser; import com.teamdev.jxbrowser.mozilla.MozillaCookieStorage; import com.teamdev.jxbrowser.prompt.DefaultPromptService; import com.teamdev.jxbrowser.proxy.*; import com.teamdev.jxbrowser.security.HttpSecurityAction; import com.teamdev.jxbrowser.security.HttpSecurityHandler; import com.teamdev.jxbrowser.security.SecurityProblem; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.client.methods.HttpGet; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.routing.HttpRoutePlanner; import org.mozilla.interfaces.*; import org.mozilla.xpcom.Mozilla; import org.mozilla.xpcom.XPCOMException; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.lang.reflect.InvocationTargetException; import java.net.MalformedURLException; import java.net.URL; import java.util.*; import java.util.List; public class BrowserComponent implements nsIWebProgressListener, nsIWeakReference, StatusListener { private static final String CONTENT_TYPE_FORM_URLENCODED = "application/x-www-form-urlencoded"; private MozillaBrowser browser; private JPanel panel = new JPanel(new BorderLayout()); private JPanel statusBar; private JLabel statusLabel; private String errorPage; private boolean showingErrorPage; public String url; private Boolean possibleError = false; @SuppressWarnings("unused") private boolean disposed; // private static boolean disabled; private NavigationListener internalNavigationListener; private HttpHtmlResponseView httpHtmlResponseView; private static SoapUINewWindowManager newWindowManager; private static Map<nsIDOMWindow, BrowserComponent> browserMap = new HashMap<nsIDOMWindow, BrowserComponent>(); private static Map<BrowserComponent, Map<String, RecordedRequest>> browserRecordingMap = new HashMap<BrowserComponent, Map<String, RecordedRequest>>(); private static Object recordingHttpListener; private final boolean addStatusBar; public BrowserComponent(boolean addToolbar, boolean addStatusBar) { this.addStatusBar = addStatusBar; } public Component getComponent() { if (SoapUI.isJXBrowserDisabled()) { JEditorPane jxbrowserDisabledPanel = new JEditorPane(); jxbrowserDisabledPanel.setText("Browser Component disabled or not available on this platform"); panel.add(jxbrowserDisabledPanel); } else { if (browser == null) { if (addStatusBar) { statusBar = new JPanel(new BorderLayout()); statusLabel = new JLabel(); UISupport.setFixedSize(statusBar, new Dimension(20, 20)); statusBar.add(statusLabel, BorderLayout.WEST); panel.add(statusBar, BorderLayout.SOUTH); } if (!initBrowser()) return panel; configureBrowser(); browser.navigate("about:blank"); } } return panel; } @SuppressWarnings("unused") private Component buildToolbar() { JXToolBar toolbar = UISupport.createToolbar(); toolbar.addFixed(UISupport.createToolbarButton(new BackAction())); toolbar.addRelatedGap(); toolbar.addFixed(UISupport.createToolbarButton(new ForwardAction())); toolbar.addGlue(); return toolbar; } public void setRecordingHttpHtmlResponseView(HttpHtmlResponseView httpHtmlResponseView) { this.httpHtmlResponseView = httpHtmlResponseView; if (httpHtmlResponseView != null) { if (!browserRecordingMap.containsKey(BrowserComponent.this)) { browserRecordingMap.put(BrowserComponent.this, new HashMap<String, RecordedRequest>()); } // clear cookies when we start recording HttpCookieStorage cookies = MozillaCookieStorage.getInstance(BrowserType.Mozilla); cookies.deleteCookie(cookies.getCookies()); } else { browserRecordingMap.remove(BrowserComponent.this); } } private final class InternalNavigationAdapter extends NavigationAdapter { @Override public void navigationFinished(NavigationFinishedEvent evt) { if (evt.getUrl().equals(SoapUI.PUSH_PAGE_URL) && !(evt.getStatusCode().equals(NavigationStatusCode.OK))) { browser.navigate(SoapUI.PUSH_PAGE_ERROR_URL); } } } private final class InternalHttpSecurityHandler implements HttpSecurityHandler { @Override public HttpSecurityAction onSecurityProblem(Set<SecurityProblem> arg0) { return HttpSecurityAction.CONTINUE; } } private static final class RecordingHttpListener implements Runnable { public void run() { recordingHttpListener = this; final Mozilla mozilla = Mozilla.getInstance(); nsIServiceManager serviceManager = mozilla.getServiceManager(); nsIObserverService observerService = (nsIObserverService) serviceManager.getServiceByContractID( "@mozilla.org/observer-service;1", nsIObserverService.NS_IOBSERVERSERVICE_IID); final nsIBinaryInputStream in = XPCOMManager.getInstance() .newComponent("@mozilla.org/binaryinputstream;1", nsIBinaryInputStream.class); nsIObserver httpObserver = new nsIObserver() { public void observe(nsISupports subject, String sTopic, String sData) { try { if (EVENT_HTTP_ON_MODIFY_REQUEST.equals(sTopic)) { nsIHttpChannel httpChannel = (nsIHttpChannel) subject .queryInterface(nsIHttpChannel.NS_IHTTPCHANNEL_IID); if (httpChannel.getNotificationCallbacks() == null) return; nsIInterfaceRequestor interfaceRequestor = (nsIInterfaceRequestor) httpChannel .getNotificationCallbacks() .queryInterface(nsIInterfaceRequestor.NS_IINTERFACEREQUESTOR_IID); nsIDOMWindow window = (nsIDOMWindow) interfaceRequestor .getInterface(nsIDOMWindow.NS_IDOMWINDOW_IID); BrowserComponent browserComponent = browserMap.get(window); if (browserComponent != null && browserRecordingMap.containsKey(browserComponent)) { RecordedRequest rr = new RecordedRequest(dumpUri(httpChannel.getURI()), httpChannel.getRequestMethod()); nsIUploadChannel upload = (nsIUploadChannel) httpChannel .queryInterface(nsIUploadChannel.NS_IUPLOADCHANNEL_IID); byte[] requestData = null; if (upload != null) { nsIInputStream uploadStream = upload.getUploadStream(); if (uploadStream != null && uploadStream.available() > 0) { nsISeekableStream seekable = (nsISeekableStream) uploadStream .queryInterface(nsISeekableStream.NS_ISEEKABLESTREAM_IID); long pos = seekable.tell(); long available = uploadStream.available(); if (available > 0) { try { synchronized (mozilla) { in.setInputStream(uploadStream); requestData = in.readByteArray(available); String requestBody = getRequestBody(requestData); if (requestBody != null && requestBody.length() > 0) { rr.setContent(requestBody); String contentType = getContentType(requestData); if (StringUtils.hasContent(contentType)) rr.setContentType(contentType); } } } catch (Throwable e) { e.printStackTrace(); } finally { seekable.seek(nsISeekableStream.NS_SEEK_SET, pos); } } } } final StringToStringsMap headersMap = new StringToStringsMap(); httpChannel.visitRequestHeaders(new nsIHttpHeaderVisitor() { public void visitHeader(String header, String value) { if (!isHeaderExcluded(header)) { headersMap.put(header, value); } } public nsISupports queryInterface(String sIID) { return Mozilla.queryInterface(this, sIID); } }); rr.setHeaders(headersMap); browserRecordingMap.get(browserComponent).put(rr.getUrl(), rr); } } else { System.out.println("HTTPObserver: Unknown event '" + sTopic + "'"); } } catch (Throwable e) { // ignore errors related to the querying of unsupported // interfaces if (e.getMessage().indexOf("0x80004002") == -1) SoapUI.logError(e); } } public nsISupports queryInterface(String sIID) { return Mozilla.queryInterface(this, sIID); } }; boolean blnObserverIsWeakReference = false; observerService.addObserver(httpObserver, EVENT_HTTP_ON_MODIFY_REQUEST, blnObserverIsWeakReference); } } public static boolean isHeaderExcluded(String header) { String excluded = SoapUI.getSettings().getString(WebRecordingSettings.EXCLUDED_HEADERS, null); List<String> result = new ArrayList<String>(); if (excluded != null && excluded.trim().length() > 0) { try { StringList names = StringList.fromXml(excluded); for (String name : names) { result.add(name); } } catch (Exception e) { SoapUI.logError(e); } } return result.contains(header); } private static String getContentType(byte[] requestData) { String request = new String(requestData); int ix = request.indexOf("Content-Type"); if (ix >= 0 && ix < request.length() - 14) { String contentType = request.substring(ix + 14); contentType = contentType.substring(0, contentType.indexOf("\n") - 1); return contentType.trim(); } else return null; } private static String getRequestBody(byte[] requestData) { String request = new String(requestData); int ix = request.indexOf("\r\n\r\n"); return ix == -1 ? "" : request.substring(ix + 4); } private static final class SoapUINewWindowManager implements NewWindowManager { public NewWindowContainer evaluateWindow(final NewWindowParams params) { return new NewWindowContainer() { public void insertBrowser(final Browser browser) { browser.addNavigationListener(new NavigationListener() { public void navigationStarted(final NavigationEvent arg0) { // this is the only event we wanted arg0.getBrowser().removeNavigationListener(this); // since there is no way to detect the source browser for // the new window we just assume it is the recording one. BrowserComponent browserComponent = null; if (params.getParent() instanceof MozillaBrowser) { browserComponent = browserMap.get(((MozillaBrowser) params.getParent()).getPeer() .getNsIWebBrowser().getContentDOMWindow()); if (browserRecordingMap.containsKey(browserComponent)) { browserComponent.replaceBrowser(arg0.getBrowser()); } else browserComponent = null; } if (browserComponent == null) { Tools.openURL(arg0.getUrl()); } } public void navigationFinished(NavigationFinishedEvent arg0) { } }); } }; } } private final class InternalBrowserNavigationListener implements NavigationListener { public void navigationStarted(NavigationEvent arg0) { } public void navigationFinished(NavigationFinishedEvent arg0) { if (browserRecordingMap.containsKey(BrowserComponent.this)) { Map<String, RecordedRequest> map = browserRecordingMap.get(BrowserComponent.this); RecordedRequest recordedRequest = map.get(arg0.getUrl()); if (recordedRequest != null) { if (httpHtmlResponseView != null && httpHtmlResponseView.isRecordHttpTrafic()) { HttpTestRequest httpTestRequest = (HttpTestRequest) (httpHtmlResponseView.getDocument() .getRequest()); WsdlTestCase testCase = httpTestRequest.getTestStep().getTestCase(); int count = testCase.getTestStepList().size(); String url2 = recordedRequest.getUrl(); try { url2 = new URL(recordedRequest.getUrl()).getPath(); } catch (MalformedURLException e) { } HttpTestRequestStep newHttpStep = (HttpTestRequestStep) testCase.addTestStep( HttpRequestStepFactory.HTTPREQUEST_TYPE, "Http Test Step " + ++count + " [" + url2 + "]", recordedRequest.getUrl(), recordedRequest.getMethod()); newHttpStep.getTestRequest().setRequestHeaders(recordedRequest.getHeaders()); if (recordedRequest.getContent() != null) { newHttpStep.getTestRequest().setMediaType(recordedRequest.getContentType()); if (newHttpStep.getTestRequest().getMediaType().equals(CONTENT_TYPE_FORM_URLENCODED)) { newHttpStep.getTestRequest().setPostQueryString(true); newHttpStep.getTestRequest().setMediaType(CONTENT_TYPE_FORM_URLENCODED); RestUtils.extractParamsFromQueryString(newHttpStep.getTestRequest().getParams(), recordedRequest.getContent()); } else { newHttpStep.getTestRequest().setRequestContent(recordedRequest.getContent()); } } } } } // TODO ask Ole why was this removing necessary // browserRecordingMap.remove( BrowserComponent.this ); } } private class BackAction extends AbstractAction { public BackAction() { putValue(SMALL_ICON, UISupport.createImageIcon("/arrow_left.png")); putValue(Action.SHORT_DESCRIPTION, "Navigate to previous selection"); } public void actionPerformed(ActionEvent e) { if (!browser.canGoBack()) Toolkit.getDefaultToolkit().beep(); else browser.goBack(); } } private class ForwardAction extends AbstractAction { public ForwardAction() { putValue(SMALL_ICON, UISupport.createImageIcon("/arrow_right.png")); putValue(Action.SHORT_DESCRIPTION, "Navigate to next selection"); } public void actionPerformed(ActionEvent e) { if (!browser.canGoForward()) Toolkit.getDefaultToolkit().beep(); else browser.goForward(); } } public synchronized boolean initBrowser() { if (browser != null || SoapUI.isJXBrowserDisabled()) return false; try { browser = (MozillaBrowser) BrowserFactory.createBrowser(BrowserType.Mozilla); browserMap.put(browser.getPeer().getNsIWebBrowser().getContentDOMWindow(), this); initNewWindowManager(browser, true); internalHttpSecurityHandler = new InternalHttpSecurityHandler(); browser.setHttpSecurityHandler(internalHttpSecurityHandler); internalNavigationListener = new InternalBrowserNavigationListener(); browser.addNavigationListener(internalNavigationListener); browser.addStatusListener(this); internalNavigationAdapter = new InternalNavigationAdapter(); browser.addNavigationListener(internalNavigationAdapter); panel.add(browser.getComponent(), BorderLayout.CENTER); return true; } catch (Throwable t) { SoapUI.logError(t); return false; } } public static void initNewWindowManager(Browser browser, boolean forRecording) { if (newWindowManager == null) { newWindowManager = new SoapUINewWindowManager(); browser.getServices().setNewWindowManager(newWindowManager); browser.getServices().setPromptService(new DefaultPromptService()); } if (forRecording && recordingHttpListener == null) registerHttpListener(); } protected void replaceBrowser(Browser browser2) { // remove old browserMap.remove(browser.getPeer().getNsIWebBrowser().getContentDOMWindow()); browser.stop(); browser.removeNavigationListener(internalNavigationListener); browser.removeStatusListener(this); panel.remove(browser.getComponent()); browser.dispose(); // replace browser = (MozillaBrowser) browser2; browserMap.put(browser.getPeer().getNsIWebBrowser().getContentDOMWindow(), this); browser.addNavigationListener(internalNavigationListener); browser.addStatusListener(this); panel.add(browser.getComponent(), BorderLayout.CENTER); } // public static boolean isRecording() // { // return httpHtmlResponseView != null && // httpHtmlResponseView.isRecordHttpTrafic(); // } public void release() { if (browser != null) { disposed = true; cleanup(); } possibleError = false; } private synchronized void cleanup() { if (browser != null) { browserMap.remove(browser.getPeer().getNsIWebBrowser().getContentDOMWindow()); browserRecordingMap.remove(this); httpHtmlResponseView = null; browser.stop(); browser.dispose(); browser.removeNavigationListener(internalNavigationListener); browser.removeNavigationListener(internalNavigationAdapter); browser.setHttpSecurityHandler(null); browser.removeStatusListener(this); panel.removeAll(); browser = null; } } private void configureBrowser() { if (browser != null) { Configurable contentSettings = browser.getConfigurable(); if (SoapUI.isJXBrowserPluginsDisabled()) { contentSettings.disableFeature(Feature.PLUGINS); } else { contentSettings.enableFeature(Feature.PLUGINS); } } } public void setContent(String contentAsString, String contextUri) { if (SoapUI.isJXBrowserDisabled()) return; if (browser == null) { if (!initBrowser()) return; } configureBrowser(); try { // browser.navigate( contextUri ); browser.setContent(contentAsString, contextUri); pcs.firePropertyChange("content", null, null); } catch (Throwable e) { e.printStackTrace(); } } public void setContent(String content) { if (SoapUI.isJXBrowserDisabled()) return; if (browser == null) { if (!initBrowser()) return; } configureBrowser(); browser.setContent(content); pcs.firePropertyChange("content", null, null); } public void navigate(String url, String errorPage) { navigate(url, null, errorPage); } public String getContent() { return browser == null ? null : XmlUtils.serialize(browser.getDocument()); } public String getUrl() { return url; } public void setUrl(String url) throws InterruptedException, InvocationTargetException { navigate(url, null); } public nsISupports queryInterface(String uuid) { return Mozilla.queryInterface(this, uuid); } public nsISupports queryReferent(String uuid) { return Mozilla.queryInterface(this, uuid); } public void onLocationChange(nsIWebProgress arg0, nsIRequest arg1, nsIURI arg2) { if (getUrl() != null && !getUrl().equals("about:blank")) { if (!possibleError) possibleError = true; else { if (!showingErrorPage) { showErrorPage(); } } } } public void onProgressChange(nsIWebProgress arg0, nsIRequest arg1, int arg2, int arg3, int arg4, int arg5) { } public void onSecurityChange(nsIWebProgress arg0, nsIRequest arg1, long arg2) { } public void onStateChange(nsIWebProgress arg0, nsIRequest request, long arg2, long arg3) { try { if (getUrl() != null && !getUrl().equals("about:blank")) { nsIHttpChannel ch = null; ch = (nsIHttpChannel) request.queryInterface(nsIHttpChannel.NS_IHTTPCHANNEL_IID); if (ch != null) { possibleError = false; showingErrorPage = false; } } } catch (XPCOMException e) { if (possibleError && !showingErrorPage) showErrorPage(); } } private void showErrorPage() { if (errorPage != null && !errorPage.equals(getUrl())) { try { showingErrorPage = true; setUrl(errorPage); } catch (Throwable e) { e.printStackTrace(); } } } public String getErrorPage() { return errorPage; } public void setErrorPage(String errorPage) { this.errorPage = errorPage; } public void onStatusChange(nsIWebProgress arg0, nsIRequest arg1, long arg2, String arg3) { try { if (getUrl() != null && !getUrl().equals("about:blank")) { nsIHttpChannel ch = null; ch = (nsIHttpChannel) arg1.queryInterface(nsIHttpChannel.NS_IHTTPCHANNEL_IID); if (ch != null) { possibleError = false; showingErrorPage = false; } } } catch (XPCOMException e) { if (possibleError && !showingErrorPage) showErrorPage(); } } public void statusChanged(StatusChangedEvent event) { if (statusLabel != null) { statusLabel.setText(event.getStatusText()); } } public boolean isBrowserInitialised() { return browser != null; } /** * Setups proxy configuration */ private static boolean proxyAuthenticationInitialized = false; public static void updateJXBrowserProxy() { ProxyConfig proxyConf = BrowserServices.getInstance().getProxyConfig(); if (proxyConf == null) return; try { proxyConf.setAutoDetectForNetwork(false); if (!proxyAuthenticationInitialized) { proxyConf.setAuthenticationHandler(ServerType.HTTP, new AuthenticationHandler() { @Override public ProxyServerLogin authenticationRequired(ServerType arg0) { Settings settings = SoapUI.getSettings(); PropertyExpansionContext context = null; String proxyUsername = PropertyExpander.expandProperties(context, settings.getString(ProxySettings.USERNAME, null)); String proxyPassword = PropertyExpander.expandProperties(context, settings.getString(ProxySettings.PASSWORD, null)); return new ProxyServerLogin(proxyUsername, proxyPassword); } }); proxyAuthenticationInitialized = true; } if (ProxyUtils.isProxyEnabled()) { if (ProxyUtils.isAutoProxy()) { HttpRoutePlanner routePlanner = HttpClientSupport.getHttpClient().getRoutePlanner(); HttpRoute httpRoute = routePlanner.determineRoute(new HttpHost("soapui.org"), new HttpGet("http://soapui.org"), null); HttpHost proxyHost = httpRoute.getProxyHost(); if (proxyHost != null) { proxyConf.setProxy(ServerType.HTTP, new ProxyServer(proxyHost.getHostName(), proxyHost.getPort())); } else { proxyConf.setDirectConnection(); } } else { Settings settings = SoapUI.getSettings(); PropertyExpansionContext context = null; // check system properties first String proxyHost = System.getProperty("http.proxyHost"); String proxyPort = System.getProperty("http.proxyPort"); if (proxyHost == null) proxyHost = PropertyExpander.expandProperties(context, settings.getString(ProxySettings.HOST, "")); if (proxyPort == null) proxyPort = PropertyExpander.expandProperties(context, settings.getString(ProxySettings.PORT, "")); proxyConf.setProxy(ServerType.HTTP, new ProxyServer(proxyHost, Integer.parseInt(proxyPort))); // check excludes proxyConf.setExceptions(PropertyExpander.expandProperties(context, settings.getString(ProxySettings.EXCLUDES, ""))); } } else { proxyConf.setDirectConnection(); } } catch (Exception e) { //ignore } } private PropertyChangeSupport pcs = new PropertyChangeSupport(this); public void addPropertyChangeListener(PropertyChangeListener pcl) { pcs.addPropertyChangeListener(pcl); } public void rempvePropertyChangeListener(PropertyChangeListener pcl) { pcs.removePropertyChangeListener(pcl); } /** * Called after a HTTP response from the server is received. * * @see http://developer.mozilla.org/en/Observer_Notifications */ public static final String EVENT_HTTP_ON_MODIFY_REQUEST = "http-on-modify-request"; private InternalHttpSecurityHandler internalHttpSecurityHandler; private InternalNavigationAdapter internalNavigationAdapter; public static void registerHttpListener() { XPCOM.invokeLater(new RecordingHttpListener()); } /** * Converts an object implementing the nsIURI interface into a human readable * URI. * * @param uri nsIURI object to convert * @return String URI result string */ public static String dumpUri(nsIURI uri) { if (uri == null) { return ""; } return ((uri.getUsername() == null || "".equals(uri.getUsername())) ? "" : uri.getUsername() + ":" + uri.getUserPass()) + uri.getScheme() + "://" + uri.getHost() + ((uri.getPort() == -1) ? "" : ":" + uri.getPort()) + uri.getPath(); } private static class RecordedRequest { private String url; private String contentType; private StringToStringsMap headers; private String method; private String content; public RecordedRequest(String url, String method) { this.url = url; this.method = method; } public void setContentType(String contentType) { this.contentType = contentType; } public void setHeaders(StringToStringsMap headersMap) { headers = headersMap; } public void setContent(String requestBody) { content = requestBody; } public String getUrl() { return url; } public String getContentType() { return contentType; } public StringToStringsMap getHeaders() { return headers; } public String getMethod() { return method; } public String getContent() { return content; } } public void navigate(String url, String postData, String errorPage) { if (SoapUI.isJXBrowserDisabled()) return; if (errorPage != null) setErrorPage(errorPage); this.url = url; if (browser == null) { if (!initBrowser()) return; } configureBrowser(); updateJXBrowserProxy(); if (postData != null && postData.length() > 0) { browser.navigate(url, postData); } else { browser.navigate(url); } if (showingErrorPage) showingErrorPage = false; } }