Java tutorial
/* * Copyright 2011 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.resultview; import annis.CommonHelper; import annis.libgui.Helper; import annis.libgui.InstanceConfig; import annis.libgui.PluginSystem; import annis.resolver.ResolverEntry; import annis.resolver.ResolverEntry.ElementType; import annis.resolver.SingleResolverRequest; import annis.service.objects.Match; import annis.service.objects.SaltURIGroup; import annis.service.objects.SaltURIGroupSet; import annis.service.objects.SubgraphQuery; import com.sun.jersey.api.client.ClientHandlerException; import com.sun.jersey.api.client.GenericType; import com.sun.jersey.api.client.UniformInterfaceException; import com.sun.jersey.api.client.WebResource; import com.vaadin.server.VaadinSession; import com.vaadin.ui.*; import com.vaadin.ui.themes.ChameleonTheme; import de.hu_berlin.german.korpling.saltnpepper.salt.saltCommon.SaltProject; import de.hu_berlin.german.korpling.saltnpepper.salt.saltCommon.sCorpusStructure.SCorpusGraph; import de.hu_berlin.german.korpling.saltnpepper.salt.saltCommon.sCorpusStructure.SDocument; import de.hu_berlin.german.korpling.saltnpepper.salt.saltCore.SLayer; import de.hu_berlin.german.korpling.saltnpepper.salt.saltCore.SNode; import de.hu_berlin.german.korpling.saltnpepper.salt.saltCore.SRelation; import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.net.URLEncoder; import java.util.*; import java.util.concurrent.*; import org.slf4j.LoggerFactory; /** * * @author thomas */ public class ResultSetPanel extends Panel implements ResolverProvider { private static final org.slf4j.Logger log = LoggerFactory.getLogger(ResultSetPanel.class); private Map<HashSet<SingleResolverRequest>, List<ResolverEntry>> cacheResolver; public static final String FILESYSTEM_CACHE_RESULT = "ResultSetPanel_FILESYSTEM_CACHE_RESULT"; private List<SingleResultPanel> resultPanelList; private PluginSystem ps; private String segmentationName; private int firstMatchOffset; private int contextLeft; private int contextRight; private ResultViewPanel parent; private List<Match> matches; private Set<String> tokenAnnotationLevelSet = Collections.synchronizedSet(new TreeSet<String>()); private Set<String> segmentationLayerSet = Collections.synchronizedSet(new TreeSet<String>()); private ProgressIndicator indicator; private VerticalLayout indicatorLayout; private CssLayout layout; private InstanceConfig instanceConfig; public ResultSetPanel(List<Match> matches, PluginSystem ps, InstanceConfig instanceConfig, int contextLeft, int contextRight, String segmentationName, ResultViewPanel parent, int firstMatchOffset) { this.ps = ps; this.segmentationName = segmentationName; this.contextLeft = contextLeft; this.contextRight = contextRight; this.parent = parent; this.matches = Collections.synchronizedList(matches); this.firstMatchOffset = firstMatchOffset; this.instanceConfig = instanceConfig; resultPanelList = Collections.synchronizedList(new LinkedList<SingleResultPanel>()); cacheResolver = Collections .synchronizedMap(new HashMap<HashSet<SingleResolverRequest>, List<ResolverEntry>>()); setSizeFull(); layout = new CssLayout(); setContent(layout); layout.addStyleName("result-view-css"); addStyleName(ChameleonTheme.PANEL_BORDERLESS); addStyleName("result-view"); indicatorLayout = new VerticalLayout(); indicator = new ProgressIndicator(); indicator.setIndeterminate(false); indicator.setValue(0f); indicator.setPollingInterval(250); indicator.setSizeUndefined(); indicatorLayout.addComponent(indicator); indicatorLayout.setWidth("100%"); indicatorLayout.setHeight("-1px"); indicatorLayout.setComponentAlignment(indicator, Alignment.TOP_CENTER); indicatorLayout.setVisible(true); layout.addComponent(indicatorLayout); // enable indicator in order to get refresh GUI regulary indicator.setEnabled(true); ExecutorService singleExecutor = Executors.newSingleThreadExecutor(); Callable<Boolean> run = new AllResultsFetcher(); FutureTask<Boolean> task = new FutureTask<Boolean>(run) { @Override protected void done() { VaadinSession session = VaadinSession.getCurrent(); session.lock(); try { indicator.setEnabled(false); indicator.setVisible(false); indicatorLayout.setVisible(false); } finally { session.unlock(); } } }; singleExecutor.submit(task); } private void addQueryResult(SaltProject p, int offset) { List<SingleResultPanel> newPanels = new LinkedList<SingleResultPanel>(); try { if (p == null) { Notification.show("Could not get subgraphs", Notification.Type.TRAY_NOTIFICATION); } else { updateVariables(p); newPanels = createPanels(p, offset); } } catch (Exception ex) { log.error(null, ex); } for (SingleResultPanel panel : newPanels) { resultPanelList.add(panel); layout.addComponent(panel); } } private void updateVariables(SaltProject p) { segmentationLayerSet.addAll(CommonHelper.getOrderingTypes(p)); tokenAnnotationLevelSet.addAll(CommonHelper.getTokenAnnotationLevelSet(p)); parent.updateSegmentationLayer(segmentationLayerSet); parent.updateTokenAnnos(tokenAnnotationLevelSet); } private List<SingleResultPanel> createPanels(SaltProject p, int offset) { List<SingleResultPanel> result = new LinkedList<SingleResultPanel>(); int i = 0; for (SCorpusGraph corpusGraph : p.getSCorpusGraphs()) { SingleResultPanel panel = new SingleResultPanel(corpusGraph.getSDocuments().get(0), i + offset, this, ps, tokenAnnotationLevelSet, segmentationName, instanceConfig); i++; panel.setWidth("100%"); panel.setHeight("-1px"); result.add(panel); } return result; } @Override public ResolverEntry[] getResolverEntries(SDocument doc) { HashSet<ResolverEntry> visSet = new HashSet<ResolverEntry>(); // create a request for resolver entries HashSet<SingleResolverRequest> resolverRequests = new HashSet<SingleResolverRequest>(); Set<String> nodeLayers = new HashSet<String>(); for (SNode n : doc.getSDocumentGraph().getSNodes()) { for (SLayer layer : n.getSLayers()) { nodeLayers.add(layer.getSName()); } } Set<String> edgeLayers = new HashSet<String>(); for (SRelation e : doc.getSDocumentGraph().getSRelations()) { for (SLayer layer : e.getSLayers()) { try { edgeLayers.add(layer.getSName()); } catch (NullPointerException ex) { log.warn("NullPointerException when using Salt, was trying to get layer name", ex); } } } for (String ns : nodeLayers) { resolverRequests.add(new SingleResolverRequest(doc.getSCorpusGraph().getSRootCorpus().get(0).getSName(), ns, ElementType.node)); } for (String ns : edgeLayers) { resolverRequests.add(new SingleResolverRequest(doc.getSCorpusGraph().getSRootCorpus().get(0).getSName(), ns, ElementType.edge)); } // query with this resolver request and make sure it is unique if (cacheResolver.containsKey(resolverRequests)) { visSet.addAll(cacheResolver.get(resolverRequests)); } else { List<ResolverEntry> resolverList = new LinkedList<ResolverEntry>(); WebResource resResolver = Helper.getAnnisWebResource().path("query").path("resolver"); for (SingleResolverRequest r : resolverRequests) { List<ResolverEntry> tmp; try { String corpusName = URLEncoder.encode(r.getCorpusName(), "UTF-8"); String namespace = r.getNamespace(); String type = r.getType() == null ? null : r.getType().toString(); if (corpusName != null && namespace != null && type != null) { WebResource res = resResolver.path(corpusName).path(namespace).path(type); try { tmp = res.get(new ResolverEntryListType()); resolverList.addAll(tmp); } catch (Exception ex) { log.error("could not query resolver entries: " + res.toString(), ex); } } } catch (UniformInterfaceException ex) { log.error(null, ex); } catch (ClientHandlerException ex) { log.error(null, ex); } catch (UnsupportedEncodingException ex) { log.error(null, ex); } } visSet.addAll(resolverList); cacheResolver.put(resolverRequests, resolverList); } // sort everything ResolverEntry[] visArray = visSet.toArray(new ResolverEntry[visSet.size()]); Arrays.sort(visArray, new ResolverEntryComparator()); return visArray; } public void setSegmentationLayer(String segmentationLayer) { for (SingleResultPanel p : resultPanelList) { p.setSegmentationLayer(segmentationLayer); } } public void setVisibleTokenAnnosVisible(Set<String> annos) { for (SingleResultPanel p : resultPanelList) { p.setVisibleTokenAnnosVisible(annos); } } public class AllResultsFetcher implements Callable<Boolean> { public AllResultsFetcher() { } private SaltProject executeQuery(WebResource subgraphRes, SubgraphQuery query) { SaltProject p = null; try { p = subgraphRes.post(SaltProject.class, query); } catch (UniformInterfaceException ex) { log.error(ex.getMessage(), ex); } return p; } private SubgraphQuery prepareQuery(List<Match> matchesToPrepare) { SubgraphQuery query = new SubgraphQuery(); query.setLeft(contextLeft); query.setRight(contextRight); if (segmentationName != null) { query.setSegmentationLayer(segmentationName); } SaltURIGroupSet saltURIs = new SaltURIGroupSet(); ListIterator<Match> it = matchesToPrepare.listIterator(); int i = 0; while (it.hasNext()) { Match m = it.next(); SaltURIGroup urisForMatch = new SaltURIGroup(); for (String s : m.getSaltIDs()) { try { urisForMatch.getUris().add(new URI(s)); } catch (URISyntaxException ex) { log.error(null, ex); } } saltURIs.getGroups().put(++i, urisForMatch); } query.setMatches(saltURIs); return query; } @Override public Boolean call() throws Exception { boolean allSuccessfull = true; WebResource res = Helper.getAnnisWebResource(); if (res != null) { res = res.path("query/search/subgraph"); int j = 0; SaltProject lastProject = null; for (Match m : matches) { List<Match> sub = new LinkedList<Match>(); sub.add(m); SubgraphQuery query = prepareQuery(sub); if (query.getMatches().getGroups().size() > 0) { SaltProject p = executeQuery(res, query); if (p != null) { lastProject = p; } } else { allSuccessfull = false; } VaadinSession session = VaadinSession.getCurrent(); session.lock(); try { if (lastProject != null) { addQueryResult(lastProject, j + firstMatchOffset); } indicator.setValue((float) j++ / (float) matches.size()); if (j == matches.size()) { indicator.setValue(1.0f); } } catch (Exception ex) { log.error("Exception when adding query result", ex); } finally { session.unlock(); } } } return allSuccessfull; } } // end class AllResultsFetcher private static class ResolverEntryListType extends GenericType<List<ResolverEntry>> { public ResolverEntryListType() { } } private static class ResolverEntryComparator implements Comparator<ResolverEntry>, Serializable { public ResolverEntryComparator() { } @Override public int compare(ResolverEntry o1, ResolverEntry o2) { if (o1.getOrder() < o2.getOrder()) { return -1; } else if (o1.getOrder() > o2.getOrder()) { return 1; } else { return 0; } } } }