All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gwt.query.client.plugins.ajax.Ajax Maven / Gradle / Ivy

The newest version!
/*
 * 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.google.gwt.query.client.plugins.ajax;

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.query.client.Function;
import com.google.gwt.query.client.GQ;
import com.google.gwt.query.client.GQuery;
import com.google.gwt.query.client.IsProperties;
import com.google.gwt.query.client.Promise;
import com.google.gwt.query.client.builders.JsonBuilder;
import com.google.gwt.query.client.js.JsUtils;
import com.google.gwt.query.client.plugins.Plugin;
import com.google.gwt.query.client.plugins.deferred.PromiseFunction;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.FormPanel;

/**
 * Ajax class for GQuery.
 *
 * 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.
 *
 * 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.
 *
 * We do not pretend to clone all the jquery Ajax API inside gquery, 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 GQuery {

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

  public static final String JSON_CONTENT_TYPE_UTF8 = JSON_CONTENT_TYPE + "; charset=utf-8";

  /**
   * 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();

    Element getContext();

    IsProperties getData();

    String getDataString();

    String getDataType();

    Function getError();

    IsProperties getHeaders();

    String getPassword();

    Function getSuccess();

    int getTimeout();

    String getType();

    String getUrl();

    String getUsername();

    boolean getWithCredentials();

    Settings setContentType(String t);

    Settings setContext(Element e);

    Settings setData(Object p);

    Settings setDataString(String d);

    Settings setDataType(String t);

    Settings setError(Function f);

    Settings setHeaders(IsProperties p);

    Settings setPassword(String p);

    Settings setSuccess(Function f);

    Settings setTimeout(int t);

    Settings setType(String t);

    Settings setUrl(String u);

    Settings setUsername(String u);

    Settings setWithCredentials(boolean b);
  }

  public static final Class Ajax = registerPlugin(Ajax.class, new Plugin() {
    public Ajax init(GQuery gq) {
      return new Ajax(gq);
    }
  });

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

  /**
   * Perform an ajax request to the server.
   *
   * Example:
   *
   * 
    import static com.google.gwt.query.client.GQ.*
    ...
    Properties properties = $$("dataType: xml, type: post; data: {q: 'gwt'}, headers: {X-Powered-By: GQuery}");
    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);
   * 
* */ 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 = GQ.getAjaxTransport().getJsonP(settings); } else if ("loadscript".equalsIgnoreCase(dataType)) { ret = GQ.getAjaxTransport().getLoadScript(settings); } else { ret = GQ.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 = GQ.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. 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 = GQ.create(Settings.class); if (prop != null && !prop.isEmpty()) s.parse(prop); return s; } public static Settings createSettings(IsProperties p) { Settings s = GQ.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); } /** * @deprecated Use promises instead */ 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) { if (!GWT.isClient() || $("script[src^='" + url + "']").isEmpty()) { return ajax(createSettings() .setUrl(url) .setType("get") .setDataType("loadscript") .setSuccess(success)); } else { return Deferred().resolve().promise(); } } 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); } protected Ajax(GQuery gq) { super(gq); } 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("\\s*", "") .replaceAll("\\s*", "") .replaceAll("\\s*", "") .replaceAll("\\s*", ""); // We wrap the results in a div s = "
" + s + "
"; 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; } /** * Load an external resource using the link tag element. * It is appended to the head of the document. * * @param rel Specifies the relationship between the current document and the linked document. * @param url Specifies the location of the linked document * @return a Promise which will be resolved when the external resource has been loaded. */ public static Promise loadLink(final String rel, final String url) { GQuery link = $("link[rel='" + rel + "'][href^='" + url + "']"); if (link.isEmpty()) { return new PromiseFunction() { public void f(final Deferred dfd) { GQuery link = $(""); link.on("load", new Function() { public void f() { // load event is fired before the imported stuff has actually // being ready, we delay it to be sure it is ready. new Timer() { public void run() { dfd.resolve(); } }.schedule(100); } }); $(document.getHead()).append(link); } }; } else { return Deferred().resolve().promise(); } } /** * Load an external html resource using the link tag element, it sets * the relationship between the current document as 'import'. * It is very useful to import web-components. */ public static Promise importHtml(String url) { return loadLink("import", url); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy