com.cgxlib.xq.client.plugins.ajax.Ajax.java Source code

Java tutorial

Introduction

Here is the source code for com.cgxlib.xq.client.plugins.ajax.Ajax.java

Source

/*
 * Copyright 2014, The gwtquery team.
 *
 * 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.cgxlib.xq.client.plugins.ajax;

/*
 * #%L
 * CGXlib
 * %%
 * Copyright (C) 2016 CGXlib (http://www.cgxlib.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.
 * #L%
  Code is originally from gwtquery, and modified by CGXlib team.
 */

import com.cgxlib.xq.client.*;
import com.cgxlib.xq.client.builders.JsonBuilder;
import com.cgxlib.xq.client.js.JsUtils;
import com.cgxlib.xq.client.plugins.Plugin;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.ScriptInjector;
import com.google.gwt.dom.client.Element;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.Response;
import com.google.gwt.user.client.ui.FormPanel;

/**
 * Ajax class for XQ.
 * <p/>
 * The jQuery library has a full suite of AJAX capabilities, but GWT is plenty of classes to get
 * data from server side: RPC, XHR, RF, etc.
 * <p/>
 * This class is not a substitute for the GWT utilities, but a complement to get server data in a
 * jquery way, specially when querying non java backends.
 * <p/>
 * We do not pretend to clone all the jquery Ajax API inside xq, just take its syntax and to
 * implement the most popular usage of it. This implementation is almost thought to be used as an
 * alternative to the GWT-XHR, GWT-XML and GWT-JSON modules.
 */
public class Ajax extends XQ {

    public static final String JSON_CONTENT_TYPE = "application/json";

    public static final String JSON_CONTENT_TYPE_UTF8 = JSON_CONTENT_TYPE + "; charset=utf-8";
    public static final Class<Ajax> Ajax = registerPlugin(Ajax.class, new Plugin<Ajax>() {
        public Ajax init(XQ xq) {
            return new Ajax(xq);
        }
    });

    protected Ajax(XQ xq) {
        super(xq);
    }

    public static Promise ajax(IsProperties p) {
        Settings s = createSettings();
        s.load(p);
        return ajax(s);
    }

    /**
     * Perform an ajax request to the server.
     * <p/>
     * Example:
     * <p/>
     * <pre>
     * import static com.cgxlib.xq.client.GQ.*
     * ...
     * Properties properties = $$("dataType: xml, type: post; data: {q: 'gwt'}, headers: {X-Powered-By: XQ}");
     * ajax("test.php", new Function() {
     * public void f() {
     * Element xmlElem = getData()[0];
     * System.out.println($("message", xmlElem));
     * }
     * }, new Function(){
     * public void f() {
     * System.err.println("Ajax Error: " + getData()[1]);
     * }
     * }, properties);
     * </pre>
     */
    public static Promise ajax(Settings settings) {
        resolveSettings(settings);

        final Function onSuccess = settings.getSuccess();
        if (onSuccess != null) {
            onSuccess.setElement(settings.getContext());
        }

        final Function onError = settings.getError();
        if (onError != null) {
            onError.setElement(settings.getContext());
        }

        final String dataType = settings.getDataType();

        Promise ret = null;

        if ("jsonp".equalsIgnoreCase(dataType)) {
            ret = XQUtil.getAjaxTransport().getJsonP(settings);
        } else if ("loadscript".equalsIgnoreCase(dataType)) {
            ret = XQUtil.getAjaxTransport().getLoadScript(settings);
        } else {
            ret = XQUtil.getAjaxTransport().getXhr(settings).then(new Function() {
                public Object f(Object... args) {
                    Response response = arguments(0);
                    Request request = arguments(1);
                    Object retData = response.getText();
                    if (retData != null && !"".equals(retData)) {
                        try {
                            if ("xml".equalsIgnoreCase(dataType)) {
                                retData = JsUtils.parseXML(response.getText());
                            } else if ("json".equalsIgnoreCase(dataType)) {
                                retData = XQUtil.create(response.getText());
                            } else {
                                retData = response.getText();
                                if ("script".equalsIgnoreCase(dataType)) {
                                    ScriptInjector.fromString((String) retData).setWindow(window).inject();
                                }
                            }
                        } catch (Exception e) {
                            if (GWT.isClient() && GWT.getUncaughtExceptionHandler() != null) {
                                GWT.getUncaughtExceptionHandler().onUncaughtException(e);
                            } else {
                                e.printStackTrace();
                            }
                        }
                    }
                    return new Object[] { retData, "success", request, response };
                }
            }, new Function() {
                public Object f(Object... args) {
                    Throwable exception = arguments(0);
                    Request request = getArgument(1, Request.class);
                    String msg = String.valueOf(exception);
                    return new Object[] { null, msg, request, null, exception };
                }
            });
        }
        if (onSuccess != null) {
            ret.done(onSuccess);
        }
        if (onError != null) {
            ret.fail(onError);
        }
        return ret;
    }

    private static void resolveSettings(Settings settings) {
        String url = settings.getUrl();
        assert settings != null && settings.getUrl() != null : "no url found in settings";

        String type = "POST";
        if (settings.getType() != null) {
            type = settings.getType().toUpperCase();
        }
        if ("jsonp".equalsIgnoreCase(settings.getDataType())) {
            type = "GET";
        }
        settings.setType(type);

        IsProperties data = settings.getData();
        if (data != null) {
            String dataString = null, contentType = null;
            if (data.getDataImpl() instanceof JavaScriptObject
                    && JsUtils.isFormData(data.<JavaScriptObject>getDataImpl())) {
                dataString = null;
                contentType = FormPanel.ENCODING_URLENCODED;
            } else if (settings.getType().matches("(POST|PUT)")
                    && "json".equalsIgnoreCase(settings.getDataType())) {
                dataString = data.toJson();
                contentType = JSON_CONTENT_TYPE_UTF8;
            } else {
                dataString = data.toQueryString();
                contentType = FormPanel.ENCODING_URLENCODED;
            }
            settings.setDataString(dataString);
            settings.setContentType(contentType);
        }

        if ("GET".equals(settings.getType()) && settings.getDataString() != null) {
            url += (url.contains("?") ? "&" : "?") + settings.getDataString();
            settings.setUrl(url);
        }
    }

    public static Promise ajax(String url, Function onSuccess, Function onError) {
        return ajax(url, onSuccess, onError, (Settings) null);
    }

    public static Promise ajax(String url, Function onSuccess, Function onError, Settings s) {
        if (s == null) {
            s = createSettings();
        }
        s.setUrl(url).setSuccess(onSuccess).setError(onError);
        return ajax(s);
    }

    public static Promise ajax(String url, IsProperties p) {
        Settings s = createSettings();
        s.load(p);
        s.setUrl(url);
        return ajax(s);
    }

    public static Promise ajax(String url, Settings settings) {
        return ajax(settings.setUrl(url));
    }

    public static Settings createSettings() {
        return createSettings("");
    }

    public static Settings createSettings(String prop) {
        Settings s = XQUtil.create(Settings.class);
        if (prop != null && !prop.isEmpty())
            s.parse(prop);
        return s;
    }

    public static Settings createSettings(IsProperties p) {
        Settings s = XQUtil.create(Settings.class);
        s.load(p.getDataImpl());
        return s;
    }

    public static Promise get(String url) {
        return get(url, null);
    }

    public static Promise get(String url, IsProperties data) {
        return get(url, (IsProperties) data, null);
    }

    public static Promise get(String url, IsProperties data, Function onSuccess) {
        Settings s = createSettings();
        s.setUrl(url);
        s.setDataType("txt");
        s.setType("get");
        s.setData(data);
        s.setSuccess(onSuccess);
        return ajax(s);
    }

    public static Promise getJSON(String url, IsProperties data) {
        return getJSON(url, data, null);
    }

    public static Promise getJSON(String url, IsProperties data, Function onSuccess) {
        Settings s = createSettings();
        s.setUrl(url);
        s.setDataType("json");
        s.setType("post");
        s.setData(data);
        s.setSuccess(onSuccess);
        return ajax(s);
    }

    public static Promise getJSONP(String url) {
        return getJSONP(url, null);
    }

    public static Promise getJSONP(String url, IsProperties data) {
        return getJSONP(url, (IsProperties) data, null);
    }

    public static Promise getJSONP(String url, IsProperties data, Function onSuccess) {
        Settings s = createSettings();
        s.setUrl(url);
        s.setDataType("jsonp");
        s.setType("get");
        s.setData(data);
        s.setSuccess(onSuccess);
        return ajax(s);
    }

    public static Promise getJSONP(String url, Function success, Function error, int timeout) {
        return ajax(createSettings().setUrl(url).setDataType("jsonp").setType("get").setTimeout(timeout)
                .setSuccess(success).setError(error));
    }

    /**
     * Get a JavaScript file from the server using a GET HTTP request, then execute it.
     */
    public static Promise getScript(String url) {
        return getScript(url, null);
    }

    public static Promise getScript(final String url, Function success) {
        return ajax(createSettings().setUrl(url).setType("get").setDataType("script").setSuccess(success));
    }

    /**
     * Load a JavaScript file from any url using the script tag mechanism.
     */
    public static Promise loadScript(String url) {
        return loadScript(url, null);
    }

    public static Promise loadScript(final String url, Function success) {
        return ajax(createSettings().setUrl(url).setType("get").setDataType("loadscript").setSuccess(success));
    }

    public static Promise post(String url, IsProperties data) {
        return post(url, (IsProperties) data, null);
    }

    public static Promise post(String url, IsProperties data, final Function onSuccess) {
        Settings s = createSettings();
        s.setUrl(url);
        s.setDataType("txt");
        s.setType("post");
        s.setData(data);
        s.setSuccess(onSuccess);
        return ajax(s);
    }

    public Ajax load(String url, IsProperties data) {
        return load(url, data);
    }

    public Ajax load(String url, IsProperties data, final Function onSuccess) {
        Settings s = createSettings();
        final String filter = url.contains(" ") ? url.replaceFirst("^[^\\s]+\\s+", "") : "";
        s.setUrl(url.replaceAll("\\s+.+$", ""));
        s.setDataType("html");
        s.setType("get");
        s.setData(data);
        s.setSuccess(new Function() {
            public void f() {
                try {
                    // We clean up the returned string to smoothly append it to our document
                    // Note: using '\s\S' instead of '.' because gwt String emulation does
                    // not support java embedded flag expressions (?s) and javascript does
                    // not have multidot flag.
                    String s = arguments(0).toString().replaceAll("<![^>]+>\\s*", "")
                            .replaceAll("</?html[\\s\\S]*?>\\s*", "").replaceAll("<head[\\s\\S]*?</head>\\s*", "")
                            .replaceAll("<script[\\s\\S]*?</script>\\s*", "")
                            .replaceAll("</?body[\\s\\S]*?>\\s*", "");
                    // We wrap the results in a div
                    s = "<div>" + s + "</div>";

                    Ajax.this.empty().append(filter.isEmpty() ? $(s) : $(s).find(filter));
                    if (onSuccess != null) {
                        onSuccess.setElement(Ajax.this.get(0));
                        onSuccess.f();
                    }
                } catch (Exception e) {
                    if (GWT.getUncaughtExceptionHandler() != null) {
                        GWT.getUncaughtExceptionHandler().onUncaughtException(e);
                    }
                }
            }
        });
        ajax(s);
        return this;
    }

    /**
     * Ajax Transport object.
     */
    public interface AjaxTransport {
        Promise getJsonP(Settings settings);

        Promise getLoadScript(Settings settings);

        Promise getXhr(Settings settings);
    }

    /**
     * Ajax Settings object.
     */
    public interface Settings extends JsonBuilder {
        String getContentType();

        Settings setContentType(String t);

        Element getContext();

        Settings setContext(Element e);

        IsProperties getData();

        Settings setData(Object p);

        String getDataString();

        Settings setDataString(String d);

        String getDataType();

        Settings setDataType(String t);

        Function getError();

        Settings setError(Function f);

        IsProperties getHeaders();

        Settings setHeaders(IsProperties p);

        String getPassword();

        Settings setPassword(String p);

        Function getSuccess();

        Settings setSuccess(Function f);

        int getTimeout();

        Settings setTimeout(int t);

        String getType();

        Settings setType(String t);

        String getUrl();

        Settings setUrl(String u);

        String getUsername();

        Settings setUsername(String u);

        boolean getWithCredentials();

        Settings setWithCredentials(boolean b);
    }
}