com.gdevelop.gwt.syncrpc.RemoteServiceSyncProxy.java Source code

Java tutorial

Introduction

Here is the source code for com.gdevelop.gwt.syncrpc.RemoteServiceSyncProxy.java

Source

/*
 * Copyright www.gdevelop.com.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.gdevelop.gwt.syncrpc;

import com.google.gwt.user.client.rpc.InvocationException;
import com.google.gwt.user.client.rpc.RpcRequestBuilder;
import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.client.rpc.SerializationStreamFactory;
import com.google.gwt.user.client.rpc.StatusCodeException;
import com.google.gwt.user.client.rpc.impl.RequestCallbackAdapter;
import com.google.gwt.user.server.rpc.SerializationPolicy;
import com.google.gwt.user.server.rpc.SerializationPolicyLoader;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;

import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.CookieStore;
import java.net.HttpCookie;
import java.net.HttpURLConnection;
import java.net.URL;

import org.apache.commons.io.IOUtils;

/**
 * Base on {@link com.google.gwt.user.client.rpc.impl.RemoteServiceProxy}
 */
public class RemoteServiceSyncProxy implements SerializationStreamFactory {
    public static final boolean DUMP_PAYLOAD = Boolean.getBoolean("gwt.rpc.dumpPayload");

    public static class DummySerializationPolicy extends SerializationPolicy {
        public boolean shouldDeserializeFields(Class<?> clazz) {
            return clazz != null;
        }

        public boolean shouldSerializeFields(Class<?> clazz) {
            return clazz != null;
        }

        public void validateDeserialize(Class<?> clazz) throws SerializationException {
        }

        public void validateSerialize(Class<?> clazz) throws SerializationException {
        }
    }

    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(RemoteServiceSyncProxy.class);

    private String moduleBaseURL;
    private String remoteServiceURL;
    private String serializationPolicyName;
    private SerializationPolicy serializationPolicy;
    private CookieManager cookieManager;

    public RemoteServiceSyncProxy(String moduleBaseURL, String remoteServiceRelativePath,
            String serializationPolicyName, CookieManager cookieManager) {
        this.moduleBaseURL = moduleBaseURL;
        this.remoteServiceURL = moduleBaseURL + remoteServiceRelativePath;
        this.serializationPolicyName = serializationPolicyName;
        this.cookieManager = cookieManager;

        if (serializationPolicyName == null) {
            serializationPolicy = new DummySerializationPolicy();
        } else {
            String policyFileName = SerializationPolicyLoader
                    .getSerializationPolicyFileName(serializationPolicyName);
            InputStream is = getClass().getResourceAsStream("/" + policyFileName);
            try {
                if (is == null) {
                    // Try to get from cache
                    String text = RpcPolicyFinder.getCachedPolicyFile(moduleBaseURL + policyFileName);
                    if (text != null) {
                        is = new ByteArrayInputStream(text.getBytes("UTF8"));
                    }
                }
                serializationPolicy = SerializationPolicyLoader.loadFromStream(is, null);
            } catch (Exception e) {
                throw new InvocationException("Error while loading serialization policy " + serializationPolicyName,
                        e);
            } finally {
                if (is != null) {
                    try {
                        is.close();
                    } catch (IOException e) {
                        // Ignore this error
                    }
                }
            }
        }
    }

    public SyncClientSerializationStreamReader createStreamReader(String encoded) throws SerializationException {
        SyncClientSerializationStreamReader reader = new SyncClientSerializationStreamReader(serializationPolicy);
        reader.prepareToRead(encoded);
        return reader;
    }

    public SyncClientSerializationStreamWriter createStreamWriter() {
        SyncClientSerializationStreamWriter streamWriter = new SyncClientSerializationStreamWriter(null,
                moduleBaseURL, serializationPolicyName, serializationPolicy);
        streamWriter.prepareToWrite();

        return streamWriter;
    }

    public Object doInvoke(RequestCallbackAdapter.ResponseReader responseReader, String requestData)
            throws Throwable {
        HttpURLConnection connection = null;
        InputStream is = null;
        int statusCode;

        if (DUMP_PAYLOAD) {
            log.debug("Send request to {}", remoteServiceURL);
            log.debug("Request payload: {}", requestData);
        }

        // Send request
        CookieHandler oldCookieHandler = CookieHandler.getDefault();
        try {
            CookieHandler.setDefault(cookieManager);

            URL url = new URL(remoteServiceURL);
            connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.setDoOutput(true);
            connection.setRequestMethod("POST");
            connection.setRequestProperty(RpcRequestBuilder.STRONG_NAME_HEADER, serializationPolicyName);
            connection.setRequestProperty(RpcRequestBuilder.MODULE_BASE_HEADER, moduleBaseURL);
            connection.setRequestProperty("Content-Type", "text/x-gwt-rpc; charset=utf-8");
            connection.setRequestProperty("Content-Length", "" + requestData.getBytes("UTF-8").length);

            CookieStore store = cookieManager.getCookieStore();
            String cookiesStr = "";

            for (HttpCookie cookie : store.getCookies()) {
                if (!"".equals(cookiesStr))
                    cookiesStr += "; ";
                cookiesStr += cookie.getName() + "=" + cookie.getValue();
            }

            connection.setRequestProperty("Cookie", cookiesStr);

            OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
            writer.write(requestData);
            writer.flush();
            writer.close();
        } catch (IOException e) {
            throw new InvocationException("IOException while sending RPC request", e);
        } finally {
            CookieHandler.setDefault(oldCookieHandler);
        }

        // Receive and process response
        try {

            is = connection.getInputStream();
            statusCode = connection.getResponseCode();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            while ((len = is.read(buffer)) > 0) {
                baos.write(buffer, 0, len);
            }
            String encodedResponse = baos.toString("UTF8");
            if (DUMP_PAYLOAD) {
                log.debug("Response code: {}", statusCode);
                log.debug("Response payload: {}", encodedResponse);
            }

            // System.out.println("Response payload (len = " + encodedResponse.length() + "): " + encodedResponse);
            if (statusCode != HttpURLConnection.HTTP_OK) {
                throw new StatusCodeException(statusCode, encodedResponse);
            } else if (encodedResponse == null) {
                // This can happen if the XHR is interrupted by the server dying
                throw new InvocationException("No response payload");
            } else if (isReturnValue(encodedResponse)) {
                encodedResponse = encodedResponse.substring(4);
                return responseReader.read(createStreamReader(encodedResponse));
            } else if (isThrownException(encodedResponse)) {
                encodedResponse = encodedResponse.substring(4);
                Throwable throwable = (Throwable) createStreamReader(encodedResponse).readObject();
                throw throwable;
            } else {
                throw new InvocationException("Unknown response " + encodedResponse);
            }
        } catch (IOException e) {

            log.error("error response: {}", IOUtils.toString(connection.getErrorStream()));
            throw new InvocationException("IOException while receiving RPC response", e);

        } catch (SerializationException e) {
            throw new InvocationException("Error while deserialization response", e);
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException ignore) {
                }
            }
            if (connection != null) {
                // connection.disconnect();
            }
        }
    }

    static boolean isReturnValue(String encodedResponse) {
        return encodedResponse.startsWith("//OK");
    }

    static boolean isThrownException(String encodedResponse) {
        return encodedResponse.startsWith("//EX");
    }
}