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