Java tutorial
/* * Copyright 2012 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.frequency; import annis.gui.components.FrequencyChart; import annis.gui.objects.FrequencyQuery; import annis.libgui.Helper; import annis.service.objects.FrequencyTable; import annis.service.objects.FrequencyTableEntry; import annis.service.objects.FrequencyTableEntryType; import au.com.bytecode.opencsv.CSVWriter; import com.google.common.base.Charsets; import com.google.common.base.Joiner; import com.google.common.collect.Ordering; import com.vaadin.data.Container; import com.vaadin.data.util.AbstractBeanContainer; import com.vaadin.data.util.DefaultItemSorter; import com.vaadin.data.util.IndexedContainer; import com.vaadin.data.util.ItemSorter; import com.vaadin.server.FileDownloader; import com.vaadin.server.FontAwesome; import com.vaadin.server.StreamResource; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.Table; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.themes.ValoTheme; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.Serializable; import java.io.Writer; import java.text.Collator; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.ListIterator; import java.util.Locale; import org.slf4j.LoggerFactory; /** * * @author Thomas Krause <krauseto@hu-berlin.de> */ public class FrequencyResultPanel extends VerticalLayout { private static final org.slf4j.Logger log = LoggerFactory.getLogger(FrequencyResultPanel.class); public static final int MAX_NUMBER_OF_CHART_ITEMS = 100; private Table tblResult; private final Button btDownloadCSV; private final FrequencyChart chart; private final FrequencyQueryPanel queryPanel; private final FrequencyQuery query; public FrequencyResultPanel(FrequencyTable table, FrequencyQuery query, FrequencyQueryPanel queryPanel) { this.query = query; this.queryPanel = queryPanel; setSizeFull(); chart = new FrequencyChart(this); chart.setHeight("350px"); chart.setVisible(false); addComponent(chart); btDownloadCSV = new Button("Download as CSV"); btDownloadCSV.setDescription("Download as CSV"); btDownloadCSV.setSizeUndefined(); addComponent(btDownloadCSV); setComponentAlignment(btDownloadCSV, Alignment.TOP_RIGHT); btDownloadCSV.setVisible(false); btDownloadCSV.setIcon(FontAwesome.DOWNLOAD); btDownloadCSV.addStyleName(ValoTheme.BUTTON_SMALL); showResult(table); } private void showResult(FrequencyTable table) { if (queryPanel != null) { queryPanel.notifiyQueryFinished(); } recreateTable(table); btDownloadCSV.setVisible(true); FileDownloader downloader = new FileDownloader( new StreamResource(new CSVResource(table, query.getFrequencyDefinition()), "frequency.txt")); downloader.extend(btDownloadCSV); chart.setVisible(true); FrequencyTable clippedTable = table; if (clippedTable.getEntries().size() > MAX_NUMBER_OF_CHART_ITEMS) { List<FrequencyTable.Entry> entries = new ArrayList<>(clippedTable.getEntries()); clippedTable = new FrequencyTable(); clippedTable.setEntries(entries.subList(0, MAX_NUMBER_OF_CHART_ITEMS)); clippedTable.setSum(table.getSum()); chart.setCaption("Showing historgram of top " + MAX_NUMBER_OF_CHART_ITEMS + " results, see table below for complete dataset."); } chart.setFrequencyData(clippedTable); } private String createFieldsString() { StringBuilder sb = new StringBuilder(); ListIterator<FrequencyTableEntry> it = query.getFrequencyDefinition().listIterator(); while (it.hasNext()) { FrequencyTableEntry e = it.next(); sb.append(e.getReferencedNode()).append(":"); if (e.getType() == FrequencyTableEntryType.span) { sb.append("tok"); } else { sb.append(e.getKey()); } if (it.hasNext()) { sb.append(","); } } return sb.toString(); } private void recreateTable(FrequencyTable table) { if (tblResult != null) { removeComponent(tblResult); } tblResult = new Table(); tblResult.setSizeFull(); tblResult.setCaption(table.getEntries().size() + " items with a total sum of " + table.getSum() + " (query on " + Joiner.on(", ").join(query.getCorpora()) + ")"); tblResult.setSelectable(true); tblResult.setMultiSelect(false); tblResult.addStyleName(Helper.CORPUS_FONT_FORCE); if (!table.getEntries().isEmpty()) { FrequencyTable.Entry firstEntry = table.getEntries().iterator().next(); int tupelCount = firstEntry.getTupel().length; tblResult.addContainerProperty("rank", Integer.class, -1); for (int i = 1; i <= tupelCount; i++) { tblResult.addContainerProperty("tupel-" + i, String.class, ""); FrequencyTableEntry e = query.getFrequencyDefinition().get(i - 1); tblResult.setColumnHeader("tupel-" + i, getCaption(e)); } tblResult.addContainerProperty("count", Long.class, -1l); int line = 0; for (FrequencyTable.Entry e : table.getEntries()) { Object[] cells = new Object[tupelCount + 2]; System.arraycopy(e.getTupel(), 0, cells, 1, tupelCount); cells[0] = line + 1; cells[cells.length - 1] = e.getCount(); tblResult.addItem(cells, "entry-" + line++); } } addLexicalSort(tblResult.getContainerDataSource()); addComponent(tblResult); setExpandRatio(tblResult, 1.0f); } private void addLexicalSort(Container container) { ItemSorter sorter = new DefaultItemSorter(new IgnoreCaseComparator()); if (container instanceof IndexedContainer) { ((IndexedContainer) container).setItemSorter(sorter); } else if (container instanceof AbstractBeanContainer) { ((AbstractBeanContainer) container).setItemSorter(sorter); } } public static class IgnoreCaseComparator implements Comparator<Object>, Serializable { @Override @SuppressWarnings("unchecked") public int compare(Object o1, Object o2) { if (o1 instanceof String && o2 instanceof String) { String s1 = (String) o1; String s2 = (String) o2; Collator collator = Collator.getInstance(Locale.ENGLISH); collator.setStrength(Collator.PRIMARY); return collator.compare(s1, s2); } else { return Ordering.natural().compare((Comparable) o1, (Comparable) o2); } } } public static String getCaption(FrequencyTableEntry e) { String caption; switch (e.getType()) { case annotation: caption = "#" + e.getReferencedNode() + "|" + e.getKey(); break; case span: caption = "#" + e.getReferencedNode() + "|spanned text"; break; case meta: caption = "meta|" + e.getKey(); break; default: caption = "<unknown>"; } return caption; } public static class CSVResource implements StreamResource.StreamSource { private final FrequencyTable data; private final List<FrequencyTableEntry> freqDefinition; public CSVResource(FrequencyTable data, List<FrequencyTableEntry> freqDefinition) { this.data = data; this.freqDefinition = freqDefinition; } @Override public InputStream getStream() { try { File tmpFile = File.createTempFile("annis-frequency", ".txt"); tmpFile.deleteOnExit(); try (Writer writer = new OutputStreamWriter(new FileOutputStream(tmpFile), Charsets.UTF_8)) { CSVWriter csv = new CSVWriter(writer, '\t', CSVWriter.NO_QUOTE_CHARACTER, '\\'); // write headers ArrayList<String> header = new ArrayList<>(); if (data.getEntries().size() > 0) { for (int i = 0; i < data.getEntries().iterator().next().getTupel().length; i++) { FrequencyTableEntry e = freqDefinition.get(i); header.add(getCaption(e)); } } // add count header.add("count"); csv.writeNext(header.toArray(new String[0])); // write entries for (FrequencyTable.Entry e : data.getEntries()) { ArrayList<String> d = new ArrayList<>(); d.addAll(Arrays.asList(e.getTupel())); d.add("" + e.getCount()); csv.writeNext(d.toArray(new String[0])); } } return new FileInputStream(tmpFile); } catch (IOException ex) { log.error(null, ex); } return new ByteArrayInputStream(new byte[0]); } } public void selectRow(int i) { tblResult.setValue("entry-" + i); tblResult.setCurrentPageFirstItemId("entry-" + i); } }