fr.gael.dhus.gwt.client.page.SearchPage.java Source code

Java tutorial

Introduction

Here is the source code for fr.gael.dhus.gwt.client.page.SearchPage.java

Source

/*
 * Data Hub Service (DHuS) - For Space data distribution.
 * Copyright (C) 2013,2014,2015 GAEL Systems
 *
 * This file is part of DHuS software sources.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package fr.gael.dhus.gwt.client.page;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsonUtils;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.DomEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;

import fr.gael.dhus.gwt.client.AccessDeniedRedirectionCallback;
import fr.gael.dhus.gwt.client.GWTClient;
import fr.gael.dhus.gwt.services.ProductCartServiceAsync;
import fr.gael.dhus.gwt.services.ProductServiceAsync;
import fr.gael.dhus.gwt.services.SearchServiceAsync;
import fr.gael.dhus.gwt.services.UserServiceAsync;
import fr.gael.dhus.gwt.share.ProductData;
import fr.gael.dhus.gwt.share.RoleData;
import fr.gael.dhus.gwt.share.SearchData;
import fr.gael.dhus.gwt.share.UserData;

public class SearchPage extends AbstractPage {
    private static TextBox search_value;
    private static TextBox search_request;

    private static boolean searchClicked = false;

    private static RootPanel search_button;
    private static boolean firstSearch = true;
    private static boolean firstRefresh = true;
    private static SearchServiceAsync searchService = SearchServiceAsync.Util.getInstance();
    private static UserServiceAsync userService = UserServiceAsync.Util.getInstance();
    private static ProductServiceAsync productService = ProductServiceAsync.Util.getInstance();
    private static ProductCartServiceAsync productCartService = ProductCartServiceAsync.Util.getInstance();

    private static List<Long> cart;

    private static HashMap<Long, SearchData> displayedSearches = new HashMap<Long, SearchData>();

    private static String ADVANCED_PRODUCTTYPE = "productType";
    private static String ADVANCED_SENSORMODE = "sensorMode";
    private static String ADVANCED_RESOLUTION = "resolution";
    private static String ADVANCED_POLARISATION = "polarisation";
    private static String ADVANCED_SENSINGDATE = "sensingDate";
    private static String ADVANCED_SENSINGDATEEND = "sensingDateEnd";
    private static String ADVANCED_INGESTIONDATE = "ingestionDate";
    private static String ADVANCED_INGESTIONDATEEND = "ingestionDateEnd";

    private static TextBox advancedProductType;
    private static TextBox advancedPolarisation;
    private static TextBox advancedSensorMode;
    private static TextBox advancedSwath;
    private static TextBox advancedSensingDate;
    private static TextBox advancedIngestionDate;
    private static TextBox advancedSensingDateEnd;
    private static TextBox advancedIngestionDateEnd;

    private static boolean advancedSearchActive = false;

    private static SearchData givenSearch;

    public SearchPage() {
        super.name = "Search";
        super.roles = Arrays.asList(RoleData.SEARCH);
    }

    @Override
    public native JavaScriptObject getJSInitFunction()
    /*-{
       return function() {
     @fr.gael.dhus.gwt.client.page.SearchPage::init()();
       }
    }-*/;

    private static native void showSearch()
    /*-{
       $wnd.showSearch(function ( sSource, aoData, fnCallback, oSettings ) {
      @fr.gael.dhus.gwt.client.page.SearchPage::search(*)(oSettings._iDisplayStart, oSettings._iDisplayLength, fnCallback);
        }, function(data) { 
      @fr.gael.dhus.gwt.client.page.SearchPage::viewItem(*)(data);
        }, function(id, inUserCart) { 
      @fr.gael.dhus.gwt.client.page.SearchPage::modifyItemInCart(*)(id, inUserCart);
        }, function(active) { 
      @fr.gael.dhus.gwt.client.page.SearchPage::setAdvancedSearchActive(*)(active);
        }, function(id) { 
      @fr.gael.dhus.gwt.client.page.SearchPage::selectSavedSearch(*)(id);
        }, function(data, name) { 
      @fr.gael.dhus.gwt.client.page.SearchPage::deleteProduct(*)(data, name);
        });
    }-*/;

    private static native void doSearch()
    /*-{
       $wnd.doSearch();
    }-*/;

    private static native String getCurrentPolygon()
    /*-{
       return $wnd.getCurrentPolygon();
    }-*/;

    private static native String getCurrentPolygonSearchString()
    /*-{
       return $wnd.getCurrentPolygonSearchString();
    }-*/;

    private static native void destroyFeaturesFromAllFootprintLayer()
    /*-{
       $wnd.destroyFeaturesFromAllFootprintLayer();
    }-*/;

    private static native void addFeatureToAllFootprintLayer(JavaScriptObject feature)
    /*-{
       $wnd.addFeatureToAllFootprintLayer(feature);
    }-*/;

    private static native void setSearchedFootprint(JavaScriptObject feature)
    /*-{
       $wnd.search_setSearchedFootprint(feature);
    }-*/;

    private static native void searchIsEmpty()
    /*-{
       $wnd.searchIsEmpty();
    }-*/;

    private static native boolean searchTableDefined()
    /*-{
       return $wnd.searchTableDefined();
    }-*/;

    private static native void search_filling()
    /*-{
       return $wnd.search_filling();
    }-*/;

    private static native void setSearches(JavaScriptObject searches)
    /*-{
       return $wnd.setSearches(searches);
    }-*/;

    private static native void refreshSearch()
    /*-{
       return $wnd.search_refreshSearch();
    }-*/;

    private static native void displayAdvancedSearch(boolean displayed)
    /*-{
       return $wnd.search_displayAdvancedSearch(displayed);
    }-*/;

    @Override
    public native JavaScriptObject getJSRefreshFunction()
    /*-{
       return function() {      
     @fr.gael.dhus.gwt.client.page.SearchPage::refresh()();
       }
    }-*/;

    @Override
    public void unload() {
        super.unload();
        firstSearch = true;
        firstRefresh = true;
    }

    private static void refresh() {
        if (givenSearch != null) {
            search_value.setValue(givenSearch.getValue());
            search_filling();
            advancedProductType.setValue("");
            advancedSensorMode.setValue("");
            advancedPolarisation.setValue("");
            advancedSwath.setValue("");
            advancedIngestionDate.setValue("");
            advancedIngestionDateEnd.setValue("");
            advancedSensingDate.setValue("");
            advancedSensingDateEnd.setValue("");
            if (givenSearch.getAdvanced() != null && !givenSearch.getAdvanced().isEmpty()) {
                displayAdvancedSearch(true);
                for (String key : givenSearch.getAdvanced().keySet()) {
                    String value = givenSearch.getAdvanced().get(key);
                    if (key.equals(ADVANCED_PRODUCTTYPE)) {
                        advancedProductType.setValue(value);
                    } else if (key.equals(ADVANCED_SENSORMODE)) {
                        advancedSensorMode.setValue(value);
                    } else if (key.equals(ADVANCED_POLARISATION)) {
                        advancedPolarisation.setValue(value);
                    } else if (key.equals(ADVANCED_RESOLUTION)) {
                        advancedSwath.setValue(value);
                    } else if (key.equals(ADVANCED_SENSINGDATE)) {
                        advancedSensingDate.setValue(value);
                    } else if (key.equals(ADVANCED_SENSINGDATEEND)) {
                        advancedSensingDateEnd.setValue(value);
                    } else if (key.equals(ADVANCED_INGESTIONDATE)) {
                        advancedIngestionDate.setValue(value);
                    } else if (key.equals(ADVANCED_INGESTIONDATEEND)) {
                        advancedIngestionDateEnd.setValue(value);
                    }
                }
            } else {
                displayAdvancedSearch(false);
            }
            if (givenSearch.getFootprint() != null) {
                Double[][][] pts = givenSearch.getFootprint();
                JavaScriptObject footPrintJS = ProductData.getJsFootprintLayer(pts, true);
                setSearchedFootprint(footPrintJS);
            } else {
                setSearchedFootprint(null);
            }
            NativeEvent evt = Document.get().createClickEvent(0, 0, 0, 0, 0, false, false, false, false);
            DomEvent.fireNativeEvent(evt, search_button);
            givenSearch = null;
        } else if (!firstRefresh && searchClicked) {
            refreshSearch();
        } else {
            firstRefresh = false;
        }
        setSearches(null);
        displayedSearches.clear();
        reloadSavedSearches();
    }

    private static void reloadSavedSearches() {
        userService.getAllUserSearches(GWTClient.getCurrentUser().getId(),
                new AccessDeniedRedirectionCallback<List<SearchData>>() {

                    @Override
                    public void _onFailure(Throwable caught) {
                        Window.alert("There was an error while getting your saved searches.");
                    }

                    @Override
                    public void onSuccess(List<SearchData> result) {
                        if (result == null) {
                            return;
                        }
                        String searches = "[";
                        for (SearchData search : result) {
                            String advancedText = "";
                            Map<String, String> advanceds = search.getAdvanced();
                            if (advanceds != null && !advanceds.isEmpty()) {
                                advancedText += "<i> (";
                                boolean first = true;
                                List<String> keys = new ArrayList<String>(advanceds.keySet());
                                Collections.sort(keys);
                                String lastKey = "";
                                for (String key : keys) {
                                    if ((lastKey + "End").equals(key)) {
                                        advancedText += " to " + advanceds.get(key);
                                    } else {
                                        if (key.endsWith("End")) {
                                            advancedText += (first ? "" : ", ") + key.substring(0, key.length() - 3)
                                                    + ": * to " + advanceds.get(key);
                                        } else {
                                            advancedText += (first ? "" : ", ") + key + ": " + advanceds.get(key);
                                        }
                                    }
                                    first = false;
                                    lastKey = key;
                                }
                                advancedText += ")</i>";
                            }
                            displayedSearches.put(search.getId(), search);
                            searches += "{\"id\":" + search.getId() + ",\"value\":\""
                                    + search.getComplete().replace("\"", "\\\"") + "\"},";
                        }
                        if (result.size() > 0) {
                            searches = searches.substring(0, searches.length() - 1);
                        }
                        searches += "]";
                        setSearches(JsonUtils.safeEval(searches));
                    }
                });
    }

    private static void init() {
        firstSearch = true;

        advancedProductType = TextBox.wrap(RootPanel.get("search_advancedFieldProductType").getElement());
        advancedIngestionDate = TextBox.wrap(RootPanel.get("search_advancedFieldIngestionDate").getElement());
        advancedSensorMode = TextBox.wrap(RootPanel.get("search_advancedFieldSensorMode").getElement());
        advancedPolarisation = TextBox.wrap(RootPanel.get("search_advancedFieldPolarisation").getElement());
        advancedSwath = TextBox.wrap(RootPanel.get("search_advancedFieldSwath").getElement());
        advancedSensingDate = TextBox.wrap(RootPanel.get("search_advancedFieldSensingDate").getElement());
        advancedIngestionDateEnd = TextBox.wrap(RootPanel.get("search_advancedFieldIngestionDateEnd").getElement());
        advancedSensingDateEnd = TextBox.wrap(RootPanel.get("search_advancedFieldSensingDateEnd").getElement());

        search_button = RootPanel.get("search_button");
        search_button.addDomHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                searchClicked = true;
                doSearch();
            }
        }, ClickEvent.getType());
        search_request = TextBox.wrap(RootPanel.get("search_request").getElement());
        search_value = TextBox.wrap(RootPanel.get("search_value").getElement());
        search_value.addKeyUpHandler(new KeyUpHandler() {
            @Override
            public void onKeyUp(KeyUpEvent event) {
                if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
                    NativeEvent evt = Document.get().createClickEvent(0, 0, 0, 0, 0, false, false, false, false);
                    DomEvent.fireNativeEvent(evt, search_button);
                } else {
                    search_filling();
                }
            }
        });
        final Image saveSearch = Image.wrap(RootPanel.get("search_saveImage").getElement());
        saveSearch.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                if (saveSearch.getUrl().contains("saveSearch_disabled")) {
                    return;
                }

                String searchPoly = getCurrentPolygonSearchString();
                String footprint = getCurrentPolygon();
                String advancedSearch = "";
                HashMap<String, String> advancedSearchMap = new HashMap<String, String>();
                if (advancedSearchActive) {
                    boolean first = true;
                    String productType = advancedProductType.getValue();
                    String polarisation = advancedPolarisation.getValue();
                    String sensorMode = advancedSensorMode.getValue();
                    String swath = advancedSwath.getValue();
                    String sensingDate = advancedSensingDate.getValue();
                    String ingestionDate = advancedIngestionDate.getValue();
                    String sensingDateEnd = advancedSensingDateEnd.getValue();
                    String ingestionDateEnd = advancedIngestionDateEnd.getValue();
                    if (productType != null && !productType.isEmpty()) {
                        advancedSearchMap.put(ADVANCED_PRODUCTTYPE, productType);
                        advancedSearch += " productType:\"" + productType + "\" ";
                        first = false;
                    }
                    if (polarisation != null && !polarisation.isEmpty()) {
                        advancedSearchMap.put(ADVANCED_POLARISATION, polarisation);
                        advancedSearch += (!first ? " AND " : "") + " polarisationMode:\"" + polarisation + "\" ";
                        first = false;
                    }
                    if (sensorMode != null && !sensorMode.isEmpty()) {
                        advancedSearchMap.put(ADVANCED_SENSORMODE, sensorMode);
                        advancedSearch += (!first ? " AND " : "") + " sensorOperationalMode:\"" + sensorMode
                                + "\" ";
                        first = false;
                    }
                    if (swath != null && !swath.isEmpty()) {
                        advancedSearchMap.put(ADVANCED_RESOLUTION, swath);
                        advancedSearch += (!first ? " AND " : "") + " swathIdentifier:\"" + swath + "\" ";
                        first = false;
                    }
                    if (sensingDate != null && !sensingDate.isEmpty()) {
                        advancedSearchMap.put(ADVANCED_SENSINGDATE, sensingDate);
                    }
                    if (sensingDateEnd != null && !sensingDateEnd.isEmpty()) {
                        advancedSearchMap.put(ADVANCED_SENSINGDATEEND, sensingDateEnd);
                    }
                    if (ingestionDate != null && !ingestionDate.isEmpty()) {
                        advancedSearchMap.put(ADVANCED_INGESTIONDATE, ingestionDate);
                    }
                    if (ingestionDateEnd != null && !ingestionDateEnd.isEmpty()) {
                        advancedSearchMap.put(ADVANCED_INGESTIONDATEEND, ingestionDateEnd);
                    }
                    if ((sensingDate != null && !sensingDate.isEmpty())
                            || (sensingDateEnd != null && !sensingDateEnd.isEmpty())) {
                        String range = "["
                                + ((sensingDate != null && !sensingDate.isEmpty()) ? sensingDate + "T00:00:00.000Z"
                                        : "*")
                                + " TO "
                                + ((sensingDateEnd != null && !sensingDateEnd.isEmpty())
                                        ? sensingDateEnd + "T23:59:59.999Z"
                                        : "NOW")
                                + "]";
                        advancedSearch += (!first ? " AND " : "") + "( beginPosition:" + range + " AND endPosition:"
                                + range + " ) ";
                        first = false;
                    }
                    if ((ingestionDate != null && !ingestionDate.isEmpty())
                            || (ingestionDateEnd != null && !ingestionDateEnd.isEmpty())) {
                        String range = "["
                                + ((ingestionDate != null && !ingestionDate.isEmpty())
                                        ? ingestionDate + "T00:00:00.000Z"
                                        : "*")
                                + " TO "
                                + ((ingestionDateEnd != null && !ingestionDateEnd.isEmpty())
                                        ? ingestionDateEnd + "T23:59:59.999Z"
                                        : "NOW")
                                + " ]";
                        advancedSearch += (!first ? " AND " : "") + "( ingestionDate:" + range + " ) ";
                        first = false;
                    }
                }

                String tmpSearch = search_value.getValue();
                tmpSearch += (!tmpSearch.isEmpty() && !advancedSearch.isEmpty() ? " AND " : "") + advancedSearch;
                tmpSearch += (!tmpSearch.isEmpty() && !searchPoly.isEmpty() ? " AND " : "") + searchPoly;

                String completeSearch = tmpSearch.isEmpty() ? "*" : tmpSearch.trim();
                String search = search_value.getValue();
                search = search.isEmpty() ? "*" : search.trim();

                userService.storeUserSearch(GWTClient.getCurrentUser().getId(), search, footprint,
                        advancedSearchMap, completeSearch.trim(), new AccessDeniedRedirectionCallback<Void>() {

                            @Override
                            public void _onFailure(Throwable caught) {
                                Window.alert("There was an error while saving your search.");
                            }

                            @Override
                            public void onSuccess(Void result) {
                                Window.alert("Your search was successfully saved.");
                                reloadSavedSearches();
                            }
                        });
            }
        });
        showSearch();
        refresh();
    }

    private static void search(final int start, final int length, final JavaScriptObject function) {
        destroyFeaturesFromAllFootprintLayer();
        String searchPoly = getCurrentPolygonSearchString();
        String advancedSearch = "";
        if (advancedSearchActive) {
            boolean first = true;
            String productType = advancedProductType.getValue();
            String polarisation = advancedPolarisation.getValue();
            String sensorMode = advancedSensorMode.getValue();
            String swath = advancedSwath.getValue();
            String sensingDate = advancedSensingDate.getValue();
            String ingestionDate = advancedIngestionDate.getValue();
            String sensingDateEnd = advancedSensingDateEnd.getValue();
            String ingestionDateEnd = advancedIngestionDateEnd.getValue();
            if (productType != null && !productType.isEmpty()) {
                advancedSearch += " productType:\"" + productType + "\" ";
                first = false;
            }
            if (polarisation != null && !polarisation.isEmpty()) {
                advancedSearch += (!first ? " AND " : "") + " polarisationMode:\"" + polarisation + "\" ";
                first = false;
            }
            if (sensorMode != null && !sensorMode.isEmpty()) {
                advancedSearch += (!first ? " AND " : "") + " sensorOperationalMode:\"" + sensorMode + "\" ";
                first = false;
            }
            if (swath != null && !swath.isEmpty()) {
                advancedSearch += (!first ? " AND " : "") + " swathIdentifier:\"" + swath + "\" ";
                first = false;
            }
            if ((sensingDate != null && !sensingDate.isEmpty())
                    || (sensingDateEnd != null && !sensingDateEnd.isEmpty())) {
                String range = "["
                        + ((sensingDate != null && !sensingDate.isEmpty()) ? sensingDate + "T00:00:00.000Z" : "*")
                        + " TO "
                        + ((sensingDateEnd != null && !sensingDateEnd.isEmpty()) ? sensingDateEnd + "T23:59:59.999Z"
                                : "NOW")
                        + "]";
                advancedSearch += (!first ? " AND " : "") + "( beginPosition:" + range + " AND endPosition:" + range
                        + " ) ";
                first = false;
            }
            if ((ingestionDate != null && !ingestionDate.isEmpty())
                    || (ingestionDateEnd != null && !ingestionDateEnd.isEmpty())) {
                String range = "["
                        + ((ingestionDate != null && !ingestionDate.isEmpty()) ? ingestionDate + "T00:00:00.000Z"
                                : "*")
                        + " TO "
                        + ((ingestionDateEnd != null && !ingestionDateEnd.isEmpty())
                                ? ingestionDateEnd + "T23:59:59.999Z"
                                : "NOW")
                        + " ]";
                advancedSearch += (!first ? " AND" : "") + "( ingestionDate:" + range + " ) ";
                first = false;
            }
        }

        String tmpSearch = search_value.getValue();
        tmpSearch += (!tmpSearch.isEmpty() && !advancedSearch.isEmpty() ? " AND " : "") + advancedSearch;
        tmpSearch += (!tmpSearch.isEmpty() && !searchPoly.isEmpty() ? " AND " : "") + searchPoly;

        if (firstSearch && tmpSearch.isEmpty()) {
            firstSearch = false;
            GWTClient.callback(function,
                    JsonUtils.safeEval("{\"aaData\": [],\"iTotalRecords\" : 0, \"iTotalDisplayRecords\" : 0}"));
            return;
        }
        firstSearch = false;

        final String search = tmpSearch.isEmpty() ? "*" : tmpSearch.trim();

        search_request.setValue(search);

        DOM.setStyleAttribute(RootPanel.getBodyElement(), "cursor", "wait");
        productCartService.getProductsIdOfCart(GWTClient.getCurrentUser().getId(),
                new AccessDeniedRedirectionCallback<List<Long>>() {

                    @Override
                    public void _onFailure(Throwable caught) {
                        DOM.setStyleAttribute(RootPanel.getBodyElement(), "cursor", "default");
                        Window.alert("There was an error while getting your cart.\n" + caught.getMessage());
                    }

                    @Override
                    public void onSuccess(final List<Long> result) {
                        cart = result;
                        searchService.count(search, new AccessDeniedRedirectionCallback<Integer>() {

                            @Override
                            public void _onFailure(Throwable caught) {
                                DOM.setStyleAttribute(RootPanel.getBodyElement(), "cursor", "default");
                                Window.alert("There was an error while counting your search of '" + search + "'\n"
                                        + caught.getMessage());
                            }

                            @Override
                            public void onSuccess(final Integer total) {
                                searchService.search(search, start, length, GWTClient.getCurrentUser().getId(),
                                        new AccessDeniedRedirectionCallback<List<ProductData>>() {
                                            @Override
                                            public void _onFailure(Throwable caught) {
                                                DOM.setStyleAttribute(RootPanel.getBodyElement(), "cursor",
                                                        "default");
                                                Window.alert("There was an error while searching for '" + search
                                                        + "'\n" + caught.getMessage());
                                            }

                                            @Override
                                            public void onSuccess(List<ProductData> products) {
                                                String json = toJson(GWT.getHostPageBaseURL(), products,
                                                        GWTClient.getCurrentUser(), total);
                                                // Update the layer with footprints.
                                                for (ProductData product : products) {
                                                    JavaScriptObject js = ProductData
                                                            .getJsFootprintLayer(product.getFootprint(), false);
                                                    if (js != null)
                                                        addFeatureToAllFootprintLayer(js);
                                                }

                                                if (JsonUtils.safeToEval(json))
                                                    GWTClient.callback(function, JsonUtils.safeEval(json));

                                                DOM.setStyleAttribute(RootPanel.getBodyElement(), "cursor",
                                                        "default");
                                            }
                                        });
                            }
                        });
                    }
                });
    }

    public static void search(SearchData search) {
        givenSearch = search;
        Page.SEARCH.load();
    }

    private static void viewItem(int id) {
        SearchViewPage.viewProduct(id);
    }

    private static void deleteProduct(int id, String name) {
        if (!Window.confirm("Are you sure to delete the product '" + name + "' ?")) {
            return;
        }
        productService.deleteProduct(new Long(id), new AccessDeniedRedirectionCallback<Void>() {

            @Override
            public void _onFailure(Throwable caught) {
                Window.alert("There was an error while deleting product.\n " + caught.getMessage());
            }

            @Override
            public void onSuccess(Void result) {
                refreshSearch();
            }
        });
        return;
    }

    private static void modifyItemInCart(int id, boolean inUserCart) {
        if (inUserCart) {
            productCartService.removeProductFromCart(GWTClient.getCurrentUser().getId(), new Long(id),
                    new AccessDeniedRedirectionCallback<Void>() {

                        @Override
                        public void _onFailure(Throwable caught) {
                            Window.alert("There was an error while adding product to your cart.");
                        }

                        @Override
                        public void onSuccess(Void result) {
                            refreshSearch();
                        }
                    });
            return;
        }
        // else
        productCartService.addProductToCart(GWTClient.getCurrentUser().getId(), new Long(id),
                new AccessDeniedRedirectionCallback<Void>() {

                    @Override
                    public void _onFailure(Throwable caught) {
                        Window.alert("There was an error while adding product to your cart.");
                    }

                    @Override
                    public void onSuccess(Void result) {
                        refreshSearch();
                    }
                });
    }

    private static void selectSavedSearch(int id) {
        givenSearch = displayedSearches.get(new Long(id));
        Page.SEARCH.load();
    }

    private static void setAdvancedSearchActive(boolean active) {
        advancedSearchActive = active;
    }

    /**
     * Produces the JSON output required by search tab.
     */
    public static String toJson(ProductData product, String base_url, UserData user) {
        String summary = "";
        for (int i = 0; i < product.getSummary().size(); i++) {
            summary = summary + product.getSummary().get(i) + (i == product.getSummary().size() - 1 ? "" : ", ");
        }

        boolean can_download = GWTClient.getCurrentUser().getRoles().contains(RoleData.DOWNLOAD);

        String identifier = product.getIdentifier();
        String download = product.getOdataDownaloadPath(base_url);
        String quicklook = product.getOdataQuicklookPath(base_url);
        String thumbnail = product.getOdataThumbnailPath(base_url);
        boolean deletable = user != null && user.getRoles() != null
                && user.getRoles().contains(RoleData.DATA_MANAGER);

        if (!can_download)
            download = "null";
        else
            download = "\"" + download + "\"";

        if (!product.hasThumbnail())
            thumbnail = "null";
        else
            thumbnail = "\"" + thumbnail + "\"";

        if (!product.hasQuicklook())
            quicklook = "null";
        else
            quicklook = "\"" + quicklook + "\"";

        String footprintString = "[";
        Double[][][] footprint = product.getFootprint();
        if (footprint != null && footprint.length > 0) {
            for (Double[][] dd : footprint) {
                footprintString += "[";
                for (Double[] d : dd) {
                    footprintString += d[0] + "," + d[1] + ",";
                }
                if (dd != null && dd.length >= 1) {
                    footprintString = footprintString.substring(0, footprintString.length() - 1);
                }
                footprintString += "],";
            }
        }
        if (footprint != null && footprint.length >= 1) {
            footprintString = footprintString.substring(0, footprintString.length() - 1);
        }
        footprintString += "]";

        boolean canDownload = GWTClient.getCurrentUser().getRoles().contains(RoleData.DOWNLOAD);

        String json = "[\n" + "   {\n" + "      \"quicklook\": " + quicklook + ",\n" + "      \"thumbnail\": "
                + thumbnail + "\n" + "   },\n" + "   {\n" + "      \"identifier\": \"" + identifier + "\",\n"
                + "      \"link\": " + download + ",\n" + "      \"summary\": \"" + summary + "\",\n"
                + "      \"footprint\": " + footprintString + "\n" + "   },\n" + "   " + product.getId() + ",\n"
                + "   " + download + ",\n" + "   {\n" + "      \"id\": " + (canDownload ? product.getId() : null)
                + ",\n" + "      \"name\": \"" + identifier + "\",\n" + "      \"inUserCart\": "
                + (cart != null && cart.contains(product.getId())) + ",\n" + "      \"deletable\": " + deletable
                + "\n" + "   }\n]";
        return json;
    }

    public static String toJson(String base_url, List<ProductData> products, UserData user, int total) {
        String json = "{\"aaData\": [\n";

        Iterator<ProductData> it = products.iterator();
        while (it.hasNext()) {
            ProductData product = it.next();
            json += toJson(product, base_url, user) + (it.hasNext() ? ",\n" : "\n");
        }

        json += "],\"iTotalRecords\" : " + total + ", \"iTotalDisplayRecords\" : " + total + "}";

        return json;
    }
}