Skip to content

Commit

Permalink
#2696 - Document-level recommendations
Browse files Browse the repository at this point in the history
- Introduce a registry for layer recommendation supports
  • Loading branch information
reckart committed Dec 21, 2023
1 parent 7460495 commit 719e101
Show file tree
Hide file tree
Showing 19 changed files with 326 additions and 132 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ void acceptSpanSuggestion(SourceDocument aDocument, User aDataOwner, SpanSuggest
throws IOException, AnnotationException;

void rejectSpanSuggestion(String aSessionOwner, User aDataOwner, AnnotationLayer aLayer,
SpanSuggestion aSuggestion);
SpanSuggestion aSuggestion)
throws AnnotationException;

void skipSpanSuggestion(String aSessionOwner, User aDataOwner, AnnotationLayer aLayer,
SpanSuggestion aSuggestion)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ public void acceptSpanSuggestion(SourceDocument aDocument, User aDataOwner,
@Transactional
public void rejectSpanSuggestion(String aSessionOwner, User aDataOwner, AnnotationLayer aLayer,
SpanSuggestion aSuggestion)
throws AnnotationException
{
var document = documentService.getSourceDocument(aLayer.getProject(),
aSuggestion.getDocumentName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -718,12 +718,16 @@ private void actionReject(AjaxRequestTarget aTarget) throws AnnotationException

getAnnotationPage().ensureIsEditable();

alStateModel.getObject().getSuggestion().ifPresent(suggestion -> {
requestClearningSelectionAndJumpingToSuggestion();
activeLearningService.rejectSpanSuggestion(userService.getCurrentUsername(),
getModelObject().getUser(), alStateModel.getObject().getLayer(), suggestion);
moveToNextSuggestion(aTarget);
});
var maybeSuggestion = alStateModel.getObject().getSuggestion();
if (!maybeSuggestion.isPresent()) {
return;
}

requestClearningSelectionAndJumpingToSuggestion();
activeLearningService.rejectSpanSuggestion(userService.getCurrentUsername(),
getModelObject().getUser(), alStateModel.getObject().getLayer(),
maybeSuggestion.get());
moveToNextSuggestion(aTarget);
}

private void moveToNextSuggestion(AjaxRequestTarget aTarget)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,16 @@
import org.springframework.context.annotation.Configuration;

import de.tudarmstadt.ukp.inception.documents.api.DocumentService;
import de.tudarmstadt.ukp.inception.recommendation.api.LearningRecordService;
import de.tudarmstadt.ukp.inception.recommendation.api.RecommendationService;
import de.tudarmstadt.ukp.inception.schema.api.AnnotationSchemaService;
import de.tudarmstadt.ukp.inception.schema.api.feature.FeatureSupportRegistry;
import de.tudarmstadt.ukp.inception.schema.api.layer.LayerSupportRegistry;
import de.tudarmstadt.ukp.inception.schema.api.layer.LayerType;
import de.tudarmstadt.ukp.inception.ui.core.docanno.event.DocumentMetadataAnnotationActionUndoSupport;
import de.tudarmstadt.ukp.inception.ui.core.docanno.layer.DocumentMetadataLayerSingletonCreatingWatcher;
import de.tudarmstadt.ukp.inception.ui.core.docanno.layer.DocumentMetadataLayerSupport;
import de.tudarmstadt.ukp.inception.ui.core.docanno.sidebar.DocumentMetadataRecommendationSupport;
import de.tudarmstadt.ukp.inception.ui.core.docanno.sidebar.DocumentMetadataSidebarFactory;

/**
Expand Down Expand Up @@ -79,4 +82,15 @@ public DocumentMetadataAnnotationActionUndoSupport documentMetadataAnnotationAct
{
return new DocumentMetadataAnnotationActionUndoSupport();
}

@Bean
@ConditionalOnProperty(prefix = "documentmetadata", name = "enabled", havingValue = "true", matchIfMissing = true)
public DocumentMetadataRecommendationSupport documentMetadataRecommendationSupport(
RecommendationService aRecommendationService,
LearningRecordService aLearningRecordService,
ApplicationEventPublisher aApplicationEventPublisher)
{
return new DocumentMetadataRecommendationSupport(aRecommendationService,
aLearningRecordService, aApplicationEventPublisher);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,18 @@
import de.tudarmstadt.ukp.inception.recommendation.api.LayerRecommendationSupport_ImplBase;
import de.tudarmstadt.ukp.inception.recommendation.api.LearningRecordService;
import de.tudarmstadt.ukp.inception.recommendation.api.RecommendationService;
import de.tudarmstadt.ukp.inception.recommendation.api.model.AnnotationSuggestion;
import de.tudarmstadt.ukp.inception.recommendation.api.model.LearningRecordChangeLocation;
import de.tudarmstadt.ukp.inception.recommendation.api.model.LearningRecordUserAction;
import de.tudarmstadt.ukp.inception.recommendation.api.model.MetadataSuggestion;
import de.tudarmstadt.ukp.inception.recommendation.api.model.SuggestionGroup;
import de.tudarmstadt.ukp.inception.schema.api.adapter.AnnotationException;
import de.tudarmstadt.ukp.inception.schema.api.adapter.TypeAdapter;
import de.tudarmstadt.ukp.inception.ui.core.docanno.layer.DocumentMetadataLayerAdapter;
import de.tudarmstadt.ukp.inception.ui.core.docanno.layer.DocumentMetadataLayerTraits;

public class DocumentMetadataRecommendationSupport
extends LayerRecommendationSupport_ImplBase<DocumentMetadataLayerAdapter, MetadataSuggestion>
extends LayerRecommendationSupport_ImplBase<MetadataSuggestion>

{
public DocumentMetadataRecommendationSupport(RecommendationService aRecommendationService,
Expand All @@ -50,13 +52,21 @@ public DocumentMetadataRecommendationSupport(RecommendationService aRecommendati
super(aRecommendationService, aLearningRecordService, aApplicationEventPublisher);
}

@Override
public boolean accepts(AnnotationSuggestion aContext)
{
return aContext instanceof MetadataSuggestion;
}

@Override
public AnnotationBaseFS acceptSuggestion(String aSessionOwner, SourceDocument aDocument,
String aDataOwner, CAS aCas, DocumentMetadataLayerAdapter aAdapter,
AnnotationFeature aFeature, MetadataSuggestion aSuggestion,
LearningRecordChangeLocation aLocation, LearningRecordUserAction aAction)
String aDataOwner, CAS aCas, TypeAdapter aAdapter, AnnotationFeature aFeature,
AnnotationSuggestion aSuggestion, LearningRecordChangeLocation aLocation,
LearningRecordUserAction aAction)
throws AnnotationException
{
var adapter = (DocumentMetadataLayerAdapter) aAdapter;

var aValue = aSuggestion.getLabel();

var candidates = aCas.<Annotation> select(aAdapter.getAnnotationTypeName()) //
Expand All @@ -75,7 +85,7 @@ else if (candidates.isEmpty() || !aAdapter.getTraits(DocumentMetadataLayerTraits
.map(DocumentMetadataLayerTraits::isSingleton).orElse(false)) {
// ... if not or if stacking is allowed, then we create a new annotation - this also
// takes care of attaching to an annotation if necessary
var newAnnotation = aAdapter.add(aDocument, aDataOwner, aCas);
var newAnnotation = adapter.add(aDocument, aDataOwner, aCas);
annotation = newAnnotation;
}
else {
Expand All @@ -92,25 +102,24 @@ else if (candidates.isEmpty() || !aAdapter.getTraits(DocumentMetadataLayerTraits

@Override
public void rejectSuggestion(String aSessionOwner, SourceDocument aDocument, String aDataOwner,
MetadataSuggestion aSuggestion, LearningRecordChangeLocation aAction)
AnnotationSuggestion aSuggestion, LearningRecordChangeLocation aAction)
throws AnnotationException
{
throw new NotImplementedException("Not yet implemented");
}

@Override
public void skipSuggestion(String aSessionOwner, SourceDocument aDocument, String aDataOwner,
MetadataSuggestion aSuggestion, LearningRecordChangeLocation aAction)
AnnotationSuggestion aSuggestion, LearningRecordChangeLocation aAction)
throws AnnotationException
{
throw new NotImplementedException("Not yet implemented");
}

@Override
public void calculateSuggestionVisibility(String aSessionOwner, SourceDocument aDocument,
CAS aCas, String aDataOwner, AnnotationLayer aLayer,
Collection<SuggestionGroup<MetadataSuggestion>> aRecommendations, int aWindowBegin,
int aWindowEnd)
public <T extends AnnotationSuggestion> void calculateSuggestionVisibility(String aSessionOwner,
SourceDocument aDocument, CAS aCas, String aDataOwner, AnnotationLayer aLayer,
Collection<SuggestionGroup<T>> aRecommendations, int aWindowBegin, int aWindowEnd)
{
throw new NotImplementedException("Not yet implemented");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,26 @@
import de.tudarmstadt.ukp.inception.recommendation.api.model.SuggestionGroup;
import de.tudarmstadt.ukp.inception.schema.api.adapter.AnnotationException;
import de.tudarmstadt.ukp.inception.schema.api.adapter.TypeAdapter;
import de.tudarmstadt.ukp.inception.support.extensionpoint.Extension;

public interface LayerRecommendationSupport<T extends TypeAdapter, S extends AnnotationSuggestion>
public interface LayerRecommendationSupport<S extends AnnotationSuggestion>
extends Extension<AnnotationSuggestion>
{
AnnotationBaseFS acceptSuggestion(String aSessionOwner, SourceDocument aDocument,
String aDataOwner, CAS aCas, T aAdapter, AnnotationFeature aFeature, S aSuggestion,
LearningRecordChangeLocation aLocation, LearningRecordUserAction aAction)
String aDataOwner, CAS aCas, TypeAdapter aAdapter, AnnotationFeature aFeature,
AnnotationSuggestion aSuggestion, LearningRecordChangeLocation aLocation,
LearningRecordUserAction aAction)
throws AnnotationException;

void rejectSuggestion(String aSessionOwner, SourceDocument aDocument, String aDataOwner,
S suggestion, LearningRecordChangeLocation aAction)
AnnotationSuggestion suggestion, LearningRecordChangeLocation aAction)
throws AnnotationException;

void skipSuggestion(String aSessionOwner, SourceDocument aDocument, String aDataOwner,
S suggestion, LearningRecordChangeLocation aAction)
AnnotationSuggestion suggestion, LearningRecordChangeLocation aAction)
throws AnnotationException;

void calculateSuggestionVisibility(String aSessionOwner, SourceDocument aDocument, CAS aCas,
String aDataOwner, AnnotationLayer aLayer,
Collection<SuggestionGroup<S>> aRecommendations, int aWindowBegin, int aWindowEnd);
<T extends AnnotationSuggestion> void calculateSuggestionVisibility(String aSessionOwner,
SourceDocument aDocument, CAS aCas, String aDataOwner, AnnotationLayer aLayer,
Collection<SuggestionGroup<T>> aRecommendations, int aWindowBegin, int aWindowEnd);
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

import org.apache.uima.cas.AnnotationBaseFS;
import org.apache.uima.cas.CAS;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ApplicationEventPublisher;

import de.tudarmstadt.ukp.clarin.webanno.model.AnnotationFeature;
Expand All @@ -35,13 +36,15 @@
import de.tudarmstadt.ukp.inception.schema.api.adapter.TypeAdapter;
import de.tudarmstadt.ukp.inception.support.uima.ICasUtil;

public abstract class LayerRecommendationSupport_ImplBase<T extends TypeAdapter, S extends AnnotationSuggestion>
implements LayerRecommendationSupport<T, S>
public abstract class LayerRecommendationSupport_ImplBase<S extends AnnotationSuggestion>
implements LayerRecommendationSupport<S>, BeanNameAware
{
protected final RecommendationService recommendationService;
protected final LearningRecordService learningRecordService;
protected final ApplicationEventPublisher applicationEventPublisher;

private String id;

public LayerRecommendationSupport_ImplBase(RecommendationService aRecommendationService,
LearningRecordService aLearningRecordService,
ApplicationEventPublisher aApplicationEventPublisher)
Expand All @@ -51,6 +54,18 @@ public LayerRecommendationSupport_ImplBase(RecommendationService aRecommendation
applicationEventPublisher = aApplicationEventPublisher;
}

@Override
public void setBeanName(String aName)
{
id = aName;
}

@Override
public String getId()
{
return id;
}

protected void commmitAcceptedLabel(String aSessionOwner, SourceDocument aDocument,
String aDataOwner, CAS aCas, TypeAdapter aAdapter, AnnotationFeature aFeature,
AnnotationSuggestion aSuggestion, String aValue, AnnotationBaseFS annotation,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Licensed to the Technische Universität Darmstadt under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The Technische Universität Darmstadt
* licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.
*
* 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 de.tudarmstadt.ukp.inception.recommendation.api;

import de.tudarmstadt.ukp.inception.recommendation.api.model.AnnotationSuggestion;
import de.tudarmstadt.ukp.inception.support.extensionpoint.ContextLookupExtensionPoint;

public interface LayerRecommendtionSupportRegistry
extends ContextLookupExtensionPoint<AnnotationSuggestion, LayerRecommendationSupport<?>>
{

}
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,8 @@ AnnotationFS acceptSuggestion(String aSessionOwner, SourceDocument aDocument, St
*/
@Deprecated
void rejectSuggestion(String aSessionOwner, SourceDocument aDocument, String aDataOwner,
AnnotationSuggestion suggestion, LearningRecordChangeLocation aAction);
AnnotationSuggestion suggestion, LearningRecordChangeLocation aAction)
throws AnnotationException;

/**
* @deprecated Obtain {@link LayerRecommendationSupport} for relation layer and use that
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
import de.tudarmstadt.ukp.inception.project.api.ProjectService;
import de.tudarmstadt.ukp.inception.recommendation.RecommendationEditorExtension;
import de.tudarmstadt.ukp.inception.recommendation.actionbar.RecommenderActionBarExtension;
import de.tudarmstadt.ukp.inception.recommendation.api.LayerRecommendationSupport;
import de.tudarmstadt.ukp.inception.recommendation.api.LayerRecommendtionSupportRegistry;
import de.tudarmstadt.ukp.inception.recommendation.api.LearningRecordService;
import de.tudarmstadt.ukp.inception.recommendation.api.RecommendationService;
import de.tudarmstadt.ukp.inception.recommendation.api.RecommenderFactoryRegistry;
Expand All @@ -55,8 +57,11 @@
import de.tudarmstadt.ukp.inception.recommendation.render.RecommendationRelationRenderer;
import de.tudarmstadt.ukp.inception.recommendation.render.RecommendationRenderer;
import de.tudarmstadt.ukp.inception.recommendation.render.RecommendationSpanRenderer;
import de.tudarmstadt.ukp.inception.recommendation.service.LayerRecommendtionSupportRegistryImpl;
import de.tudarmstadt.ukp.inception.recommendation.service.RecommendationServiceImpl;
import de.tudarmstadt.ukp.inception.recommendation.service.RecommenderFactoryRegistryImpl;
import de.tudarmstadt.ukp.inception.recommendation.service.RelationRecommendationSupport;
import de.tudarmstadt.ukp.inception.recommendation.service.SpanRecommendationSupport;
import de.tudarmstadt.ukp.inception.recommendation.sidebar.RecommendationSidebarFactory;
import de.tudarmstadt.ukp.inception.scheduling.SchedulingService;
import de.tudarmstadt.ukp.inception.schema.api.AnnotationSchemaService;
Expand All @@ -78,11 +83,13 @@ public RecommendationService recommendationService(PreferencesService aPreferenc
RecommenderFactoryRegistry aRecommenderFactoryRegistry,
SchedulingService aSchedulingService, AnnotationSchemaService aAnnoService,
DocumentService aDocumentService, ProjectService aProjectService,
ApplicationEventPublisher aApplicationEventPublisher)
ApplicationEventPublisher aApplicationEventPublisher,
LayerRecommendtionSupportRegistry aLayerRecommendtionSupportRegistry)
{
return new RecommendationServiceImpl(aPreferencesService, aSessionRegistry, aUserRepository,
aRecommenderFactoryRegistry, aSchedulingService, aAnnoService, aDocumentService,
aProjectService, entityManager, aApplicationEventPublisher);
aProjectService, entityManager, aApplicationEventPublisher,
aLayerRecommendtionSupportRegistry);
}

@Bean
Expand Down Expand Up @@ -218,4 +225,33 @@ public RecommenderActionBarExtension recommenderActionBarExtension(
{
return new RecommenderActionBarExtension(aRecommendationService);
}

@Bean
public SpanRecommendationSupport spanRecommendationSupport(
RecommendationService aRecommendationService,
LearningRecordService aLearningRecordService,
ApplicationEventPublisher aApplicationEventPublisher,
AnnotationSchemaService aSchemaService)
{
return new SpanRecommendationSupport(aRecommendationService, aLearningRecordService,
aApplicationEventPublisher, aSchemaService);
}

@Bean
public RelationRecommendationSupport relationRecommendationSupport(
RecommendationService aRecommendationService,
LearningRecordService aLearningRecordService,
ApplicationEventPublisher aApplicationEventPublisher,
AnnotationSchemaService aSchemaService)
{
return new RelationRecommendationSupport(aRecommendationService, aLearningRecordService,
aApplicationEventPublisher, aSchemaService);
}

@Bean
public LayerRecommendtionSupportRegistry layerRecommendtionSupportRegistry(
@Lazy @Autowired(required = false) List<LayerRecommendationSupport<?>> aExtensions)
{
return new LayerRecommendtionSupportRegistryImpl(aExtensions);
}
}
Loading

0 comments on commit 719e101

Please sign in to comment.