Skip to content

Commit

Permalink
Merge branch 'release/29.x'
Browse files Browse the repository at this point in the history
* release/29.x:
  #4201 - Layer export as JSON does not include coloring rules
  #4199 - Jumping to the end of a long annotation sometimes does not work

% Conflicts:
%	inception/inception-html-apache-annotator-editor/src/main/ts/src/apache-annotator/ApacheAnnotatorVisualizer.ts
  • Loading branch information
reckart committed Sep 21, 2023
2 parents 2973c24 + ac35c16 commit 93fac7e
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 55 deletions.
22 changes: 14 additions & 8 deletions inception/inception-export/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>de.tudarmstadt.ukp.inception.app</groupId>
Expand Down Expand Up @@ -78,7 +80,7 @@
<groupId>org.apache.uima</groupId>
<artifactId>uimafit-core</artifactId>
</dependency>

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
Expand All @@ -91,7 +93,7 @@
<groupId>it.unimi.dsi</groupId>
<artifactId>fastutil</artifactId>
</dependency>

<dependency>
<groupId> org.springframework</groupId>
<artifactId>spring-core</artifactId>
Expand All @@ -112,7 +114,7 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
</dependency>

<dependency>
<groupId>org.dkpro.core</groupId>
<artifactId>dkpro-core-api-metadata-asl</artifactId>
Expand All @@ -121,18 +123,22 @@
<groupId>org.dkpro.core</groupId>
<artifactId>dkpro-core-api-segmentation-asl</artifactId>
</dependency>

<dependency>
<groupId>org.dkpro.core</groupId>
<artifactId>dkpro-core-api-lexmorph-asl</artifactId>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>


<!-- TEST DEPENDENCIES -->
<dependency>
<groupId>de.tudarmstadt.ukp.inception.app</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@

import static de.tudarmstadt.ukp.clarin.webanno.model.OverlapMode.ANY_OVERLAP;
import static de.tudarmstadt.ukp.clarin.webanno.model.OverlapMode.OVERLAP_ONLY;
import static de.tudarmstadt.ukp.clarin.webanno.support.WebAnnoConst.CHAIN_TYPE;
import static de.tudarmstadt.ukp.clarin.webanno.support.WebAnnoConst.COREFERENCE_RELATION_FEATURE;
import static de.tudarmstadt.ukp.clarin.webanno.support.WebAnnoConst.COREFERENCE_TYPE_FEATURE;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

Expand All @@ -46,7 +48,9 @@
import de.tudarmstadt.ukp.clarin.webanno.model.ValidationMode;
import de.tudarmstadt.ukp.clarin.webanno.security.model.User;
import de.tudarmstadt.ukp.clarin.webanno.support.JSONUtil;
import de.tudarmstadt.ukp.clarin.webanno.support.WebAnnoConst;
import de.tudarmstadt.ukp.dkpro.core.api.lexmorph.type.morph.MorphologicalFeatures;
import de.tudarmstadt.ukp.dkpro.core.api.segmentation.type.Lemma;
import de.tudarmstadt.ukp.dkpro.core.api.segmentation.type.Token;
import de.tudarmstadt.ukp.inception.schema.AnnotationSchemaService;

/**
Expand Down Expand Up @@ -158,6 +162,7 @@ private static void setLayer(AnnotationSchemaService aAnnotationService, Annotat
aLayer.setName(aExLayer.getName());
aLayer.setProject(aProject);
aLayer.setType(aExLayer.getType());
aLayer.setTraits(aExLayer.getTraits());
aAnnotationService.createOrUpdateLayer(aLayer);
}

Expand All @@ -167,28 +172,27 @@ public static AnnotationLayer importLayerFile(AnnotationSchemaService annotation
{
String text = IOUtils.toString(aIS, "UTF-8");

ExportedAnnotationLayer[] exLayers = JSONUtil.getObjectMapper().readValue(text,
ExportedAnnotationLayer[].class);
var exLayers = JSONUtil.getObjectMapper().readValue(text, ExportedAnnotationLayer[].class);

// First import the layers but without setting the attach-layers/features
Map<String, ExportedAnnotationLayer> exLayersMap = new HashMap<>();
Map<String, AnnotationLayer> layersMap = new HashMap<>();
for (ExportedAnnotationLayer exLayer : exLayers) {
AnnotationLayer layer = createLayer(annotationService, project, exLayer);
for (var exLayer : exLayers) {
var layer = createLayer(annotationService, project, exLayer);
layersMap.put(layer.getName(), layer);
exLayersMap.put(layer.getName(), exLayer);
}

// Second fill in the attach-layer and attach-feature information
for (AnnotationLayer layer : layersMap.values()) {
ExportedAnnotationLayer exLayer = exLayersMap.get(layer.getName());
for (var layer : layersMap.values()) {
var exLayer = exLayersMap.get(layer.getName());
if (exLayer.getAttachType() != null) {
layer.setAttachType(layersMap.get(exLayer.getAttachType().getName()));
}
if (exLayer.getAttachFeature() != null) {
AnnotationLayer attachLayer = annotationService.findLayer(project,
var attachLayer = annotationService.findLayer(project,
exLayer.getAttachType().getName());
AnnotationFeature attachFeature = annotationService
var attachFeature = annotationService
.getFeature(exLayer.getAttachFeature().getName(), attachLayer);
layer.setAttachFeature(attachFeature);
}
Expand All @@ -213,8 +217,8 @@ private static AnnotationLayer createLayer(AnnotationSchemaService annotationSer
setLayer(annotationService, layer, aExLayer, project);
}

for (ExportedAnnotationFeature exfeature : aExLayer.getFeatures()) {
ExportedTagSet exTagset = exfeature.getTagSet();
for (var exfeature : aExLayer.getFeatures()) {
var exTagset = exfeature.getTagSet();
TagSet tagSet = null;
if (exTagset != null && annotationService.existsTagSet(exTagset.getName(), project)) {
tagSet = annotationService.getTagSet(exTagset.getName(), project);
Expand All @@ -231,7 +235,7 @@ else if (exTagset != null) {
setFeature(annotationService, feature, exfeature, project);
continue;
}
AnnotationFeature feature = new AnnotationFeature();
var feature = new AnnotationFeature();
feature.setLayer(layer);
feature.setTagset(tagSet);
setFeature(annotationService, feature, exfeature, project);
Expand All @@ -249,16 +253,21 @@ private static void setFeature(AnnotationSchemaService aAnnotationService,
aFeature.setVisible(aExFeature.isVisible());
aFeature.setUiName(aExFeature.getUiName());
aFeature.setProject(aProject);
aFeature.setLayer(aFeature.getLayer());
boolean isItChainedLayer = aFeature.getLayer().getType().equals(WebAnnoConst.CHAIN_TYPE);
if (isItChainedLayer && (aExFeature.getName().equals(WebAnnoConst.COREFERENCE_TYPE_FEATURE)
|| aExFeature.getName().equals(WebAnnoConst.COREFERENCE_RELATION_FEATURE))) {
aFeature.setName(aExFeature.getName());
boolean isItChainedLayer = CHAIN_TYPE.equals(aFeature.getLayer().getType());
if (isItChainedLayer && (COREFERENCE_TYPE_FEATURE.equals(aExFeature.getName())
|| COREFERENCE_RELATION_FEATURE.equals(aExFeature.getName()))) {
aFeature.setType(CAS.TYPE_NAME_STRING);
}
else if (Token._TypeName.equals(aFeature.getLayer().getName())
&& Token._FeatName_morph.equals(aExFeature.getName())
&& Lemma._TypeName.equals(aExFeature.getType())) {
// See https://github.com/inception-project/inception/issues/3080
aFeature.setType(MorphologicalFeatures._TypeName);
}
else {
aFeature.setType(aExFeature.getType());
}
aFeature.setName(aExFeature.getName());
aFeature.setRemember(aExFeature.isRemember());
aFeature.setRequired(aExFeature.isRequired());
aFeature.setHideUnconstraintFeature(aExFeature.isHideUnconstraintFeature());
Expand All @@ -268,7 +277,8 @@ private static void setFeature(AnnotationSchemaService aAnnotationService,
aFeature.setLinkTypeRoleFeatureName(aExFeature.getLinkTypeRoleFeatureName());
aFeature.setLinkTypeTargetFeatureName(aExFeature.getLinkTypeTargetFeatureName());
aFeature.setTraits(aExFeature.getTraits());

aFeature.setCuratable(aExFeature.isCuratable());
aFeature.setRank(aExFeature.getRank());
aAnnotationService.createFeature(aFeature);
}

Expand All @@ -278,15 +288,15 @@ public static ExportedAnnotationLayer exportLayerDetails(
Map<AnnotationFeature, ExportedAnnotationFeature> aFeatureToExFeature,
AnnotationLayer aLayer, AnnotationSchemaService aAnnotationService)
{
ExportedAnnotationLayer exLayer = new ExportedAnnotationLayer();
var exLayer = new ExportedAnnotationLayer();
exLayer.setAllowStacking(aLayer.isAllowStacking());
exLayer.setLockToTokenOffset(AnchoringMode.SINGLE_TOKEN.equals(aLayer.getAnchoringMode()));
exLayer.setMultipleTokens(AnchoringMode.TOKENS.equals(aLayer.getAnchoringMode()));
exLayer.setBuiltIn(aLayer.isBuiltIn());
exLayer.setReadonly(aLayer.isReadonly());
exLayer.setCrossSentence(aLayer.isCrossSentence());
exLayer.setDescription(aLayer.getDescription());
exLayer.setEnabled(aLayer.isEnabled());
exLayer.setLockToTokenOffset(AnchoringMode.SINGLE_TOKEN.equals(aLayer.getAnchoringMode()));
exLayer.setMultipleTokens(AnchoringMode.TOKENS.equals(aLayer.getAnchoringMode()));
exLayer.setOverlapMode(aLayer.getOverlapMode());
exLayer.setAnchoringMode(aLayer.getAnchoringMode());
exLayer.setValidationMode(aLayer.getValidationMode());
Expand All @@ -295,14 +305,15 @@ public static ExportedAnnotationLayer exportLayerDetails(
exLayer.setProjectName(aLayer.getProject().getName());
exLayer.setType(aLayer.getType());
exLayer.setUiName(aLayer.getUiName());
exLayer.setTraits(aLayer.getTraits());

if (aLayerToExLayer != null) {
aLayerToExLayer.put(aLayer, exLayer);
}

List<ExportedAnnotationFeature> exFeatures = new ArrayList<>();
for (AnnotationFeature feature : aAnnotationService.listAnnotationFeature(aLayer)) {
ExportedAnnotationFeature exFeature = new ExportedAnnotationFeature();
var exFeatures = new ArrayList<ExportedAnnotationFeature>();
for (var feature : aAnnotationService.listAnnotationFeature(aLayer)) {
var exFeature = new ExportedAnnotationFeature();
exFeature.setDescription(feature.getDescription());
exFeature.setEnabled(feature.isEnabled());
exFeature.setRemember(feature.isRemember());
Expand All @@ -319,18 +330,20 @@ public static ExportedAnnotationLayer exportLayerDetails(
exFeature.setLinkTypeRoleFeatureName(feature.getLinkTypeRoleFeatureName());
exFeature.setLinkTypeTargetFeatureName(feature.getLinkTypeTargetFeatureName());
exFeature.setTraits(feature.getTraits());
exFeature.setCuratable(feature.isCuratable());
exFeature.setRank(feature.getRank());

if (feature.getTagset() != null) {
TagSet tagSet = feature.getTagset();
ExportedTagSet exTagSet = new ExportedTagSet();
var tagSet = feature.getTagset();
var exTagSet = new ExportedTagSet();
exTagSet.setDescription(tagSet.getDescription());
exTagSet.setLanguage(tagSet.getLanguage());
exTagSet.setName(tagSet.getName());
exTagSet.setCreateTag(tagSet.isCreateTag());

List<ExportedTag> exportedTags = new ArrayList<>();
for (Tag tag : aAnnotationService.listTags(tagSet)) {
ExportedTag exTag = new ExportedTag();
var exportedTags = new ArrayList<ExportedTag>();
for (var tag : aAnnotationService.listTags(tagSet)) {
var exTag = new ExportedTag();
exTag.setDescription(tag.getDescription());
exTag.setName(tag.getName());
exportedTags.add(exTag);
Expand All @@ -343,6 +356,7 @@ public static ExportedAnnotationLayer exportLayerDetails(
aFeatureToExFeature.put(feature, exFeature);
}
}

exLayer.setFeatures(exFeatures);
return exLayer;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ export class ApacheAnnotatorVisualizer {

private data? : AnnotatedText

private removePingMarkers: (() => void)[] = []
private removePingMarkersTimeout: number | undefined = undefined
private removeTransientMarkers: (() => void)[] = []
private removeTransientMarkersTimeout: number | undefined = undefined

private alpha = '55'

constructor (element: Element, ajax: DiamAjax) {
Expand Down Expand Up @@ -133,6 +134,7 @@ export class ApacheAnnotatorVisualizer {
if (doc.spans) {
console.log(`Loaded ${doc.spans.size} span annotations`)
doc.spans.forEach(span => this.renderSpanAnnotation(doc, span))

this.removeSpuriousZeroWidthHighlights()
if (!this.showEmptyHighlights) {
this.removeWhitepaceOnlyHighlights()
Expand Down Expand Up @@ -182,7 +184,7 @@ export class ApacheAnnotatorVisualizer {

const vhl = this.root.ownerDocument.createElement('div')
vhl.classList.add('iaa-vertical-marker-focus')
vhl.style.top = `${top - scrollerContainerRect.top + this.root.scrollTop}px`
vhl.style.top = `${top - scrollerContainerRect.top + (this.root.scrollTop || 0)}px`
vhl.style.height = `${bottom - top}px`
this.root.appendChild(vhl)

Expand Down Expand Up @@ -229,8 +231,8 @@ export class ApacheAnnotatorVisualizer {
/**
* Some highliths may only contain whitepace. This method removes such highlights.
*/
private removeWhitepaceOnlyHighlights () {
this.getAllHighlights().forEach(e => {
private removeWhitepaceOnlyHighlights (selector: string = '.iaa-highlighted') {
this.root.querySelectorAll(selector).forEach(e => {
if (!e.classList.contains('iaa-zero-width') && !e.textContent?.trim()) {
e.after(...e.childNodes)
e.remove()
Expand Down Expand Up @@ -361,16 +363,21 @@ export class ApacheAnnotatorVisualizer {
const range = offsetToRange(this.root, args.offset, args.offset)
if (!range) return

window.clearTimeout(this.removePingMarkersTimeout)
this.removePingMarkers.forEach(remove => remove())
window.clearTimeout(this.removeTransientMarkersTimeout)
this.removeTransientMarkers.forEach(remove => remove())

const removeScrollMarker = highlightText(range, 'mark', { id: 'iaa-scroll-marker' })
this.removePingMarkers = []
this.removeTransientMarkers = [removeScrollMarker]
for (const pingOffset of args.pingRanges || []) {
const pingRange = offsetToRange(this.root, pingOffset[0], pingOffset[1])
if (!pingRange) continue
this.removePingMarkers.push(highlightText(pingRange, 'mark', { class: 'iaa-ping-marker' }))
this.removeTransientMarkers.push(highlightText(pingRange, 'mark', { class: 'iaa-ping-marker' }))
}

if (!this.showEmptyHighlights) {
this.removeWhitepaceOnlyHighlights('.iaa-ping-marker')
}

this.root.querySelectorAll('.iaa-ping-marker').forEach(e => {
if (!e.textContent) e.remove()
})
Expand All @@ -394,10 +401,9 @@ export class ApacheAnnotatorVisualizer {
scrollTarget.scrollIntoView({ behavior: 'auto', block: 'center', inline: 'nearest' })
}

removeScrollMarker()
this.removePingMarkersTimeout = window.setTimeout(() => {
this.removePingMarkers.forEach(remove => remove())
console.log('ping removed')
this.removeTransientMarkersTimeout = window.setTimeout(() => {
this.removeTransientMarkers.forEach(remove => remove())
this.removeTransientMarkers = []
}, 2000)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,14 @@ $(document).ready(function() {
// http://stackoverflow.com/questions/2335553/jquery-how-to-catch-enter-key-and-change-event-to-tab

function moveToNextInput(current) {
var inputs = $(current).parents("#annotationFeatureForm").eq(0).find(":input");
var idx = inputs.index(current);
let inputs = $(current).parents("#annotationFeatureForm").eq(0).find(":input");
let idx = inputs.index(current);
if (idx == inputs.length - 1) {
inputs[idx].blur();
} else {
inputs[idx + 1].focus(); // handles submit buttons
inputs[idx + 1].select();
let input = inputs[idx + 1];
if (input.focus) input.focus(); // handles submit buttons
if (input.select) input.select();
}
}

Expand Down

0 comments on commit 93fac7e

Please sign in to comment.