Java tutorial
/* * 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); } }