Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2014 SFB 632.
*
* 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.visualizers.component.grid;
import annis.CommonHelper;
import annis.gui.widgets.grid.AnnotationGrid;
import annis.gui.widgets.grid.GridEvent;
import annis.gui.widgets.grid.Row;
import annis.libgui.Helper;
import annis.libgui.media.MediaController;
import annis.libgui.media.PDFController;
import annis.libgui.visualizers.VisualizerInput;
import annis.model.AnnisConstants;
import static annis.model.AnnisConstants.ANNIS_NS;
import static annis.model.AnnisConstants.FEAT_MATCHEDNODE;
import annis.model.RelannisNodeFeature;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.vaadin.ui.Label;
import com.vaadin.ui.Panel;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.themes.ChameleonTheme;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;
import org.corpus_tools.salt.common.SDocumentGraph;
import org.corpus_tools.salt.common.SSpan;
import org.corpus_tools.salt.common.STextualDS;
import org.corpus_tools.salt.common.SToken;
import org.corpus_tools.salt.core.SAnnotation;
import org.corpus_tools.salt.core.SFeature;
import org.corpus_tools.salt.core.SNode;
import org.eclipse.emf.common.util.EList;
import org.slf4j.LoggerFactory;
/**
*
* @author Thomas Krause
*/
public class GridComponent extends Panel
{
private static final org.slf4j.Logger log
= LoggerFactory.getLogger(GridComponent.class);
public static final String MAPPING_ANNOS_KEY = "annos";
public static final String MAPPING_ANNO_REGEX_KEY = "anno_regex";
public static final String MAPPING_HIDE_TOK_KEY = "hide_tok";
public static final String MAPPING_TOK_ANNOS_KEY = "tok_anno";
public static final String MAPPING_ESCAPE_HTML = "escape_html";
public static final String MAPPING_SHOW_NAMESPACE = "show_ns";
private AnnotationGrid grid;
private final transient VisualizerInput input;
private final transient MediaController mediaController;
private final transient PDFController pdfController;
private final VerticalLayout layout;
private Set manuallySelectedTokenAnnos;
private String segmentationName;
private final transient STextualDS enforcedText;
private final Label lblEmptyToken;
public enum ElementType
{
begin, end, middle, single, noEvent
}
public GridComponent(VisualizerInput input, MediaController mediaController,
PDFController pdfController, boolean forceToken, STextualDS enforcedText)
{
this.input = input;
this.mediaController = mediaController;
this.pdfController = pdfController;
this.enforcedText = enforcedText;
setWidth("100%");
setHeight("-1");
layout = new VerticalLayout();
setContent(layout);
layout.setSizeUndefined();
addStyleName(ChameleonTheme.PANEL_BORDERLESS);
lblEmptyToken = new Label("(Empty token list, you may want to select another base text from the menu above.)");
lblEmptyToken.setVisible(false);
lblEmptyToken.addStyleName("empty_token_hint");
layout.addComponent(lblEmptyToken);
if (input != null)
{
this.manuallySelectedTokenAnnos = input.getVisibleTokenAnnos();
this.segmentationName = forceToken ? null : input.getSegmentationName();
List texts
= input.getDocument().getDocumentGraph().getTextualDSs();
if (texts != null && texts.size() > 0 && !Helper.isRTLDisabled())
{
if (CommonHelper.containsRTLText(texts.get(0).getText()))
{
addStyleName("rtl");
}
}
createAnnotationGrid();
} // end if input not null
}
private void createAnnotationGrid()
{
String resultID = input.getId();
grid = new AnnotationGrid(mediaController, pdfController, resultID);
grid.addStyleName(getMainStyle());
grid.addStyleName(Helper.CORPUS_FONT_FORCE);
grid.setEscapeHTML(Boolean.parseBoolean(input.getMappings().
getProperty(MAPPING_ESCAPE_HTML, "true")));
LinkedList> types = new LinkedList<>();
if(isShowingSpanAnnotations())
{
types.add(SSpan.class);
}
if(isShowingTokenAnnotations())
{
types.add(SToken.class);
}
grid.setAnnosWithNamespace(EventExtractor.computeDisplayedNamespace(input, types));
layout.addComponent(grid);
SDocumentGraph graph = input.getDocument().getDocumentGraph();
List tokens = CommonHelper.getSortedSegmentationNodes(segmentationName,
graph);
Preconditions.checkArgument(!tokens.isEmpty(), "Token list must be non-empty");
RelannisNodeFeature featTokStart
= (RelannisNodeFeature) tokens.get(0).
getFeature(AnnisConstants.ANNIS_NS, AnnisConstants.FEAT_RELANNIS_NODE).
getValue();
long startIndex = featTokStart.getTokenIndex();
RelannisNodeFeature featTokEnd
= (RelannisNodeFeature) tokens.get(tokens.size() - 1).
getFeature(AnnisConstants.ANNIS_NS, AnnisConstants.FEAT_RELANNIS_NODE).
getValue();
long endIndex = featTokEnd.getTokenIndex();
LinkedHashMap> rowsByAnnotation =
computeAnnotationRows(startIndex, endIndex);
// add tokens as row
AtomicInteger tokenOffsetForText = new AtomicInteger(-1);
Row tokenRow = computeTokenRow(tokens, graph,
rowsByAnnotation, startIndex, tokenOffsetForText);
if (isHidingToken() == false)
{
if(isTokenFirst())
{
// copy original list but add token row at the beginning
LinkedHashMap> newList = new LinkedHashMap<>();
newList.put("tok", Lists.newArrayList(tokenRow));
newList.putAll(rowsByAnnotation);
rowsByAnnotation = newList;
}
else
{
// just add the token row to the end of the list
rowsByAnnotation.put("tok", Lists.newArrayList(tokenRow));
}
}
EventExtractor.removeEmptySpace(rowsByAnnotation, tokenRow);
// check if the token row only contains empty values
boolean tokenRowIsEmpty = true;
for(GridEvent tokenEvent : tokenRow.getEvents())
{
if(tokenEvent.getValue() != null && !tokenEvent.getValue().trim().isEmpty())
{
tokenRowIsEmpty = false;
break;
}
}
if(!isHidingToken() && canShowEmptyTokenWarning())
{
lblEmptyToken.setVisible(tokenRowIsEmpty);
}
grid.setRowsByAnnotation(rowsByAnnotation);
grid.setTokenIndexOffset(tokenOffsetForText.get());
}
private Row computeTokenRow(List tokens,
SDocumentGraph graph, LinkedHashMap> rowsByAnnotation,
long startIndex, AtomicInteger tokenOffsetForText)
{
/* we will only add tokens of one texts which is mentioned by any
included annotation. */
Set validTextIDs = new HashSet<>();
if(enforcedText == null)
{
Iterator> itAllRows = rowsByAnnotation.values().iterator();
while (itAllRows.hasNext())
{
ArrayList rowsForAnnotation = itAllRows.next();
for (Row r : rowsForAnnotation)
{
validTextIDs.addAll(r.getTextIDs());
}
}
/**
* we want to show all token if no valid text was found and we have only one
* text and the first one if there are more than one text.
*/
List allTexts = graph.getTextualDSs();
if (validTextIDs.isEmpty() && allTexts != null && (allTexts.size() == 1
|| allTexts.size() == 2))
{
validTextIDs.add(allTexts.get(0).getId());
}
}
else
{
validTextIDs.add(enforcedText.getId());
}
Row tokenRow = new Row();
for (SNode t : tokens)
{
// get the Salt ID of the STextualDS of this token
STextualDS tokenText = CommonHelper.getTextualDSForNode(t, graph);
// only add token if text ID matches the valid one
if (tokenText != null && validTextIDs.contains(tokenText.getId()))
{
RelannisNodeFeature feat
= (RelannisNodeFeature) t.getFeature(AnnisConstants.ANNIS_NS,
AnnisConstants.FEAT_RELANNIS_NODE).getValue();
long idxLeft = feat.getLeftToken() - startIndex;
long idxRight = feat.getRightToken() - startIndex;
if (tokenOffsetForText.get() < 0)
{
// set the token offset by assuming the first idx must be zero
tokenOffsetForText.set(Math.abs((int) idxLeft));
}
String text = extractTextForToken(t, segmentationName);
GridEvent event
= new GridEvent(t.getId(), (int) idxLeft, (int) idxRight, text);
event.setTextID(tokenText.getId());
// check if the token is a matched node
Long match = isCoveredTokenMarked() ?
markCoveredTokens(input.getMarkedAndCovered(), t) : tokenMatch(t);
event.setMatch(match);
tokenRow.addEvent(event);
}
} // end token row
return tokenRow;
}
private String extractTextForToken(SNode t, String segmentation)
{
if(t instanceof SToken)
{
return CommonHelper.getSpannedText((SToken) t);
}
else if(segmentation != null)
{
for(SAnnotation anno : t.getAnnotations())
{
if(anno.getName().equals(segmentation))
{
return anno.getValue_STEXT();
}
}
}
return "";
}
private LinkedHashMap> computeAnnotationRows(
long startIndex, long endIndex)
{
List annos = new LinkedList<>();
boolean showSpanAnnotations = isShowingSpanAnnotations();
if(showSpanAnnotations)
{
annos.addAll(EventExtractor.computeDisplayAnnotations(input, SSpan.class));
}
boolean showTokenAnnotations = isShowingTokenAnnotations();
if (showTokenAnnotations)
{
List tokenAnnos
= EventExtractor.computeDisplayAnnotations(input, SToken.class);
if(manuallySelectedTokenAnnos != null)
{
tokenAnnos.retainAll(manuallySelectedTokenAnnos);
}
annos.addAll(tokenAnnos);
}
// search for media annotations
Set mediaAnnotations = null;
if(isFilteringMediaLayer())
{
mediaAnnotations = new HashSet<>();
Pattern patternMedia = Pattern.compile("(annis::)?time");
for (String qname : annos)
{
if(patternMedia.matcher(qname).matches())
{
mediaAnnotations.add(qname);
}
}
}
LinkedHashMap> rowsByAnnotation
= EventExtractor.parseSalt(input, showSpanAnnotations,
showTokenAnnotations, annos, mediaAnnotations, isAddingPlaybackRow(),
(int) startIndex, (int) endIndex, pdfController, enforcedText);
return rowsByAnnotation;
}
public void setVisibleTokenAnnos(Set annos)
{
this.manuallySelectedTokenAnnos = annos;
// complete recreation of the grid
layout.removeComponent(grid);
createAnnotationGrid();
}
public void setSegmentationLayer(String segmentationName,
Map markedAndCovered)
{
this.segmentationName = segmentationName;
this.input.setMarkedAndCovered(markedAndCovered);
// complete recreation of the grid
layout.removeComponent(grid);
createAnnotationGrid();
}
protected boolean isShowingTokenAnnotations()
{
return Boolean.parseBoolean(input.getMappings().
getProperty(MAPPING_TOK_ANNOS_KEY));
}
protected boolean isShowingSpanAnnotations()
{
return true;
}
protected boolean isHidingToken()
{
return Boolean.parseBoolean(input.getMappings().
getProperty(MAPPING_HIDE_TOK_KEY, "false"));
}
protected boolean isTokenFirst()
{
return false;
}
protected boolean isFilteringMediaLayer()
{
return false;
}
protected boolean isAddingPlaybackRow()
{
return false;
}
protected boolean canShowEmptyTokenWarning()
{
return false;
}
protected boolean isCoveredTokenMarked()
{
return false;
}
protected String getMainStyle()
{
return "partitur_table";
}
/**
* Checks if a token is covered by a matched node but not a match by it self.
*
* @param markedAndCovered A mapping from node to a matched number. The node
* must not matched directly, but covered by a matched node.
* @param tok the checked token.
* @return Returns null, if token is not covered neither marked.
*/
private Long markCoveredTokens(Map markedAndCovered, SNode tok)
{
RelannisNodeFeature f = RelannisNodeFeature.extract(tok);
if (markedAndCovered.containsKey(tok) && f != null && f.getMatchedNode()
== null)
{
return markedAndCovered.get(tok);
}
return f != null ? f.getMatchedNode() : null;
}
/**
* Checks if a token is a marked match
*
* @param tok the checked token.
* @return Returns null, if token is not marked.
*/
private Long tokenMatch(SNode tok)
{
// check if the span is a matched node
SFeature featMatched = tok.getFeature(ANNIS_NS, FEAT_MATCHEDNODE);
Long matchRaw = featMatched == null ? null : featMatched.
getValue_SNUMERIC();
return matchRaw;
}
public VisualizerInput getInput()
{
return input;
}
public AnnotationGrid getGrid()
{
return grid;
}
} // end GridVisualizerComponent