HttpSubmitController.java :  » XML-UI » SwingML » org » swingml » Java Open Source

Java Open Source » XML UI » SwingML 
SwingML » org » swingml » HttpSubmitController.java
package org.swingml;

import java.awt.*;
import java.io.*;
import java.net.*;

import javax.xml.parsers.*;

import org.apache.xml.serialize.*;
import org.swingml.action.*;
import org.swingml.component.*;
import org.swingml.errors.*;
import org.swingml.server.*;
import org.swingml.server.xml.*;
import org.swingml.system.*;
import org.swingml.task.*;
import org.swingml.task.monitoring.*;
import org.xml.sax.*;
import org.xml.sax.ContentHandler;
import org.xml.sax.helpers.*;


/**
 * @author CrossLogic
 */
public class HttpSubmitController {

    /**
     * Performs an HTTP GET to the specified address, giving feedback to the
     * system on its progress.
     */
    private static class HttpGetTask extends AbstractTask {

        private String address;

        public HttpGetTask (String anAddress, ITaskMonitor aTaskMonitor) {
            super(aTaskMonitor);
            setAddress(anAddress);
        }

        public Object execute () {
            String result = "";
            beginTask();
            try {
                progressMade(1, "Connecting to the Server");
                StringBuffer theValueBuffer = new StringBuffer();
                SwingMLLogger.getInstance().log(SwingMLLogger.INFO, "Connecting to: " + getAddress());
                URL theSource = URLHandler.handle(getAddress());
                URLConnection theConnection = theSource.openConnection();
                theConnection.setUseCaches(false);
                // set the cookie so we get the previous session, if we have one
                // SwingMLLogger.getInstance().log(SwingMLLogger.DEBUG, "GET
                // cookie session: " + getSessionId());
                if (getSessionId() != null) {
                    theConnection.setRequestProperty("Cookie", getSessionId());
                }
                progressMade(1, "Processing");
                BufferedReader theBufferedReader = new BufferedReader(new InputStreamReader(theConnection.getInputStream()));
                char[] readChars = new char[BUFFER_SIZE];
                int numCharsRead = theBufferedReader.read(readChars);
                while (numCharsRead > 0) {
                    theValueBuffer.append(new String(readChars, 0, numCharsRead));
                    numCharsRead = theBufferedReader.read(readChars);
                }
                theBufferedReader.close();
                progressMade(1, "Receiving Response");
                // Get the session id and store it
                setSessionId(theConnection);
                result = theValueBuffer.toString();
                progressMade(1, "Processing Response");
            } catch (MalformedURLException e) {
                SwingMLLogger.getInstance().log(ILogCapable.ERROR, e);
                result = getErrorResponse(ISwingMLError.ERROR_SERVER_COMMUNICATION, "Invalid server URL.");
            } catch (IOException e) {
                SwingMLLogger.getInstance().log(ILogCapable.ERROR, e);
                if (e instanceof ConnectException) {
                    result = getErrorResponse(ISwingMLError.ERROR_SERVER_COMMUNICATION, null);
                } else {
                    result = getErrorResponse(ISwingMLError.ERROR_INVALID_SERVER_RESPONSE, null);
                }
            }
            return result;
        }

        public Object execute (ITaskMonitor monitor) throws Exception {
            addTaskMonitor(monitor);
            return execute();
        }

        public String getAddress () {
            return address;
        }

        public String getName () {
            return "Connecting to Server";
        }

        public int getSteps () {
            return 5;
        }

        /**
         * Simply return the response xml we retreived in the execute.
         */
        public Object onComplete (Object result) {
            String xml = (String) result;
            SwingMLServerResponse finalResult = parseServerResponse(xml);
            progressMade(1, "Finished");
            endTask();
            return finalResult;
        }

        public void setAddress (String anAddress) {
            address = anAddress;
        }
    }
    /**
     * Performs an HTTP POST to the specified address (with the given form
     * parameters), giving feedback to the system on its progress.
     */
    private static class HttpPostTask extends AbstractTask {

        private String address;
        private String request;

        public HttpPostTask (String anAddress, String httpRequest, ITaskMonitor aTaskMonitor) {
            super(aTaskMonitor);
            setAddress(anAddress);
            setRequest(httpRequest);
        }

        public Object execute () {
            String result = "";
            beginTask();
            try {
                progressMade(1, "Connecting to the Server");
                SwingMLLogger.getInstance().log(SwingMLLogger.INFO, "Connecting to: " + getAddress());
                URL theUrl = URLHandler.handle(getAddress());
                URLConnection theUrlConnection = theUrl.openConnection();
                // set the cookie so we get the previous session
                // SwingMLLogger.getInstance().log(SwingMLLogger.DEBUG, "POST
                // cookie session: " + getSessionId());
                if (getSessionId() != null) {
                    theUrlConnection.setRequestProperty("Cookie", getSessionId());
                }
                theUrlConnection.setUseCaches(false);
                theUrlConnection.setDoOutput(true);

                progressMade(1, "Sending Data to the Server");
                ByteArrayOutputStream theByteStream = new ByteArrayOutputStream(BUFFER_SIZE);
                PrintWriter theOutput = new PrintWriter(theByteStream, true);
                if (getRequest() != null && getRequest().length() > 100) {
                    SwingMLLogger.getInstance().log(SwingMLLogger.INFO, "Adding parameters: " + getRequest().substring(0, 100) + "...");
                } else {
                    SwingMLLogger.getInstance().log(SwingMLLogger.INFO, "Adding parameters: " + getRequest());
                }
                theOutput.print(getRequest());
                theOutput.flush();
                theUrlConnection.setRequestProperty("Content-Length", theByteStream.size() + "");
                theUrlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                theByteStream.writeTo(theUrlConnection.getOutputStream());

                // Receive Http Response.
                progressMade(1, "Processing");
                BufferedReader theBufferedReader = new BufferedReader(new InputStreamReader(theUrlConnection.getInputStream()));
                StringBuffer theHttpResponse = new StringBuffer();
                char[] readChars = new char[BUFFER_SIZE];
                int numCharsRead = theBufferedReader.read(readChars);
                while (numCharsRead > 0) {
                    theHttpResponse.append(new String(readChars, 0, numCharsRead));
                    numCharsRead = theBufferedReader.read(readChars);
                }
                // Get the session id and store it
                setSessionId(theUrlConnection);

                progressMade(1, "Receiving Response");
                result = theHttpResponse.toString();
                theBufferedReader.close();
                theByteStream.close();
                theOutput.close();

                progressMade(1, "Processing Response");
            } catch (MalformedURLException e) {
                SwingMLLogger.getInstance().log(ILogCapable.ERROR, e);
                result = getErrorResponse(ISwingMLError.ERROR_SERVER_COMMUNICATION, "Invalid server URL.");
            } catch (IOException e) {
                SwingMLLogger.getInstance().log(ILogCapable.ERROR, e);
                if (e instanceof FileNotFoundException) {
                    result = getErrorResponse(ISwingMLError.ERROR_INVALID_SERVER_RESPONSE, null);
                } else {
                    result = getErrorResponse(ISwingMLError.ERROR_SERVER_COMMUNICATION, null);
                }
            }
            return result;
        }

        public Object execute (ITaskMonitor monitor) throws Exception {
            addTaskMonitor(monitor);
            return execute();
        }

        public String getAddress () {
            return address;
        }

        public String getName () {
            return "Connecting to Server";
        }

        public String getRequest () {
            return request;
        }

        /**
         * 6 steps - Connect, Send, Receive, Process, Done, OnComplete
         */
        public int getSteps () {
            return 5;
        }

        /**
         * Simply return the response xml we retreived in the execute.
         */
        public Object onComplete (Object result) {
            String xml = (String) result;
            SwingMLServerResponse finalResult = parseServerResponse(xml);
            progressMade(1, "Finished");
            endTask();
            return finalResult;
        }

        public void setAddress (String anAddress) {
            address = anAddress;
        }

        public void setRequest (String aRequest) {
            request = aRequest;
        }
    }

    private static URL codeBase;
    private static final int BUFFER_SIZE = 32000;
    private static String serverURL;
    private static String sessionId = null;

    /**
     * Uses the parent parameter as a starting point for building the parameters
     * to use during a submit() operation.
     * 
     * @param parent
     *            A reference to the Container to use as the root during the
     *            construction of the document's parameters.
     */
    public static String buildHttpRequest (Container aContainer) {
        StringBuffer theFormParameters = new StringBuffer();
        processFormParameters(aContainer, theFormParameters);
        if (theFormParameters.length() != 0) {
            theFormParameters.deleteCharAt(theFormParameters.length() - 1);
        }
        return theFormParameters.toString();
    }

    private static String createErrorTag (int type, String message) {
        return "<" + ISwingMLResponseConstants.ELEMENT_ERROR + " " + ISwingMLResponseConstants.ATTRIBUTE_ERROR_TYPE + "=\"" + type + "\">" + message
                + createTag(ISwingMLResponseConstants.ELEMENT_ERROR, true);
    }

    private static String createTag (String elementName) {
        return createTag(elementName, false);
    }

    private static String createTag (String elementName, boolean isEndTag) {
        return "<" + (isEndTag ? "/" : "") + elementName + ">";
    }

    public static URL getCodeBase () {
        return codeBase;
    }

    /**
     * Return an error panel saying that the server could not be connected to.
     * 
     * @return
     */
    public static String getConnectionErrorSpec () {
        return "<FRAME LAYOUT=\"BorderLayout\" NAME=\"ServerNotFoundWindow\" TEXT=\"Server Unavailable\" WIDTH=\"300\" HEIGHT=\"150\" >"
                + "<PANEL NAME=\"ServerUnavailablePanel\" LAYOUT=\"BorderLayout\" ORIENTATION=\"Center\">" + "<PANEL NAME=\"LabelPanel\" ORIENTATION=\"Center\">"
                + "<LABEL NAME=\"ErrorLabel\" TEXT=\"Unable to connect to the server. Application will now exit.\" />" + "</PANEL>"
                + "<PANEL NAME=\"OkButtonOuterPanel\" ORIENTATION=\"South\" LAYOUT=\"BorderLayout\">" + "<PANEL NAME=\"OkButtonPanel\" ORIENTATION=\"Center\" LAYOUT=\"FlowLayout\">"
                + "<BUTTON ENABLED=\"True\" NAME=\"okButton\" TEXT=\"OK\" ORIENTATION=\"Center\">" + "<LISTENER EVENT=\"ActionListener.actionPerformed\">"
                + "<EXTERNAL-ACTION COMPONENT=\"ServerNotFoundWindow\" EXTERNAL-CLASS=\"com.yell.common.swingmlclient.controller.DesktopEventHandler\">"
                + "<ACTION-PARAM NAME=\"EXIT\" VALUE=\"ServerNotFound\" />" + "<ACTION-PARAM NAME=\"EVENT-SOURCE\" VALUE=\"okButton\" />" + "</EXTERNAL-ACTION>" + "</LISTENER>" + "</BUTTON>"
                + "</PANEL>" + "</PANEL>" + "</PANEL>" + "</FRAME>";
    }

    private static String getErrorResponse (int errorType, String message) {
        String result = createTag(ISwingMLResponseConstants.ELEMENT_RESPONSE);
        result += createTag(ISwingMLResponseConstants.ELEMENT_HEAD);
        result += createTag(ISwingMLResponseConstants.ELEMENT_ERRORS);
        // find and add the system message
        int matchedType = ISwingMLError.ERROR_UNKNOWN;
        switch (errorType) {
            case ISwingMLError.ERROR_INVALID_SERVER_RESPONSE:
                matchedType = ISwingMLError.ERROR_INVALID_SERVER_RESPONSE;
                result += createErrorTag(ISwingMLError.ERROR_INVALID_SERVER_RESPONSE, "The server returned an invalid response.");
                break;
            case ISwingMLError.ERROR_NO_SERVER_RESPONSE:
                matchedType = ISwingMLError.ERROR_NO_SERVER_RESPONSE;
                result += createErrorTag(ISwingMLError.ERROR_NO_SERVER_RESPONSE, "The server did not return a response");
                break;
            case ISwingMLError.ERROR_SERVER_COMMUNICATION:
                matchedType = ISwingMLError.ERROR_SERVER_COMMUNICATION;
                result += createErrorTag(ISwingMLError.ERROR_SERVER_COMMUNICATION, "Unable to connect to the server.");
                break;
            default:
                result += createErrorTag(ISwingMLError.ERROR_UNKNOWN, "An unknown error occurred.");
        }
        // add the specific error message passed in
        if (message != null && message.length() > 0) {
            result += createErrorTag(matchedType, message);
        }
        result += createTag(ISwingMLResponseConstants.ELEMENT_ERRORS, true);
        result += createTag(ISwingMLResponseConstants.ELEMENT_HEAD, true);
        result += createTag(ISwingMLResponseConstants.ELEMENT_RESPONSE, true);
        return result;
    }

    public static String getInvalidTargetErrorSpec () {
        return "<FRAME LAYOUT=\"BorderLayout\" NAME=\"InvalidTargetWindow\" TEXT=\"Invalid Target URL\" WIDTH=\"375\" HEIGHT=\"150\" >"
                + "<PANEL NAME=\"InvalidTargetPanel\" LAYOUT=\"BorderLayout\" ORIENTATION=\"Center\">" + "<PANEL NAME=\"LabelPanel\" ORIENTATION=\"Center\">"
                + "<LABEL NAME=\"ErrorLabel\" WRAP-TEXT=\"True\" TEXT=\"Invalid component name was specified.  No server URL could be found.\" />" + "</PANEL>"
                + "<PANEL NAME=\"OkButtonOuterPanel\" ORIENTATION=\"South\" LAYOUT=\"BorderLayout\">" + "<PANEL NAME=\"OkButtonPanel\" ORIENTATION=\"Center\" LAYOUT=\"FlowLayout\">"
                + "<BUTTON ENABLED=\"True\" NAME=\"okButton\" TEXT=\"OK\" ORIENTATION=\"Center\">" + "<LISTENER EVENT=\"ActionListener.actionPerformed\">"
                + "<EXTERNAL-ACTION COMPONENT=\"InvalidTargetWindow\" EXTERNAL-CLASS=\"com.yell.common.swingmlclient.controller.DesktopEventHandler\">"
                + "<ACTION-PARAM NAME=\"EXIT\" VALUE=\"InvalidTarget\" />" + "<ACTION-PARAM NAME=\"EVENT-SOURCE\" VALUE=\"okButton\" />" + "</EXTERNAL-ACTION>" + "</LISTENER>" + "</BUTTON>"
                + "</PANEL>" + "</PANEL>" + "</PANEL>" + "</FRAME>";
    }

    /**
     * Gets the JSESSIONID that is being set if one exists.
     * 
     * @param httpConnection -
     *            The URLConnection
     * @return The JSESSIONID
     */
    protected static String getJSessionId (URLConnection httpConnection) {
        return httpConnection.getHeaderField("Set-Cookie");
    }

    public static String getServerURL () {
        return serverURL;
    }

    public static String getSessionId () {
        return sessionId;
    }

    /**
     * Performs the equivalent of an HTTP Get call to the given URL, but doesn't
     * show progress.
     */
    public static SwingMLServerResponse getSpec (String address) {
        return getSpec(address, null);
    }

    /**
     * Performs the equivalent of an HTTP Get call to the given URL, indicating
     * progress as it processes.
     */
    public static SwingMLServerResponse getSpec (String address, Container container) {
        return (SwingMLServerResponse) TaskExecutor.getInstance().runTask(new HttpGetTask(address, StatusBar.findStatusBarFor(container)));
    }

    /**
     * Parse the XML returned from the server into a SwingMLResponse object
     * 
     * @param xml
     * @return
     */
    private static SwingMLServerResponse parseServerResponse (String xml) {
        SwingMLServerResponse result = new NullSwingMLResponse();
        if (xml != null && xml.length() > 0) {
            try {
                ServerResponseFilter filter = new ServerResponseFilter();
                OutputFormat format = new OutputFormat(Method.XML, null, true);
                format.setOmitXMLDeclaration(true);
                format.setPreserveSpace(true);
                StringWriter writer = new StringWriter();
                ContentHandler xmlSerializer = new XMLSerializer(writer, format).asContentHandler();
                InputSource inputSource = new InputSource(new StringReader(xml));
                filter.setContentHandler(xmlSerializer);
                SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
                XMLReader inputReader = new ParserAdapter(parser.getParser());
                inputReader.setContentHandler(filter);
                inputReader.parse(inputSource);
                result = filter.getResponse();
                result.setSwingMLSpec(writer.toString());
            } catch (ParserConfigurationException e) {
                SwingMLLogger.getInstance().log(SwingMLLogger.ERROR, e);
            } catch (SAXException e) {
                SwingMLLogger.getInstance().log(SwingMLLogger.ERROR, e);
            } catch (FactoryConfigurationError e) {
                SwingMLLogger.getInstance().log(SwingMLLogger.ERROR, e);
            } catch (IOException e) {
                SwingMLLogger.getInstance().log(SwingMLLogger.ERROR, e);
            }
        }
        return result;
    }

    public static void processDocumentBase (String aSpecLocation) {
        int theLastIndex = aSpecLocation.lastIndexOf("/");
        String theDocumentBase = aSpecLocation.substring(0, theLastIndex + 1);
        setServerURL(theDocumentBase);
    }

    public static void processFormParameters (Container aContainer, StringBuffer aFormParameters) {
        try {
            Component theComponent = null;
            XMLTranslatable theXMLTranslatableComponent = null;
            // process the container first
            if (aContainer instanceof XMLTranslatable) {
                theXMLTranslatableComponent = (XMLTranslatable) aContainer;
                aFormParameters.append(aContainer.getName() + "=");
                aFormParameters.append(URLEncoder.encode(theXMLTranslatableComponent.getXMLValue() + "", "UTF-8") + "&");
            }
            Component[] aComponents = aContainer.getComponents();
            for (int i = 0; i < aComponents.length; i++) {
                theComponent = aComponents[i];
                processFormParameters((Container) theComponent, aFormParameters);
            }
        } catch (UnsupportedEncodingException e) {
            SwingMLLogger.getInstance().log(e);
        }
    }

    public static void setCodeBase (URL base) {
        HttpSubmitController.codeBase = base;
    }

    private static void setServerURL (String someLocation) {
        HttpSubmitController.serverURL = someLocation;
    }

    public static void setSessionId (URLConnection aConnection) {
        String sid = getJSessionId(aConnection);
        // SwingMLLogger.getInstance().log(SwingMLLogger.DEBUG, "Set session id:
        // " + sid);
        if (sid != null) {
            sessionId = sid;
        }
    }

    public static SwingMLServerResponse submit (String address, Container submitter, String parameters, boolean showProgress) {
        SwingMLServerResponse result = null;
        // Create the HTTP request.
        String theHttpRequest = buildHttpRequest(submitter);
        // Append parameters, if necessary
        StringBuffer sb = new StringBuffer(theHttpRequest);
        if (parameters != null) {
            sb.append("&");
            sb.append(parameters);
            theHttpRequest = sb.toString();
        }
        if (showProgress) {
            result = submit(address, theHttpRequest, submitter);
        } else {
            result = submit(address, theHttpRequest, null);
        }
        return result;
    }

    /**
     * Performs the equivalent of an HTTP POST to the given address, with the
     * given parameters.
     * 
     * @param address
     * @param request
     * @param container
     * @return
     */
    public static SwingMLServerResponse submit (String address, String request, Container container) {
        ITaskMonitor taskMonitor = StatusBar.findStatusBarFor(container);
        HttpPostTask postTask = new HttpPostTask(address, request, taskMonitor);
        return (SwingMLServerResponse) TaskExecutor.getInstance().runTask(postTask);
    }

    public static SwingMLServerResponse submitRemoteAction (String anAddress, RemoteAction action, Container aContainer) {
        String httpRequest = action.createParamString();
        return submit(anAddress, httpRequest, aContainer);
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.