com.data2semantics.yasgui.client.helpers.SparqlQuery.java Source code

Java tutorial

Introduction

Here is the source code for com.data2semantics.yasgui.client.helpers.SparqlQuery.java

Source

package com.data2semantics.yasgui.client.helpers;

/*
 * #%L
 * YASGUI
 * %%
 * Copyright (C) 2013 Laurens Rietveld
 * %%
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 * #L%
 */

import com.data2semantics.yasgui.client.View;
import com.data2semantics.yasgui.client.tab.QueryTab;
import com.data2semantics.yasgui.client.tab.optionbar.endpoints.EndpointInput;
import com.google.common.collect.HashMultimap;
import com.google.gwt.core.client.GWT;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;

public class SparqlQuery {

    private static String corsNotification = "For information on CORS, and how to access your endpoint, "
            + "visit the <a href=\"http://laurensrietveld.nl/yasgui/help.html\" target=\"_blank\">YASGUI help page</a> for more information.";

    private View view;
    private String tabId;
    private String endpoint;
    private String queryString;
    private String acceptHeader;

    private HashMultimap<String, String> customQueryArgs;
    private RequestBuilder.Method queryRequestMethod;

    public SparqlQuery(View view) {
        this.view = view;
    }

    private void fetchProperties() {
        //onblur might not always fire (will have to check that). for now, store query in settings before query execution just to be sure
        view.getCallableJsMethods().storeQueryInCookie();
        queryString = view.getSelectedTabSettings().getQueryString();
        //the same happens whenever our endpointinput has focus
        EndpointInput endpointInput = view.getSelectedTab().getEndpointInput();
        if (endpointInput != null) {
            endpointInput.storeEndpointInSettings();
        }
        endpoint = view.getSelectedTabSettings().getEndpoint();
        view.checkAndAddEndpointToDs(endpoint);

        tabId = view.getSelectedTab().getID();

        if (view.getSelectedTab().getQueryType().equals("CONSTRUCT")
                || view.getSelectedTab().getQueryType().equals("DESCRIBE")) {
            //Change content type automatically for construct queries
            acceptHeader = view.getSelectedTabSettings().getConstructContentType();
        } else {
            acceptHeader = view.getSelectedTabSettings().getSelectContentType();
        }
        acceptHeader += ",*/*;q=0.9";

        customQueryArgs = view.getSelectedTabSettings().getQueryArgs();
        queryRequestMethod = (view.getSelectedTabSettings().getRequestMethod().equals("GET") ? RequestBuilder.GET
                : RequestBuilder.POST);
    }

    public void doRequest() {
        if (!view.getConnHelper().isOnline() && !JsMethods.corsEnabled(endpoint)) {
            //cors disabled and not online: problem!
            String errorMsg = "YASGUI is current not connected to the YASGUI server. "
                    + "This mean you can only access endpoints on your own computer (e.g. localhost), which are <a href=\"http://enable-cors.org/\" target=\"_blank\">CORS enabled</a>.<br>"
                    + "The endpoint you try to access is either not running on your computer, or not CORS-enabled.<br>"
                    + corsNotification;
            view.getErrorHelper().onQueryError(errorMsg, endpoint, queryString, customQueryArgs);
            return;
        }

        view.getElements().onQueryStart();
        RequestBuilder builder;
        HashMultimap<String, String> queryArgs = customQueryArgs;
        RequestBuilder.Method requestMethod = queryRequestMethod;
        queryArgs.put("query", queryString);
        if (JsMethods.corsEnabled(endpoint)) {
            String params = Helper.getParamsAsString(queryArgs);
            String url = endpoint;
            if (queryRequestMethod == RequestBuilder.GET) {
                url += "?" + params;
            }
            builder = new RequestBuilder(queryRequestMethod, url);
            if (queryRequestMethod == RequestBuilder.POST) {
                builder.setHeader("Content-Type", "application/x-www-form-urlencoded");
                builder.setRequestData(params);
            }
        } else {
            requestMethod = RequestBuilder.POST;
            queryArgs.put("endpoint", endpoint);
            queryArgs.put("requestMethod", (queryRequestMethod == RequestBuilder.POST ? "POST" : "GET"));
            builder = new RequestBuilder(RequestBuilder.POST, GWT.getModuleBaseURL() + "sparql"); //send via proxy
            builder.setHeader("Content-Type", "application/x-www-form-urlencoded");
        }
        builder.setHeader("Accept", acceptHeader);
        try {
            final long startTime = System.currentTimeMillis();
            builder.sendRequest((requestMethod == RequestBuilder.POST ? Helper.getParamsAsString(queryArgs) : null),
                    new RequestCallback() {
                        public void onError(Request request, Throwable e) {
                            //e.g. a timeout
                            queryErrorHandler(e);
                        }

                        @Override
                        public void onResponseReceived(Request request, Response response) {
                            view.getElements().onQueryFinish();
                            if (!response.getStatusText().equals("Abort")) {
                                //if user cancels query, textStatus will be 'abort'. No need to show error window then
                                if (response.getStatusCode() >= 200 && response.getStatusCode() < 300) {
                                    if (view.getSettings().useGoogleAnalytics()) {
                                        long stopTime = System.currentTimeMillis();
                                        GoogleAnalytics.trackEvent(new GoogleAnalyticsEvent(endpoint,
                                                JsMethods.getUncommentedSparql(queryString),
                                                Integer.toString((int) (stopTime - startTime)),
                                                (int) (stopTime - startTime)));
                                    }
                                    drawResults(response.getText(), response.getHeader("Content-Type"));
                                } else {
                                    queryErrorHandler(response);

                                }
                            }

                        }
                    });
        } catch (RequestException e) {
            queryErrorHandler(e);
        }
    }

    private void queryErrorHandler(Response response) {
        if (view.getSettings().useGoogleAnalytics()) {
            GoogleAnalytics.trackEvent(
                    new GoogleAnalyticsEvent(endpoint, JsMethods.getUncommentedSparql(queryString), "-1", -1));
        }
        view.getElements().onQueryFinish();

        //clear query result
        QueryTab tab = (QueryTab) view.getTabs().getTab(tabId);
        view.getTabs().selectTab(tabId);
        if (tab != null) {
            view.getSelectedTab().getResultContainer().resetResultArea();
        }

        String errorMsg;
        if (response.getStatusCode() == 0
                && (response.getStatusText() == null || response.getStatusText().trim().length() == 0)) {
            view.getConnHelper().checkOnlineStatus();
            errorMsg = "Error querying endpoint: empty response returned";
        } else {
            errorMsg = "Error querying endpoint: " + response.getStatusCode() + " - " + response.getStatusText();
        }
        if (!Helper.inDebugMode() && view.getSettings().getEnabledFeatures().endpointSelectionEnabled()
                && JsMethods.corsEnabled(endpoint) != true && Helper.isLocalhostDomain(endpoint)) {
            //         //we were trying to access a local endpoint via the proxy: this won't work...
            errorMsg += "<br><br>A possible reason for this error (next to an incorrect endpoint URL) is that you tried to send a query to an endpoint installed on your computer.<br>"
                    + "This only works when the endpoint is <a href=\"http://enable-cors.org/\" target=\"_blank\">CORS enabled</a>.<br>"
                    + corsNotification;

        }
        view.getErrorHelper().onQueryError(errorMsg, endpoint, queryString, customQueryArgs);
    }

    private void queryErrorHandler(Throwable throwable) {
        view.getElements().onQueryFinish();

        if (view.getSettings().useGoogleAnalytics()) {
            GoogleAnalytics.trackEvent(
                    new GoogleAnalyticsEvent(endpoint, JsMethods.getUncommentedSparql(queryString), "-1", -1));
        }

        //clear query result
        QueryTab tab = (QueryTab) view.getTabs().getTab(tabId);
        view.getTabs().selectTab(tabId);
        if (tab != null) {
            view.getSelectedTab().getResultContainer().resetResultArea();
        }

        view.getErrorHelper().onQueryError(throwable.getMessage(), endpoint, queryString, customQueryArgs);
    }

    private void preProcess() {
        //set history checkpoint (do before resetting resultcontainer, as we need this info)
        view.getHistory().setHistoryCheckpoint();

        //clear current result container -before- query, not after
        view.getSelectedTab().getResultContainer().resetResultArea();

        //disable string to download icon
        if (JsMethods.stringToDownloadSupported()) {
            view.getSelectedTab().getDownloadLink().showDisabledIcon();
        }

        //onblur might not always fire (will have to check that). for now, store query in settings before query execution just to be sure
        view.getCallableJsMethods().storeQueryInCookie();
        //the same happens whenever our endpointinput has focus
        EndpointInput endpointInput = view.getSelectedTab().getEndpointInput();
        if (endpointInput != null) {
            endpointInput.storeEndpointInSettings();
        }
        view.checkAndAddEndpointToDs(endpoint);
    }

    private void drawResults(String resultString, String contentType) {
        QueryTab tab = (QueryTab) view.getTabs().getTab(tabId);
        view.getTabs().selectTab(tabId);
        if (tab == null) {
            view.getErrorHelper().onError("No tab to draw results in");
        }
        tab.getResultContainer().drawResult(endpoint, queryString, resultString, contentType);
    }

    public static void exec(View view) {
        SparqlQuery query = new SparqlQuery(view);
        query.fetchProperties();
        query.preProcess();
        query.doRequest();
    }
}