gov.wa.wsdot.apps.analytics.client.activities.twitter.view.search.SearchView.java Source code

Java tutorial

Introduction

Here is the source code for gov.wa.wsdot.apps.analytics.client.activities.twitter.view.search.SearchView.java

Source

/*
 * Copyright (c) 2016 Washington State Department of Transportation
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 *
 */
package gov.wa.wsdot.apps.analytics.client.activities.twitter.view.search;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.http.client.URL;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.jsonp.client.JsonpRequestBuilder;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.web.bindery.event.shared.binder.EventBinder;
import com.google.web.bindery.event.shared.binder.EventHandler;
import gov.wa.wsdot.apps.analytics.client.ClientFactory;
import gov.wa.wsdot.apps.analytics.client.activities.events.SearchEvent;
import gov.wa.wsdot.apps.analytics.client.activities.twitter.view.tweet.TweetView;
import gov.wa.wsdot.apps.analytics.client.resources.Resources;
import gov.wa.wsdot.apps.analytics.shared.Mention;
import gov.wa.wsdot.apps.analytics.shared.Words;
import gov.wa.wsdot.apps.analytics.util.Consts;
import gwt.material.design.client.base.SearchObject;
import gwt.material.design.client.constants.IconType;
import gwt.material.design.client.ui.*;

import java.util.ArrayList;
import java.util.List;

public class SearchView extends Composite {

    interface MyEventBinder extends EventBinder<SearchView> {
    }

    private final MyEventBinder eventBinder = GWT.create(MyEventBinder.class);

    private static SearchViewUiBinder uiBinder = GWT.create(SearchViewUiBinder.class);

    interface SearchViewUiBinder extends UiBinder<Widget, SearchView> {
    }

    @UiField
    MaterialTextBox tweetSearch;

    @UiField
    MaterialIcon clearSearch;

    @UiField
    static MaterialPreLoader searchLoader;

    @UiField
    static HTMLPanel searchList;

    @UiField
    static MaterialButton moreSearchBtn;

    @UiField
    static MaterialButton backToSearchTopBtn;

    @UiField
    static MaterialLink advSearchLink;

    @UiField(provided = true)
    static AdvSearchView advSearch;

    @UiField
    static MaterialLink exportLink;

    final Resources res;

    private static final String JSON_URL_SUGGESTION = Consts.HOST_URL + "/search/suggest/";
    private static int pageNum = 1;
    private static String searchText = "";
    private static String url = "";

    private static ClientFactory clientFactory;

    public SearchView(ClientFactory clientFactory) {

        advSearch = new AdvSearchView(clientFactory);
        res = GWT.create(Resources.class);
        res.css().ensureInjected();
        eventBinder.bindEventHandlers(this, clientFactory.getEventBus());
        initWidget(uiBinder.createAndBindUi(this));
        this.clientFactory = clientFactory;
    }

    @UiHandler("advSearchLink")
    void onAdvSearch(ClickEvent e) {
        advSearch.open();
    }

    @UiHandler("tweetSearch")
    void onSearch(ValueChangeEvent<String> e) {
        SearchEvent searchEvent = new SearchEvent(tweetSearch.getValue());
        clientFactory.getEventBus().fireEvent(searchEvent);
    }

    @UiHandler("tweetSearch")
    void onKeyUp(KeyUpEvent e) {
        //getSuggestions(tweetSearch.getValue());
    }

    @UiHandler("clearSearch")
    void onClear(ClickEvent e) {
        tweetSearch.clear();
    }

    @UiHandler("exportLink")
    void onExport(ClickEvent e) {
        Window.open(url, "_blank", "");
    }

    @UiHandler("moreSearchBtn")
    public void onMore(ClickEvent e) {

        int nextPage = pageNum + 1;

        searchLoader.setVisible(true);

        JsonpRequestBuilder jsonp = new JsonpRequestBuilder();
        // Set timeout for 30 seconds (30000 milliseconds)
        jsonp.setTimeout(30000);
        jsonp.requestObject(url + nextPage, new AsyncCallback<Mention>() {

            @Override
            public void onFailure(Throwable caught) {
                Window.alert("Failure: " + caught.getMessage());
                searchLoader.setVisible(false);
            }

            @Override
            public void onSuccess(Mention mention) {
                if (mention.getMentions() != null) {
                    pageNum++;
                    updateSearch(mention.getMentions());
                    searchLoader.setVisible(false);
                }
            }
        });
    }

    @UiHandler("backToSearchTopBtn")
    public void onBackToTop(ClickEvent e) {
        Window.scrollTo(0, 0);
    }

    @EventHandler
    void onSearch(SearchEvent e) {
        pageNum = 1;
        backToSearchTopBtn.setVisible(false);
        searchText = e.getSearchText();
        searchList.clear();
        moreSearchBtn.setVisible(false);
        exportLink.setVisible(false);

        tweetSearch.setText(e.getSearchText());

        String url = getUrl(e);

        searchLoader.setVisible(true);

        JsonpRequestBuilder jsonp = new JsonpRequestBuilder();
        // Set timeout for 30 seconds (30000 milliseconds)
        jsonp.setTimeout(30000);
        jsonp.requestObject(url + pageNum, new AsyncCallback<Mention>() {

            @Override
            public void onFailure(Throwable caught) {
                Window.alert("Failure: " + caught.getMessage());
                searchLoader.setVisible(false);
            }

            @Override
            public void onSuccess(Mention mention) {
                if (mention.getMentions() != null) {
                    updateSearch(mention.getMentions());
                    searchLoader.setVisible(false);
                }
            }
        });
    }

    /**
     * Constructs a url for searching tweets
     *
     * the url has the form:
     *
     *  HOST_URL/search/:text/:screenName/:collection/:fromYear/:fromMonth/:fromDay/:toYear/:toMonth/:toDay/:page
     *
     * @param e
     * @return
     */
    private static String getUrl(SearchEvent e) {

        searchText = e.getSearchText();

        searchText = URL.encodePathSegment(searchText);

        url = Consts.HOST_URL + "/search/" + searchText + "/";

        url = url + e.getAccount() + "/" + ((e.getSearchType() == 2) ? "mentions" : "statuses");

        url = url + "/" + e.getMediaOnly();

        if (e.getStartDate() != null && e.getEndDate() != null) {
            url = url + e.getStartDate() + e.getEndDate() + "/";
        } else if (e.getEndDate() != null) {
            url = url + "/0/0/0" + e.getEndDate() + "/";
        } else if (e.getStartDate() != null) {
            url = url + e.getStartDate() + "/0/0/0/";
        } else {
            url = url + "/0/0/0/0/0/0/";
        }

        return url;
    }

    public static void updateSearch(JsArray<Mention> asArrayOfMentionData) {

        int j = asArrayOfMentionData.length();

        if (j > 24) {
            backToSearchTopBtn.setVisible(true);
        }

        DateTimeFormat dateTimeFormat = DateTimeFormat.getFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
        DateTimeFormat dateTimeFormat2 = DateTimeFormat.getFormat("MMMM dd, yyyy h:mm:ss a");

        String urlPattern = "(https?:\\/\\/[-a-zA-Z0-9._~:\\/?#@!$&\'()*+,;=%]+)";
        String atPattern = "@+([_a-zA-Z0-9-]+)";
        String hashPattern = "#+([_a-zA-Z0-9-]+)";
        String text;
        String updatedText;
        String screenName;
        String mediaUrl;

        for (int i = 0; i < j; i++) {

            screenName = (asArrayOfMentionData.get(i).getFromUser() != null)
                    ? asArrayOfMentionData.get(i).getFromUser()
                    : asArrayOfMentionData.get(i).getUser().getScreenName();

            TweetView tweet;

            text = asArrayOfMentionData.get(i).getText();
            updatedText = text.replaceAll(urlPattern, "<a href=\"$1\" target=\"_blank\">$1</a>");
            updatedText = updatedText.replaceAll(atPattern,
                    "<a href=\"http://twitter.com/#!/$1\" target=\"_blank\">@$1</a>");
            updatedText = updatedText.replaceAll(hashPattern,
                    "<a href=\"http://twitter.com/#!/search?q=%23$1\" target=\"_blank\">#$1</a>");

            String createdAt = dateTimeFormat2
                    .format(dateTimeFormat.parse(asArrayOfMentionData.get(i).getCreatedAt()));

            String link = "http://twitter.com/#!/" + screenName + "/status/"
                    + asArrayOfMentionData.get(i).getIdStr();

            mediaUrl = null;
            try {
                for (int k = 0; k < asArrayOfMentionData.get(i).getEntities().getMedia().length(); k++) {
                    mediaUrl = asArrayOfMentionData.get(i).getEntities().getMedia().get(k).getMediaUrl();
                }
            } catch (Exception e) {
            } // Image preview is nice, but if it fails...oh well.

            String id = asArrayOfMentionData.get(i).getIdStr();

            if (asArrayOfMentionData.get(i).getSentiment().equals("positive")) {
                tweet = new TweetView(id, screenName, updatedText, createdAt, link, mediaUrl,
                        IconType.SENTIMENT_SATISFIED);
            } else if (asArrayOfMentionData.get(i).getSentiment().equals("negative")) {
                tweet = new TweetView(id, screenName, updatedText, createdAt, link, mediaUrl,
                        IconType.SENTIMENT_DISSATISFIED);
            } else {
                tweet = new TweetView(id, screenName, updatedText, createdAt, link, mediaUrl,
                        IconType.SENTIMENT_NEUTRAL);
            }
            searchList.add(tweet);
        }

        if (j > 0) {
            exportLink.setVisible(true);
        }

        if (j < 25) {
            moreSearchBtn.setVisible(false);
        } else {
            moreSearchBtn.setVisible(true);
        }
    }

    public void getSuggestions(String searchText) {
        String url = JSON_URL_SUGGESTION;
        String searchString = SafeHtmlUtils.htmlEscape(searchText.trim().replace("'", ""));

        // Append the name of the callback function to the JSON URL.
        url += searchString;
        url = URL.encode(url);
        JsonpRequestBuilder jsonp = new JsonpRequestBuilder();
        // Set timeout for 30 seconds (30000 milliseconds)
        jsonp.setTimeout(30000);
        jsonp.requestObject(url, new AsyncCallback<Words>() {

            @Override
            public void onFailure(Throwable caught) {
                // Just fail silently here.
            }

            @Override
            public void onSuccess(Words words) {
                if (words.getWords() != null) {

                    List<SearchObject> searchHints = new ArrayList<SearchObject>();

                    for (int i = 0; i < words.getWords().length(); i++) {
                        SearchObject search = new SearchObject();
                        search.setKeyword(words.getWords().get(i));
                        searchHints.add(search);
                    }

                    updateSuggestions(searchHints);
                }
            }
        });
    }

    public void updateSuggestions(List<SearchObject> suggestions) {

    }
}