Skip to content

Commit

Permalink
Merge branch 'release/26.x'
Browse files Browse the repository at this point in the history
* release/26.x:
  #3610 - Minimizing icon in document level feature is wrong after updating feature
  #3656 - The color of the existing layers changes after adding another layer
  #3679 - NullPointerException during export in WebAnno format
  • Loading branch information
reckart committed Jan 4, 2023
2 parents b93b60b + f206471 commit ba84242
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
package de.tudarmstadt.ukp.clarin.webanno.api.annotation.rendering;

import static java.lang.invoke.MethodHandles.lookup;
import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.toList;
import static org.apache.commons.lang3.exception.ExceptionUtils.getRootCauseMessage;
import static org.slf4j.LoggerFactory.getLogger;

Expand Down Expand Up @@ -98,8 +100,14 @@ public void render(VDocument aVDoc, RenderRequest aRequest)
allLayers = schemaService.listAnnotationLayer(aRequest.getProject());
}

// Sort layers by creation order (i.e. by ID) to ensure the colors remain the same even
// if a new layer is added to a project
var sortedLayers = allLayers.stream() //
.sorted(comparing(AnnotationLayer::getId)) //
.collect(toList());

Map<String[], Queue<String>> colorQueues = new HashMap<>();
for (AnnotationLayer layer : allLayers) {
for (AnnotationLayer layer : sortedLayers) {
ColoringStrategy coloringStrategy = aRequest.getColoringStrategyOverride()
.orElse(coloringService.getStrategy(layer, prefs.get(), colorQueues));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
import org.apache.uima.fit.util.CasUtil;
import org.apache.uima.fit.util.FSUtil;
import org.apache.uima.jcas.JCas;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.tudarmstadt.ukp.clarin.webanno.tsv.internal.tsv3x.model.LayerType;
import de.tudarmstadt.ukp.clarin.webanno.tsv.internal.tsv3x.model.TsvColumn;
Expand All @@ -66,6 +68,8 @@

public class Tsv3XCasDocumentBuilder
{
private static final Logger LOG = LoggerFactory.getLogger(Tsv3XCasDocumentBuilder.class);

public static TsvDocument of(TsvSchema aSchema, JCas aJCas)
{
TsvFormatHeader format = new TsvFormatHeader("WebAnno TSV", "3.3");
Expand Down Expand Up @@ -111,15 +115,23 @@ public static TsvDocument of(TsvSchema aSchema, JCas aJCas)
// Scan all annotations of the types defined in the schema and use them to set up sub-token
// units.
for (Type type : aSchema.getUimaTypes()) {
var annotations = CasUtil.select(aJCas.getCas(), type);

if (aSchema.getIgnoredTypes().contains(type)) {
if (!annotations.isEmpty()) {
LOG.warn(
"The layer [{}] is incompatible with WebAnno TSV but contains {} "
+ "annotations - these will not be exported.",
type, annotations.size());
}
continue;
}

LayerType layerType = aSchema.getLayerType(type);

boolean addDisambiguationIdIfStacked = SPAN.equals(layerType);

for (AnnotationFS annotation : CasUtil.select(aJCas.getCas(), type)) {
for (AnnotationFS annotation : annotations) {
// Mind that we might actually get an annotation here which is a subtype of `type`!
doc.activateType(type);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public static TsvSchema analyze(TypeSystem aTypeSystem)
{
TsvSchema schema = new TsvSchema();

Set<Type> ignoredTypes = new HashSet<>();
Set<Type> incompatibleTypes = new HashSet<>();

Set<Type> chainLinkTypes = new HashSet<>();

Expand Down Expand Up @@ -96,7 +96,7 @@ public static TsvSchema analyze(TypeSystem aTypeSystem)
break;
case INCOMPATIBLE:
// Do not generate a column definition for incompatible types.
ignoredTypes.add(type);
incompatibleTypes.add(type);
break;
}
}
Expand All @@ -107,11 +107,11 @@ public static TsvSchema analyze(TypeSystem aTypeSystem)
Feature firstFeat = type.getFeatureByBaseName(CHAIN_FIRST_FEAT);
if (firstFeat != null && chainLinkTypes.contains(firstFeat.getRange())) {
schema.addChainHeadType(type);
ignoredTypes.remove(type);
incompatibleTypes.remove(type);
}
}

ignoredTypes.forEach(schema::ignoreType);
incompatibleTypes.forEach(schema::ignoreType);

return schema;
}
Expand Down Expand Up @@ -139,6 +139,10 @@ else if (SPAN.equals(aLayerType) && isSlotFeature(aTypeSystem, feat)) {
targetColumn.setTargetTypeHint(slotTargetType);
aSchema.addColumn(targetColumn);
}
else if (CAS.TYPE_NAME_STRING_ARRAY.equals(feat.getRange().getName())) {
LOG.debug("Multi-value string features are not supported by WebAnno TSV: [{}]",
feat.getName());
}
}
}

Expand Down Expand Up @@ -223,12 +227,18 @@ public static boolean isSpanLayer(Type aType)
continue;
}

// We ignore multi-value string features which are a new feature in INCEpTION but will
// not be supported by WebAnno TSV 3.x anymore. This should allow to at least export
// the compatible information while skipping over the multi-value strings.
if (CAS.TYPE_NAME_STRING_ARRAY.equals(feat.getRange().getName())) {
continue;
}

if (!(isPrimitiveFeature(feat) || isSlotFeature(feat))) {
compatible = false;
// LOG.debug("Incompatible feature in type [" + aType + "]: " + feat);
break;
}

}

return compatible;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -89,7 +90,11 @@ public Set<Type> getActiveTypes()
*/
public TsvUnit findIdDefiningUnit(AnnotationFS aFS)
{
return fs2unitIndex.get(aFS);
TsvUnit unit = fs2unitIndex.get(aFS);
if (unit == null) {
throw new NoSuchElementException("No ID-defining unit found for annotation: " + aFS);
}
return unit;
}

public void mapFS2Unit(AnnotationFS aFS, TsvUnit aUnit)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
[[sect_formats_webannotsv3]]
= WebAnno TSV 3.x

====
CAUTION: Legacy feature. This format does not support all of the layer and feature configurations of {product-name}. For example, multi-value features are not supported. Using this format when exporting documents or projects with layer configurations not supported by this file format may generate errors or may simply omit unsupported information from the export. Please consider switching your post-processing workflows to
the <<sect_formats_uimaxmi,CAS XMI (XML 1.0)>> format.
====

The file format used by WebAnno version 3.

[cols="2,1,1,1,3"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ the world of XML parsers, so you may expect better interoperability with other p
(e.g. Python) with the XML 1.0 flavor. XML 1.1 has a support for a wider range of characters, despite
dating back to 2006, it is still not supported by all XML parsers.

The format can be processed in Java using the link:https://github.com/apache/uima-uimaj#readme[Apache UIMA Java SDK] (both flavors) or in Python using link:https://pypi.org/project/dkpro-cassis/[DKPro Cassis] (only the XMI 1.0 flavor).
The format can be processed in Java using the link:https://github.com/apache/uima-uimaj#readme[Apache UIMA Java SDK] (both flavors) or in Python using link:https://pypi.org/project/dkpro-cassis/[DKPro Cassis] (only the XML 1.0 flavor).

[cols="2,1,1,1,3"]
|====
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,7 @@ protected void onEvent(AjaxRequestTarget aTarget)
}
});

detailPanel.add(visibleWhen(
() -> selectedAnnotation == container || aItem.getModelObject().singleton));
detailPanel.add(visibleWhen(() -> isExpanded(aItem, container)));

if (createdAnnotationAddress == vid.getId()) {
createdAnnotationAddress = -1;
Expand All @@ -306,14 +305,12 @@ protected void onEvent(AjaxRequestTarget aTarget)
}

WebMarkupContainer close = new WebMarkupContainer("close");
close.add(visibleWhen(
() -> !detailPanel.isVisible() && !aItem.getModelObject().singleton));
close.add(visibleWhen(() -> isExpanded(aItem, container)));
close.setOutputMarkupId(true);
container.add(close);

WebMarkupContainer open = new WebMarkupContainer("open");
open.add(visibleWhen(
() -> detailPanel.isVisible() && !aItem.getModelObject().singleton));
open.add(visibleWhen(() -> !isExpanded(aItem, container)));
open.setOutputMarkupId(true);
container.add(open);

Expand All @@ -332,6 +329,12 @@ protected void onEvent(AjaxRequestTarget aTarget)

aItem.setOutputMarkupId(true);
}

private boolean isExpanded(ListItem<AnnotationListItem> aItem,
WebMarkupContainer container)
{
return selectedAnnotation == container || aItem.getModelObject().singleton;
}
};
}

Expand Down

0 comments on commit ba84242

Please sign in to comment.