annis.gui.resultfetch.ResultFetchJob.java Source code

Java tutorial

Introduction

Here is the source code for annis.gui.resultfetch.ResultFetchJob.java

Source

/*
 * Copyright 2013 Corpuslinguistic working group Humboldt University Berlin.
 *
 * 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 annis.gui.resultfetch;

import annis.gui.SearchUI;
import annis.gui.objects.PagedResultQuery;
import annis.gui.paging.PagingComponent;
import annis.gui.resultview.ResultViewPanel;
import annis.libgui.Helper;
import annis.libgui.PollControl;
import annis.model.AqlParseError;
import annis.service.objects.Match;
import annis.service.objects.MatchGroup;
import annis.service.objects.SubgraphFilter;
import com.google.common.base.Joiner;
import com.sun.jersey.api.client.AsyncWebResource;
import com.sun.jersey.api.client.GenericType;
import com.sun.jersey.api.client.UniformInterfaceException;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.uri.UriComponent;
import de.hu_berlin.german.korpling.saltnpepper.salt.saltCommon.SaltProject;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import javax.ws.rs.core.MediaType;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A thread that queries for the matches, fetches the the subgraph for the
 * matches and updates the GUI at certain points.
 *
 * @author Thomas Krause <krauseto@hu-berlin.de>
 */
public class ResultFetchJob extends AbstractResultFetchJob implements Runnable {

    protected static final Logger log = LoggerFactory.getLogger(ResultFetchJob.class);

    protected ResultViewPanel resultPanel;

    private final Future<MatchGroup> futureMatches;

    protected AsyncWebResource res;

    protected PagedResultQuery query;

    protected SearchUI ui;

    public ResultFetchJob(PagedResultQuery query, ResultViewPanel resultPanel, SearchUI ui) {
        this.resultPanel = resultPanel;
        this.query = query;
        this.ui = ui;

        res = Helper.getAnnisAsyncWebResource();

        futureMatches = res.path("query").path("search").path("find")
                .queryParam("q", Helper.encodeJersey(query.getQuery())).queryParam("offset", "" + query.getOffset())
                .queryParam("limit", "" + query.getLimit())
                .queryParam("corpora", StringUtils.join(query.getCorpora(), ","))
                .queryParam("order", query.getOrder().toString()).accept(MediaType.APPLICATION_XML_TYPE)
                .get(MatchGroup.class);

    }

    @Override
    public void run() {
        WebResource subgraphRes = Helper.getAnnisWebResource().path("query/search/subgraph");

        // holds the ids of the matches.
        MatchGroup result;

        try {
            if (Thread.interrupted()) {
                return;
            }

            // set the the progress bar, for given the user some information about the loading process
            ui.accessSynchronously(new Runnable() {
                @Override
                public void run() {
                    resultPanel.showMatchSearchInProgress(query);
                }
            });

            // get the matches
            result = futureMatches.get();

            // get the subgraph for each match, when the result is not empty
            if (result.getMatches().isEmpty()) {

                // check if thread was interrupted
                if (Thread.interrupted()) {
                    return;
                }

                // nothing found, so inform the user about this.
                ui.access(new Runnable() {
                    @Override
                    public void run() {
                        resultPanel.showNoResult();
                    }
                });
            } else {
                if (Thread.interrupted()) {
                    return;
                }

                // since annis found something, inform the user that subgraphs are created
                ui.access(new Runnable() {
                    @Override
                    public void run() {
                        resultPanel.showSubgraphSearchInProgress(query, 0.0f);
                    }
                });

                // prepare fetching subgraphs
                final int totalResultSize = result.getMatches().size();

                final BlockingQueue<SaltProject> queue = new ArrayBlockingQueue<>(totalResultSize);
                int current = 0;

                for (Match m : result.getMatches()) {
                    if (Thread.interrupted()) {
                        return;
                    }

                    List<Match> subList = new LinkedList<>();
                    subList.add(m);
                    final SaltProject p = executeQuery(subgraphRes, new MatchGroup(subList), query.getLeftContext(),
                            query.getRightContext(), query.getSegmentation(), SubgraphFilter.all);

                    queue.put(p);
                    log.debug("added match {} to queue", current + 1);

                    if (current == 0) {
                        PollControl.changePollingTime(ui, PollControl.DEFAULT_TIME);
                        ui.access(new Runnable() {
                            @Override
                            public void run() {
                                resultPanel.setQueryResultQueue(queue, query, totalResultSize);
                            }
                        });
                    }

                    if (Thread.interrupted()) {
                        return;
                    }

                    current++;
                }
            } // end if no results

        } catch (InterruptedException ex) {
            // just return
        } catch (final ExecutionException root) {
            ui.accessSynchronously(new Runnable() {
                @Override
                public void run() {
                    if (resultPanel != null && resultPanel.getPaging() != null) {
                        PagingComponent paging = resultPanel.getPaging();
                        Throwable cause = root.getCause();
                        if (cause instanceof UniformInterfaceException) {
                            UniformInterfaceException ex = (UniformInterfaceException) cause;
                            if (ex.getResponse().getStatus() == 400) {
                                List<AqlParseError> errors = ex.getResponse()
                                        .getEntity(new GenericType<List<AqlParseError>>() {
                                        });
                                String errMsg = Joiner.on(" | ").join(errors);

                                paging.setInfo("parsing error: " + errMsg);
                            } else if (ex.getResponse().getStatus() == 504) {
                                paging.setInfo("Timeout: query exeuction took too long");
                            } else if (ex.getResponse().getStatus() == 403) {
                                paging.setInfo("Not authorized to query this corpus.");
                            } else {
                                paging.setInfo("unknown error: " + ex);
                            }
                        } else {
                            log.error("Unexcepted ExecutionException cause", root);
                        }

                        resultPanel.showFinishedSubgraphSearch();

                    }
                }
            });
        } // end catch
    }
}