diff --git a/inception/inception-active-learning/pom.xml b/inception/inception-active-learning/pom.xml index 3f9aeb1b55c..69d484e7aca 100644 --- a/inception/inception-active-learning/pom.xml +++ b/inception/inception-active-learning/pom.xml @@ -97,6 +97,10 @@ commons-lang3 + + org.springframework + spring-core + org.springframework spring-beans diff --git a/inception/inception-active-learning/src/main/java/de/tudarmstadt/ukp/inception/active/learning/sidebar/ActiveLearningSidebarFactory.java b/inception/inception-active-learning/src/main/java/de/tudarmstadt/ukp/inception/active/learning/sidebar/ActiveLearningSidebarFactory.java index d06a1889f6f..7f368adbb32 100644 --- a/inception/inception-active-learning/src/main/java/de/tudarmstadt/ukp/inception/active/learning/sidebar/ActiveLearningSidebarFactory.java +++ b/inception/inception-active-learning/src/main/java/de/tudarmstadt/ukp/inception/active/learning/sidebar/ActiveLearningSidebarFactory.java @@ -20,6 +20,7 @@ import org.apache.wicket.Component; import org.apache.wicket.model.IModel; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.annotation.Order; import de.tudarmstadt.ukp.clarin.webanno.api.casstorage.CasProvider; import de.tudarmstadt.ukp.clarin.webanno.model.Project; @@ -37,6 +38,7 @@ * {@link ActiveLearningAutoConfiguration#activeLearningSidebarFactory}. *

*/ +@Order(4000) public class ActiveLearningSidebarFactory extends AnnotationSidebarFactory_ImplBase { diff --git a/inception/inception-api-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/api/annotation/coloring/ColoringServiceImpl.java b/inception/inception-api-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/api/annotation/coloring/ColoringServiceImpl.java index 9434b316a44..58e5d3146f0 100644 --- a/inception/inception-api-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/api/annotation/coloring/ColoringServiceImpl.java +++ b/inception/inception-api-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/api/annotation/coloring/ColoringServiceImpl.java @@ -26,7 +26,7 @@ import static de.tudarmstadt.ukp.inception.rendering.coloring.ColoringStrategyType.GRAY; import static de.tudarmstadt.ukp.inception.rendering.coloring.ColoringStrategyType.LEGACY; import static de.tudarmstadt.ukp.inception.rendering.coloring.ColoringStrategyType.STATIC_PASTELLE; -import static de.tudarmstadt.ukp.inception.rendering.coloring.ReadonlyColoringBehaviour.NORMAL; +import static de.tudarmstadt.ukp.inception.rendering.coloring.ReadonlyColoringStrategy.NORMAL; import static de.tudarmstadt.ukp.inception.support.WebAnnoConst.SPAN_TYPE; import static java.lang.Integer.MAX_VALUE; import static java.util.Arrays.asList; @@ -50,7 +50,7 @@ import de.tudarmstadt.ukp.inception.rendering.coloring.ColoringService; import de.tudarmstadt.ukp.inception.rendering.coloring.ColoringStrategy; import de.tudarmstadt.ukp.inception.rendering.coloring.ColoringStrategyType; -import de.tudarmstadt.ukp.inception.rendering.coloring.ReadonlyColoringBehaviour; +import de.tudarmstadt.ukp.inception.rendering.coloring.ReadonlyColoringStrategy; import de.tudarmstadt.ukp.inception.rendering.editorstate.ColoringPreferences; import de.tudarmstadt.ukp.inception.schema.api.AnnotationSchemaService; import de.tudarmstadt.ukp.inception.schema.api.event.LayerConfigurationChangedEvent; @@ -85,7 +85,7 @@ public ColoringStrategy getStrategy(AnnotationLayer aLayer, ColoringPreferences Map> aColorQueues) { ColoringStrategyType t = aPreferences.getColorPerLayer().get(aLayer.getId()); - ReadonlyColoringBehaviour rt = aPreferences.getReadonlyLayerColoringBehaviour(); + ReadonlyColoringStrategy rt = aPreferences.getReadonlyLayerColoringBehaviour(); if (aLayer.isReadonly() && rt != NORMAL) { t = rt.getColoringStrategy(); diff --git a/inception/inception-api-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/api/annotation/config/AnnotationAutoConfiguration.java b/inception/inception-api-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/api/annotation/config/AnnotationAutoConfiguration.java index fd5d784a812..e6a6edc9c9e 100644 --- a/inception/inception-api-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/api/annotation/config/AnnotationAutoConfiguration.java +++ b/inception/inception-api-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/api/annotation/config/AnnotationAutoConfiguration.java @@ -33,6 +33,7 @@ import de.tudarmstadt.ukp.clarin.webanno.api.annotation.rendering.PreRenderer; import de.tudarmstadt.ukp.clarin.webanno.api.annotation.rendering.PreRendererImpl; import de.tudarmstadt.ukp.clarin.webanno.api.annotation.rendering.RenderNotificationRenderStep; +import de.tudarmstadt.ukp.clarin.webanno.security.UserDao; import de.tudarmstadt.ukp.inception.documents.api.RepositoryProperties; import de.tudarmstadt.ukp.inception.preferences.PreferencesService; import de.tudarmstadt.ukp.inception.rendering.coloring.ColoringService; @@ -89,10 +90,10 @@ public UserPreferencesService userPreferencesService( AnnotationSchemaService aAnnotationService, RepositoryProperties aRepositoryProperties, ColoringService aColoringService, AnnotationSchemaProperties aAnnotationEditorProperties, - PreferencesService aPreferencesService) + PreferencesService aPreferencesService, UserDao aUserService) { return new UserPreferencesServiceImpl(aDefaultPreferences, aAnnotationService, aRepositoryProperties, aColoringService, aAnnotationEditorProperties, - aPreferencesService); + aPreferencesService, aUserService); } } diff --git a/inception/inception-api-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/api/annotation/preferences/AnnotationPreferencesDialogContent.java b/inception/inception-api-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/api/annotation/preferences/AnnotationPreferencesDialogContent.java index b1dc9b8523f..5015950afc9 100755 --- a/inception/inception-api-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/api/annotation/preferences/AnnotationPreferencesDialogContent.java +++ b/inception/inception-api-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/api/annotation/preferences/AnnotationPreferencesDialogContent.java @@ -20,6 +20,8 @@ import static de.tudarmstadt.ukp.clarin.webanno.api.annotation.page.AnnotationEditorState.KEY_EDITOR_STATE; import static de.tudarmstadt.ukp.clarin.webanno.model.Mode.ANNOTATION; import static de.tudarmstadt.ukp.clarin.webanno.model.Mode.CURATION; +import static de.tudarmstadt.ukp.inception.rendering.editorstate.AnnotationPreference.FONT_ZOOM_MAX; +import static de.tudarmstadt.ukp.inception.rendering.editorstate.AnnotationPreference.FONT_ZOOM_MIN; import static de.tudarmstadt.ukp.inception.rendering.editorstate.AnnotationPreference.SIDEBAR_SIZE_MAX; import static de.tudarmstadt.ukp.inception.rendering.editorstate.AnnotationPreference.SIDEBAR_SIZE_MIN; import static de.tudarmstadt.ukp.inception.support.WebAnnoConst.CHAIN_TYPE; @@ -30,10 +32,10 @@ import java.io.IOException; import java.io.Serializable; +import java.lang.invoke.MethodHandles; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Set; import java.util.stream.Collectors; import org.apache.commons.lang3.tuple.Pair; @@ -54,7 +56,6 @@ import org.apache.wicket.spring.injection.annot.SpringBean; import org.slf4j.Logger; -import de.tudarmstadt.ukp.clarin.webanno.api.annotation.page.AnnotationEditorState; import de.tudarmstadt.ukp.clarin.webanno.model.AnnotationLayer; import de.tudarmstadt.ukp.clarin.webanno.security.UserDao; import de.tudarmstadt.ukp.inception.editor.AnnotationEditorFactory; @@ -62,8 +63,7 @@ import de.tudarmstadt.ukp.inception.preferences.PreferencesService; import de.tudarmstadt.ukp.inception.project.api.ProjectService; import de.tudarmstadt.ukp.inception.rendering.coloring.ColoringStrategyType; -import de.tudarmstadt.ukp.inception.rendering.coloring.ReadonlyColoringBehaviour; -import de.tudarmstadt.ukp.inception.rendering.editorstate.AnnotationPreference; +import de.tudarmstadt.ukp.inception.rendering.coloring.ReadonlyColoringStrategy; import de.tudarmstadt.ukp.inception.rendering.editorstate.AnnotatorState; import de.tudarmstadt.ukp.inception.schema.api.AnnotationSchemaService; import de.tudarmstadt.ukp.inception.schema.api.config.AnnotationSchemaProperties; @@ -80,7 +80,7 @@ public class AnnotationPreferencesDialogContent { private static final long serialVersionUID = -2102136855109258306L; - private static final Logger LOG = getLogger(AnnotationPreferencesDialogContent.class); + private static final Logger LOG = getLogger(MethodHandles.lookup().lookupClass()); private @SpringBean AnnotationSchemaService annotationService; private @SpringBean ProjectService projectService; @@ -105,35 +105,35 @@ public AnnotationPreferencesDialogContent(String aId, IModel aMo editorChoices = getEditorChoices(); onChangeAction = aOnChangeAction; - form = new Form<>("form", new CompoundPropertyModel<>(loadModel(stateModel.getObject()))); + form = new Form<>("form", new CompoundPropertyModel<>(loadPreferences(stateModel.getObject()))); - NumberTextField windowSizeField = new NumberTextField<>("windowSize"); + var windowSizeField = new NumberTextField("windowSize"); windowSizeField.setType(Integer.class); windowSizeField.setMinimum(1); form.add(windowSizeField); - NumberTextField sidebarSizeLeftField = new NumberTextField<>("sidebarSizeLeft"); + var sidebarSizeLeftField = new NumberTextField("sidebarSizeLeft"); sidebarSizeLeftField.setType(Integer.class); sidebarSizeLeftField.setMinimum(SIDEBAR_SIZE_MIN); sidebarSizeLeftField.setMaximum(SIDEBAR_SIZE_MAX); form.add(sidebarSizeLeftField); - NumberTextField sidebarSizeRightField = new NumberTextField<>("sidebarSizeRight"); + var sidebarSizeRightField = new NumberTextField("sidebarSizeRight"); sidebarSizeRightField.setType(Integer.class); sidebarSizeRightField.setMinimum(SIDEBAR_SIZE_MIN); sidebarSizeRightField.setMaximum(SIDEBAR_SIZE_MAX); form.add(sidebarSizeRightField); - NumberTextField fontZoomField = new NumberTextField<>("fontZoom"); + var fontZoomField = new NumberTextField("fontZoom"); fontZoomField.setType(Integer.class); - fontZoomField.setMinimum(AnnotationPreference.FONT_ZOOM_MIN); - fontZoomField.setMaximum(AnnotationPreference.FONT_ZOOM_MAX); + fontZoomField.setMinimum(FONT_ZOOM_MIN); + fontZoomField.setMaximum(FONT_ZOOM_MAX); form.add(fontZoomField); - AnnotationEditorState state = preferencesService - .loadDefaultTraitsForProject(KEY_EDITOR_STATE, stateModel.getObject().getProject()); + var state = preferencesService.loadDefaultTraitsForProject(KEY_EDITOR_STATE, + stateModel.getObject().getProject()); - DropDownChoice> editor = new DropDownChoice<>("editor"); + var editor = new DropDownChoice>("editor"); editor.setChoiceRenderer(new ChoiceRenderer<>("value")); editor.setChoices(editorChoices); editor.add( @@ -145,19 +145,19 @@ public AnnotationPreferencesDialogContent(String aId, IModel aMo form.add(createLayerContainer()); // Add a check box to enable/disable automatic page navigations while annotating - CheckBox scrollCheckBox = new CheckBox("scrollPage"); + var scrollCheckBox = new CheckBox("scrollPage"); scrollCheckBox.setOutputMarkupId(true); form.add(scrollCheckBox); // Add a check box to enable/disable arc collapsing - CheckBox collapseCheckBox = new CheckBox("collapseArcs"); + var collapseCheckBox = new CheckBox("collapseArcs"); collapseCheckBox.setOutputMarkupId(true); form.add(collapseCheckBox); // Add global read-only coloring strategy combo box - DropDownChoice readOnlyColor = new DropDownChoice<>( + var readOnlyColor = new DropDownChoice( "readonlyLayerColoringBehaviour"); - readOnlyColor.setChoices(asList(ReadonlyColoringBehaviour.values())); + readOnlyColor.setChoices(asList(ReadonlyColoringStrategy.values())); readOnlyColor.setChoiceRenderer(new ChoiceRenderer<>("descriptiveName")); form.add(readOnlyColor); @@ -180,10 +180,10 @@ private List> getEditorChoices() private void actionSave(AjaxRequestTarget aTarget, Form aForm) { try { - AnnotatorState state = stateModel.getObject(); - Preferences model = form.getModelObject(); + var state = stateModel.getObject(); + var model = form.getModelObject(); - AnnotationPreference prefs = state.getPreferences(); + var prefs = state.getPreferences(); prefs.setScrollPage(model.scrollPage); prefs.setWindowSize(model.windowSize); prefs.setSidebarSizeLeft(model.sidebarSizeLeft); @@ -203,7 +203,7 @@ private void actionSave(AjaxRequestTarget aTarget, Form aForm) // layers state.refreshSelectableLayers(annotationEditorProperties::isLayerBlocked); - userPreferencesService.savePreference(state, userDao.getCurrentUsername()); + userPreferencesService.savePreferences(state, userDao.getCurrentUsername()); } catch (IOException e) { error("Preference file not found"); @@ -219,12 +219,12 @@ private void actionCancel(AjaxRequestTarget aTarget) findParent(ModalDialog.class).close(aTarget); } - private Preferences loadModel(AnnotatorState state) + private Preferences loadPreferences(AnnotatorState aState) { - AnnotationPreference prefs = state.getPreferences(); + var prefs = aState.getPreferences(); // Import current settings from the annotator - Preferences model = new Preferences(); + var model = new Preferences(); model.windowSize = Math.max(prefs.getWindowSize(), 1); model.sidebarSizeLeft = prefs.getSidebarSizeLeft(); model.sidebarSizeRight = prefs.getSidebarSizeRight(); @@ -235,20 +235,20 @@ private Preferences loadModel(AnnotatorState state) model.collapseArcs = prefs.isCollapseArcs(); model.editor = editorChoices.stream().filter( - editor -> Objects.equals(editor.getKey(), state.getPreferences().getEditor())) + editor -> Objects.equals(editor.getKey(), aState.getPreferences().getEditor())) .findFirst().orElseGet(() -> { AnnotationEditorFactory editorFactory = annotationEditorRegistry .getDefaultEditorFactory(); return Pair.of(editorFactory.getBeanName(), editorFactory.getDisplayName()); }); - model.annotationLayers = annotationService.listAnnotationLayer(state.getProject()).stream() + model.annotationLayers = annotationService.listAnnotationLayer(aState.getProject()).stream() // hide disabled Layers .filter(layer -> layer.isEnabled()) // hide blocked layers .filter(layer -> !annotationEditorProperties.isLayerBlocked(layer)) .filter(layer -> !(layer.getType().equals(CHAIN_TYPE) - && CURATION == state.getMode())) + && CURATION == aState.getMode())) .collect(Collectors.toList()); return model; @@ -263,13 +263,13 @@ private ListView createLayerContainer() @Override protected void populateItem(ListItem aItem) { - Preferences prefs = form.getModelObject(); - AnnotationLayer layer = aItem.getModelObject(); - Set hiddenLayerIds = stateModel.getObject().getPreferences() + var prefs = form.getModelObject(); + var layer = aItem.getModelObject(); + var hiddenLayerIds = stateModel.getObject().getPreferences() .getHiddenAnnotationLayerIds(); // add visibility checkbox - CheckBox layerVisible = new CheckBox("annotationLayerActive", + var layerVisible = new CheckBox("annotationLayerActive", Model.of(!hiddenLayerIds.contains(layer.getId()))); layerVisible.add(new LambdaAjaxFormComponentUpdatingBehavior("change", _target -> { @@ -283,8 +283,7 @@ protected void populateItem(ListItem aItem) aItem.add(layerVisible); // add coloring strategy choice - DropDownChoice layerColor = new DropDownChoice<>( - "layercoloring"); + var layerColor = new DropDownChoice("layercoloring"); layerColor.setModel(Model.of(prefs.colorPerLayer.get(layer.getId()))); layerColor.setChoiceRenderer(new ChoiceRenderer<>("descriptiveName")); layerColor.setChoices(asList(ColoringStrategyType.values())); @@ -338,7 +337,7 @@ private static class Preferences private int fontZoom; private boolean scrollPage; private List annotationLayers; - private ReadonlyColoringBehaviour readonlyLayerColoringBehaviour; + private ReadonlyColoringStrategy readonlyLayerColoringBehaviour; private Map colorPerLayer; private boolean collapseArcs; } diff --git a/inception/inception-api-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/api/annotation/preferences/UserPreferencesService.java b/inception/inception-api-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/api/annotation/preferences/UserPreferencesService.java index 4d34b975a0d..ff7d688b4ee 100644 --- a/inception/inception-api-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/api/annotation/preferences/UserPreferencesService.java +++ b/inception/inception-api-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/api/annotation/preferences/UserPreferencesService.java @@ -42,7 +42,7 @@ public interface UserPreferencesService AnnotationPreference loadPreferences(Project aProject, String aUsername, Mode aMode) throws IOException; - void savePreference(AnnotatorState aState, String aUsername) throws IOException; + void savePreferences(AnnotatorState aState, String aUsername) throws IOException; void savePreferences(Project aProject, String aUsername, Mode aMode, AnnotationPreference aPref) throws IOException; diff --git a/inception/inception-api-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/api/annotation/preferences/UserPreferencesServiceImpl.java b/inception/inception-api-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/api/annotation/preferences/UserPreferencesServiceImpl.java index e73aa196718..d9648131899 100644 --- a/inception/inception-api-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/api/annotation/preferences/UserPreferencesServiceImpl.java +++ b/inception/inception-api-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/api/annotation/preferences/UserPreferencesServiceImpl.java @@ -19,9 +19,12 @@ import static de.tudarmstadt.ukp.inception.project.api.ProjectService.PROJECT_FOLDER; import static de.tudarmstadt.ukp.inception.project.api.ProjectService.SETTINGS_FOLDER; -import static java.util.stream.Collectors.toList; +import static de.tudarmstadt.ukp.inception.rendering.editorstate.AnnotationLayerVisibilityState.KEY_LAYERS_STATE; +import static de.tudarmstadt.ukp.inception.rendering.editorstate.AnnotationPageLayoutState.KEY_LAYOUT_STATE; +import static java.util.Arrays.asList; +import static java.util.stream.Collectors.toMap; +import static org.apache.commons.lang3.StringUtils.replaceChars; -import java.beans.PropertyDescriptor; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -31,17 +34,10 @@ import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; import java.util.Objects; -import java.util.Optional; import java.util.Properties; -import java.util.stream.Collectors; import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.BeanWrapper; import org.springframework.beans.BeanWrapperImpl; import org.springframework.beans.BeansException; import org.springframework.beans.PropertyAccessorFactory; @@ -49,14 +45,14 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import de.tudarmstadt.ukp.clarin.webanno.api.annotation.config.AnnotationAutoConfiguration; -import de.tudarmstadt.ukp.clarin.webanno.model.AnnotationLayer; import de.tudarmstadt.ukp.clarin.webanno.model.Mode; import de.tudarmstadt.ukp.clarin.webanno.model.Project; +import de.tudarmstadt.ukp.clarin.webanno.security.UserDao; +import de.tudarmstadt.ukp.clarin.webanno.security.model.User; import de.tudarmstadt.ukp.inception.documents.api.RepositoryProperties; import de.tudarmstadt.ukp.inception.preferences.Key; import de.tudarmstadt.ukp.inception.preferences.PreferencesService; import de.tudarmstadt.ukp.inception.rendering.coloring.ColoringService; -import de.tudarmstadt.ukp.inception.rendering.coloring.ColoringStrategyType; import de.tudarmstadt.ukp.inception.rendering.editorstate.AnnotationPreference; import de.tudarmstadt.ukp.inception.rendering.editorstate.AnnotatorState; import de.tudarmstadt.ukp.inception.schema.api.AnnotationSchemaService; @@ -83,13 +79,14 @@ public class UserPreferencesServiceImpl private final ColoringService coloringService; private final AnnotationSchemaProperties annotationEditorProperties; private final PreferencesService preferencesService; + private final UserDao userService; public UserPreferencesServiceImpl( AnnotationEditorDefaultPreferencesProperties aDefaultPreferences, AnnotationSchemaService aAnnotationService, RepositoryProperties aRepositoryProperties, ColoringService aColoringService, AnnotationSchemaProperties aAnnotationEditorProperties, - PreferencesService aPreferencesService) + PreferencesService aPreferencesService, UserDao aUserService) { defaultPreferences = aDefaultPreferences; annotationService = aAnnotationService; @@ -97,29 +94,28 @@ public UserPreferencesServiceImpl( coloringService = aColoringService; annotationEditorProperties = aAnnotationEditorProperties; preferencesService = aPreferencesService; + userService = aUserService; } @Override public void loadPreferences(AnnotatorState aState, String aUsername) throws BeansException, IOException { - AnnotationPreference preference = loadPreferences(aState.getProject(), aUsername, - aState.getMode()); + var preference = loadPreferences(aState.getProject(), aUsername, aState.getMode()); aState.setPreferences(preference); // set layers according to preferences - List allLayers = annotationService - .listAnnotationLayer(aState.getProject()); + var allLayers = annotationService.listAnnotationLayer(aState.getProject()); aState.setAllAnnotationLayers(allLayers); aState.setAnnotationLayers(allLayers.stream() // .filter(l -> !annotationEditorProperties.isLayerBlocked(l)) // .filter(l -> l.isEnabled()) // .filter(l -> !preference.getHiddenAnnotationLayerIds().contains(l.getId())) - .collect(toList())); + .toList()); // set default layer according to preferences - Optional defaultLayer = aState.getAnnotationLayers().stream() + var defaultLayer = aState.getAnnotationLayers().stream() .filter(layer -> Objects.equals(layer.getId(), preference.getDefaultLayer())) .findFirst(); @@ -133,32 +129,99 @@ public void loadPreferences(AnnotatorState aState, String aUsername) } @Override - public void savePreference(AnnotatorState aState, String aUsername) throws IOException + public void savePreferences(AnnotatorState aState, String aSessionOwnerName) throws IOException { - savePreferences(aState.getProject(), aUsername, aState.getMode(), aState.getPreferences()); + savePreferences(aState.getProject(), aSessionOwnerName, aState.getMode(), + aState.getPreferences()); } @Override - public synchronized AnnotationPreference loadPreferences(Project aProject, String aUsername, - Mode aMode) + public synchronized AnnotationPreference loadPreferences(Project aProject, + String aSessionOwnerName, Mode aMode) throws IOException { // TODO Use modular preference loading once it is available and if there is a corresponding // data file. Otherwise, fall back to loading the legacy preferences - AnnotationPreference pref = loadLegacyPreferences(aProject, aUsername, aMode); + var preferences = loadLegacyPreferences(aProject, aSessionOwnerName, aMode); + + var sessionOwner = userService.get(aSessionOwnerName); + + upgradeLayerVisibilityPreferences(aProject, sessionOwner, preferences); + upgradeLayoutStatePreferences(aProject, sessionOwner, preferences); + + return preferences; + } + + private void upgradeLayerVisibilityPreferences(Project aProject, User aSessionOwner, + AnnotationPreference preferences) + { + var maybeLayersState = preferencesService + .loadOptionalTraitsForUserAndProject(KEY_LAYERS_STATE, aSessionOwner, aProject); + if (maybeLayersState.isPresent()) { + var layersState = maybeLayersState.get(); + preferences.setColorPerLayer(layersState.getLayerColoringStrategy()); + preferences.setReadonlyLayerColoringBehaviour( + layersState.getReadonlyLayerColoringStrategy()); + preferences.setHiddenAnnotationLayerIds(layersState.getHiddenLayers()); + return; + } + + saveLayerVisibilityPreferences(aProject, aSessionOwner, preferences); + } + + private void saveLayerVisibilityPreferences(Project aProject, User aSessionOwner, + AnnotationPreference preferences) + { + var layersState = preferencesService.loadTraitsForUserAndProject(KEY_LAYERS_STATE, + aSessionOwner, aProject); + layersState.setLayerColoringStrategy(preferences.getColorPerLayer()); + layersState + .setReadonlyLayerColoringStrategy(preferences.getReadonlyLayerColoringBehaviour()); + layersState.setHiddenLayers(preferences.getHiddenAnnotationLayerIds()); + preferencesService.saveTraitsForUserAndProject(KEY_LAYERS_STATE, aSessionOwner, aProject, + layersState); + } + + private void upgradeLayoutStatePreferences(Project aProject, User aSessionOwner, + AnnotationPreference preferences) + { + var maybeLayoutState = preferencesService + .loadOptionalTraitsForUserAndProject(KEY_LAYOUT_STATE, aSessionOwner, aProject); + if (maybeLayoutState.isPresent()) { + var layoutState = maybeLayoutState.get(); + preferences.setSidebarSizeLeft(layoutState.getSidebarSizeLeft()); + preferences.setSidebarSizeRight(layoutState.getSidebarSizeRight()); + return; + } + + saveLayoutStatePreferences(aProject, aSessionOwner, preferences); + } - return pref; + private void saveLayoutStatePreferences(Project aProject, User aSessionOwner, + AnnotationPreference preferences) + { + var layoutState = preferencesService.loadTraitsForUserAndProject(KEY_LAYOUT_STATE, + aSessionOwner, aProject); + layoutState.setSidebarSizeLeft(preferences.getSidebarSizeLeft()); + layoutState.setSidebarSizeRight(preferences.getSidebarSizeRight()); + preferencesService.saveTraitsForUserAndProject(KEY_LAYOUT_STATE, aSessionOwner, aProject, + layoutState); } @Override - public synchronized void savePreferences(Project aProject, String aUsername, Mode aMode, + public synchronized void savePreferences(Project aProject, String aSessionOwnerName, Mode aMode, AnnotationPreference aPref) throws IOException { // TODO Switch to a new and modular way of writing preferences - saveLegacyPreferences(aProject, aUsername, aMode, aPref); + var sessionOwner = userService.get(aSessionOwnerName); + + saveLayerVisibilityPreferences(aProject, sessionOwner, aPref); + saveLayoutStatePreferences(aProject, sessionOwner, aPref); + + saveLegacyPreferences(aProject, aSessionOwnerName, aMode, aPref); } /** @@ -177,26 +240,27 @@ public synchronized void savePreferences(Project aProject, String aUsername, Mod * @throws IOException * if an I/O error occurs. */ + @Deprecated private void saveLegacyPreferences(Project aProject, String aUsername, Mode aMode, AnnotationPreference aPref) throws IOException { - BeanWrapper wrapper = PropertyAccessorFactory.forBeanPropertyAccess(aPref); - Properties props = new Properties(); - for (PropertyDescriptor value : wrapper.getPropertyDescriptors()) { + var wrapper = PropertyAccessorFactory.forBeanPropertyAccess(aPref); + var props = new Properties(); + for (var value : wrapper.getPropertyDescriptors()) { if (wrapper.getPropertyValue(value.getName()) == null) { continue; } props.setProperty(aMode + "." + value.getName(), wrapper.getPropertyValue(value.getName()).toString()); } - String propertiesPath = repositoryProperties.getPath().getAbsolutePath() + "/" - + PROJECT_FOLDER + "/" + aProject.getId() + "/" + SETTINGS_FOLDER + "/" + aUsername; + var propertiesPath = repositoryProperties.getPath().getAbsolutePath() + "/" + PROJECT_FOLDER + + "/" + aProject.getId() + "/" + SETTINGS_FOLDER + "/" + aUsername; // append existing preferences for the other mode if (new File(propertiesPath, ANNOTATION_PREFERENCE_PROPERTIES_FILE).exists()) { - Properties properties = loadLegacyPreferencesFile(aUsername, aProject); - for (Entry entry : properties.entrySet()) { - String key = entry.getKey().toString(); + var properties = loadLegacyPreferencesFile(aUsername, aProject); + for (var entry : properties.entrySet()) { + var key = entry.getKey().toString(); // Maintain other Modes of annotations confs than this one if (!key.substring(0, key.indexOf(".")).equals(aMode.toString())) { props.put(entry.getKey(), entry.getValue()); @@ -219,38 +283,36 @@ private void saveLegacyPreferences(Project aProject, String aUsername, Mode aMod // } } + @Deprecated private AnnotationPreference loadLegacyPreferences(Project aProject, String aUsername, Mode aMode) { - AnnotationPreference preference = new AnnotationPreference(); + var preference = new AnnotationPreference(); - BeanWrapper wrapper = new BeanWrapperImpl(preference); + var wrapper = new BeanWrapperImpl(preference); // get annotation preference from file system try { - Properties props = loadLegacyPreferencesFile(aUsername, aProject); - for (Entry entry : props.entrySet()) { - String property = entry.getKey().toString(); - int index = property.indexOf("."); - String propertyName = property.substring(index + 1); - String mode = property.substring(0, index); + var props = loadLegacyPreferencesFile(aUsername, aProject); + for (var entry : props.entrySet()) { + var property = entry.getKey().toString(); + var index = property.indexOf("."); + var propertyName = property.substring(index + 1); + var mode = property.substring(0, index); if (wrapper.isWritableProperty(propertyName) && mode.equals(aMode.getName())) { if (AnnotationPreference.class.getDeclaredField(propertyName) .getGenericType() instanceof ParameterizedType) { if (entry.getValue().toString().startsWith("[")) { // its a list - List value = Arrays.asList( - StringUtils.replaceChars(entry.getValue().toString(), "[]", "") - .split(",")); + var value = asList( + replaceChars(entry.getValue().toString(), "[]", "").split(",")); if (!value.get(0).equals("")) { wrapper.setPropertyValue(propertyName, value); } } else if (entry.getValue().toString().startsWith("{")) { // its a map - String s = StringUtils.replaceChars(entry.getValue().toString(), "{}", - ""); - Map value = Arrays.stream(s.split(",")) - .map(x -> x.split("=")) - .collect(Collectors.toMap(x -> x[0], x -> x[1])); + var s = replaceChars(entry.getValue().toString(), "{}", ""); + var value = Arrays.stream(s.split(",")).map(x -> x.split("=")) + .collect(toMap(x -> x[0], x -> x[1])); wrapper.setPropertyValue(propertyName, value); } } @@ -270,12 +332,13 @@ else if (entry.getValue().toString().startsWith("{")) { // its a map } // Get color preferences for each layer, init with default if not found - Map colorPerLayer = preference.getColorPerLayer(); + var colorPerLayer = preference.getColorPerLayer(); if (colorPerLayer == null) { colorPerLayer = new HashMap<>(); preference.setColorPerLayer(colorPerLayer); } - for (AnnotationLayer layer : annotationService.listAnnotationLayer(aProject)) { + + for (var layer : annotationService.listAnnotationLayer(aProject)) { if (!colorPerLayer.containsKey(layer.getId())) { colorPerLayer.put(layer.getId(), coloringService.getBestInitialStrategy(layer)); } @@ -304,11 +367,12 @@ else if (entry.getValue().toString().startsWith("{")) { // its a map private Properties loadLegacyPreferencesFile(String aUsername, Project aProject) throws IOException { - Properties property = new Properties(); - property.load(new FileInputStream(new File(repositoryProperties.getPath().getAbsolutePath() - + "/" + PROJECT_FOLDER + "/" + aProject.getId() + "/" + SETTINGS_FOLDER + "/" - + aUsername + "/" + ANNOTATION_PREFERENCE_PROPERTIES_FILE))); - return property; + var properties = new Properties(); + properties + .load(new FileInputStream(new File(repositoryProperties.getPath().getAbsolutePath() + + "/" + PROJECT_FOLDER + "/" + aProject.getId() + "/" + SETTINGS_FOLDER + + "/" + aUsername + "/" + ANNOTATION_PREFERENCE_PROPERTIES_FILE))); + return properties; } /** @@ -332,8 +396,7 @@ public static class BratAnnotationEditorManagerPrefs public BratAnnotationEditorManagerPrefs() { - AnnotationEditorDefaultPreferencesProperties defaults = ApplicationContextProvider - .getApplicationContext() + var defaults = ApplicationContextProvider.getApplicationContext() .getBean(AnnotationEditorDefaultPreferencesProperties.class); defaultPageSize = defaults.getPageSize(); } diff --git a/inception/inception-api-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/api/annotation/rendering/ColorRenderer.java b/inception/inception-api-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/api/annotation/rendering/ColorRenderer.java index 27913bcaab8..624776887ee 100644 --- a/inception/inception-api-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/api/annotation/rendering/ColorRenderer.java +++ b/inception/inception-api-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/api/annotation/rendering/ColorRenderer.java @@ -41,7 +41,6 @@ import de.tudarmstadt.ukp.inception.rendering.coloring.ColoringService; import de.tudarmstadt.ukp.inception.rendering.coloring.ColoringStrategy; import de.tudarmstadt.ukp.inception.rendering.editorstate.AnnotationPreference; -import de.tudarmstadt.ukp.inception.rendering.editorstate.AnnotatorState; import de.tudarmstadt.ukp.inception.rendering.pipeline.RenderStep; import de.tudarmstadt.ukp.inception.rendering.request.RenderRequest; import de.tudarmstadt.ukp.inception.rendering.vmodel.VDocument; @@ -134,7 +133,7 @@ public void render(VDocument aVDoc, RenderRequest aRequest) private Optional getPreferences(RenderRequest aRequest) { - AnnotatorState state = aRequest.getState(); + var state = aRequest.getState(); if (state != null) { return Optional.of(state.getPreferences()); } diff --git a/inception/inception-api-render/pom.xml b/inception/inception-api-render/pom.xml index 859d8cad6b2..6a92d68316b 100644 --- a/inception/inception-api-render/pom.xml +++ b/inception/inception-api-render/pom.xml @@ -46,6 +46,10 @@ de.tudarmstadt.ukp.inception.app inception-security
+ + de.tudarmstadt.ukp.inception.app + inception-preferences + org.apache.uima diff --git a/inception/inception-api-render/src/main/java/de/tudarmstadt/ukp/inception/rendering/coloring/ReadonlyColoringBehaviour.java b/inception/inception-api-render/src/main/java/de/tudarmstadt/ukp/inception/rendering/coloring/ReadonlyColoringStrategy.java similarity index 91% rename from inception/inception-api-render/src/main/java/de/tudarmstadt/ukp/inception/rendering/coloring/ReadonlyColoringBehaviour.java rename to inception/inception-api-render/src/main/java/de/tudarmstadt/ukp/inception/rendering/coloring/ReadonlyColoringStrategy.java index b2220f477b5..c8a1842692e 100644 --- a/inception/inception-api-render/src/main/java/de/tudarmstadt/ukp/inception/rendering/coloring/ReadonlyColoringBehaviour.java +++ b/inception/inception-api-render/src/main/java/de/tudarmstadt/ukp/inception/rendering/coloring/ReadonlyColoringStrategy.java @@ -17,7 +17,7 @@ */ package de.tudarmstadt.ukp.inception.rendering.coloring; -public enum ReadonlyColoringBehaviour +public enum ReadonlyColoringStrategy { LEGACY("legacy " + ColoringStrategyType.GRAY.getDescriptiveName(), ColoringStrategyType.GRAY), NORMAL("normal", null), @@ -26,7 +26,7 @@ public enum ReadonlyColoringBehaviour private final String descriptiveName; private final ColoringStrategyType strategy; - private ReadonlyColoringBehaviour(String aDescriptiveName, ColoringStrategyType aStrategy) + private ReadonlyColoringStrategy(String aDescriptiveName, ColoringStrategyType aStrategy) { descriptiveName = aDescriptiveName; strategy = aStrategy; diff --git a/inception/inception-api-render/src/main/java/de/tudarmstadt/ukp/inception/rendering/editorstate/AnnotationLayerVisibilityState.java b/inception/inception-api-render/src/main/java/de/tudarmstadt/ukp/inception/rendering/editorstate/AnnotationLayerVisibilityState.java new file mode 100644 index 00000000000..38c85669936 --- /dev/null +++ b/inception/inception-api-render/src/main/java/de/tudarmstadt/ukp/inception/rendering/editorstate/AnnotationLayerVisibilityState.java @@ -0,0 +1,75 @@ +/* + * 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.rendering.editorstate; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import de.tudarmstadt.ukp.inception.preferences.Key; +import de.tudarmstadt.ukp.inception.rendering.coloring.ColoringStrategyType; +import de.tudarmstadt.ukp.inception.rendering.coloring.ReadonlyColoringStrategy; + +public class AnnotationLayerVisibilityState + implements Serializable +{ + private static final long serialVersionUID = -4171872631523263892L; + + public static final Key KEY_LAYERS_STATE = new Key<>( + AnnotationLayerVisibilityState.class, "annotation/layers"); + + private Map layerColoringStrategy = new HashMap<>(); + + private ReadonlyColoringStrategy readonlyLayerColoringStrategy = ReadonlyColoringStrategy.LEGACY; + + // Id of annotation layers, to be stored in the properties file comma separated: 12, 34,.... + private Set hiddenLayers = new HashSet<>(); + + public Map getLayerColoringStrategy() + { + return layerColoringStrategy; + } + + public void setLayerColoringStrategy(Map aLayerColoringStrategy) + { + layerColoringStrategy = aLayerColoringStrategy; + } + + public ReadonlyColoringStrategy getReadonlyLayerColoringStrategy() + { + return readonlyLayerColoringStrategy; + } + + public void setReadonlyLayerColoringStrategy( + ReadonlyColoringStrategy aReadonlyLayerColoringStrategy) + { + readonlyLayerColoringStrategy = aReadonlyLayerColoringStrategy; + } + + public Set getHiddenLayers() + { + return hiddenLayers; + } + + public void setHiddenLayers(Set aHiddenLayers) + { + hiddenLayers = aHiddenLayers; + } +} diff --git a/inception/inception-api-render/src/main/java/de/tudarmstadt/ukp/inception/rendering/editorstate/AnnotationPageLayoutState.java b/inception/inception-api-render/src/main/java/de/tudarmstadt/ukp/inception/rendering/editorstate/AnnotationPageLayoutState.java new file mode 100644 index 00000000000..1cdae6d6a3c --- /dev/null +++ b/inception/inception-api-render/src/main/java/de/tudarmstadt/ukp/inception/rendering/editorstate/AnnotationPageLayoutState.java @@ -0,0 +1,84 @@ +/* + * 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.rendering.editorstate; + +import static de.tudarmstadt.ukp.inception.rendering.editorstate.AnnotationPreference.SIDEBAR_SIZE_DEFAULT; +import static de.tudarmstadt.ukp.inception.rendering.editorstate.AnnotationPreference.SIDEBAR_SIZE_MAX; +import static de.tudarmstadt.ukp.inception.rendering.editorstate.AnnotationPreference.SIDEBAR_SIZE_MIN; + +import java.io.Serializable; + +import de.tudarmstadt.ukp.inception.preferences.Key; + +public class AnnotationPageLayoutState + implements Serializable +{ + public static final Key KEY_LAYOUT_STATE = new Key<>( + AnnotationPageLayoutState.class, "annotation/layout"); + + private static final long serialVersionUID = 4751157181917255392L; + + private int sidebarSizeLeft; + private int sidebarSizeRight; + + public int getSidebarSizeLeft() + { + if (sidebarSizeLeft < SIDEBAR_SIZE_MIN || sidebarSizeLeft > SIDEBAR_SIZE_MAX) { + return SIDEBAR_SIZE_DEFAULT; + } + else { + return sidebarSizeLeft; + } + } + + public void setSidebarSizeLeft(int aSidebarSize) + { + if (aSidebarSize > SIDEBAR_SIZE_MAX) { + sidebarSizeLeft = SIDEBAR_SIZE_MAX; + } + else if (aSidebarSize < SIDEBAR_SIZE_MIN) { + sidebarSizeLeft = SIDEBAR_SIZE_MIN; + } + else { + sidebarSizeLeft = aSidebarSize; + } + } + + public int getSidebarSizeRight() + { + if (sidebarSizeRight < SIDEBAR_SIZE_MIN || sidebarSizeRight > SIDEBAR_SIZE_MAX) { + return SIDEBAR_SIZE_DEFAULT; + } + else { + return sidebarSizeRight; + } + } + + public void setSidebarSizeRight(int aSidebarSize) + { + if (aSidebarSize > SIDEBAR_SIZE_MAX) { + sidebarSizeRight = SIDEBAR_SIZE_MAX; + } + else if (aSidebarSize < SIDEBAR_SIZE_MIN) { + sidebarSizeRight = SIDEBAR_SIZE_MIN; + } + else { + sidebarSizeRight = aSidebarSize; + } + } +} diff --git a/inception/inception-api-render/src/main/java/de/tudarmstadt/ukp/inception/rendering/editorstate/AnnotationPreference.java b/inception/inception-api-render/src/main/java/de/tudarmstadt/ukp/inception/rendering/editorstate/AnnotationPreference.java index dae10b79cb3..de5cdf50f53 100644 --- a/inception/inception-api-render/src/main/java/de/tudarmstadt/ukp/inception/rendering/editorstate/AnnotationPreference.java +++ b/inception/inception-api-render/src/main/java/de/tudarmstadt/ukp/inception/rendering/editorstate/AnnotationPreference.java @@ -24,57 +24,54 @@ import java.util.Map; import java.util.Set; +import de.tudarmstadt.ukp.clarin.webanno.model.AnnotationLayer; import de.tudarmstadt.ukp.inception.rendering.coloring.ColoringStrategyType; -import de.tudarmstadt.ukp.inception.rendering.coloring.ReadonlyColoringBehaviour; +import de.tudarmstadt.ukp.inception.rendering.coloring.ReadonlyColoringStrategy; /** * This is a class representing the bean objects to store users preference of annotation settings * such as annotation layers, number of sentence to display at a time, visibility of lemma and * whether to allow auto page scrolling. - * */ public class AnnotationPreference implements Serializable, ColoringPreferences { private static final long serialVersionUID = 2202236699782758271L; + // BEGIN: Settings related to editor choice + private String editor; + // END: Settings related to editor choice + + // BEGIN: Settings specific to the brat editor public static final int FONT_ZOOM_MIN = 10; public static final int FONT_ZOOM_MAX = 1000; public static final int FONT_ZOOM_DEFAULT = 100; + private int fontZoom; + private int windowSize; + private boolean scrollPage = true; + private boolean collapseArcs = false; + // END: Settings specific to the brat editor + // BEGIN: Settings specific to the AnnotationPage layout public static final int SIDEBAR_SIZE_MIN = 5; public static final int SIDEBAR_SIZE_MAX = 50; public static final int SIDEBAR_SIZE_DEFAULT = 20; - - // Id of annotation layers, to be stored in the properties file comma separated: 12, 34,.... - @Deprecated - private List annotationLayers; - - // Id of annotation layers, to be stored in the properties file comma separated: 12, 34,.... - private Set hiddenAnnotationLayerIds = new HashSet<>(); - - private long defaultLayer = -1; - - private int windowSize; - - private boolean scrollPage = true; - - @Deprecated - private boolean staticColor = true; // - - private Map colorPerLayer = new HashMap<>(); - - private ReadonlyColoringBehaviour readonlyLayerColoringBehaviour = ReadonlyColoringBehaviour.LEGACY; - - @Deprecated - private int sidebarSize; + private @Deprecated int sidebarSize; private int sidebarSizeLeft; private int sidebarSizeRight; - private int fontZoom; + // END: Settings specific to the AnnotationPage layout - private String editor; + // BEGIN: Settings specific to the AnnotationDetailPanel + private long defaultLayer = -1; + // END: Settings specific to the AnnotationDetailPanel - private boolean collapseArcs = false; + // BEGIN: Settings specific to layer visibility and coloring + private @Deprecated List annotationLayers; + private Set hiddenAnnotationLayerIds = new HashSet<>(); + private Map colorPerLayer = new HashMap<>(); + private ReadonlyColoringStrategy readonlyLayerColoringBehaviour = ReadonlyColoringStrategy.LEGACY; + private @Deprecated boolean staticColor = true; + // END: Settings specific to layer visibility and coloring /** * @return the preferred annotation layers @@ -99,6 +96,16 @@ public void setAnnotationLayers(List aAnnotationLayers) annotationLayers = aAnnotationLayers; } + public void setLayerVisible(AnnotationLayer aLayer, boolean aVisible) + { + if (aVisible) { + hiddenAnnotationLayerIds.remove(aLayer.getId()); + } + else { + hiddenAnnotationLayerIds.add(aLayer.getId()); + } + } + public Set getHiddenAnnotationLayerIds() { return hiddenAnnotationLayerIds; @@ -155,13 +162,13 @@ public void setColorPerLayer(Map colorPerLayer) } @Override - public ReadonlyColoringBehaviour getReadonlyLayerColoringBehaviour() + public ReadonlyColoringStrategy getReadonlyLayerColoringBehaviour() { return readonlyLayerColoringBehaviour; } public void setReadonlyLayerColoringBehaviour( - ReadonlyColoringBehaviour readonlyLayerColoringBehaviour) + ReadonlyColoringStrategy readonlyLayerColoringBehaviour) { this.readonlyLayerColoringBehaviour = readonlyLayerColoringBehaviour; } @@ -170,6 +177,7 @@ public void setReadonlyLayerColoringBehaviour( * @deprecated this is only here to not break previous user settings, its not an option that can * be set anymore and is also no longer used anywhere */ + @SuppressWarnings("javadoc") @Deprecated public boolean isStaticColor() { diff --git a/inception/inception-api-render/src/main/java/de/tudarmstadt/ukp/inception/rendering/editorstate/ColoringPreferences.java b/inception/inception-api-render/src/main/java/de/tudarmstadt/ukp/inception/rendering/editorstate/ColoringPreferences.java index 6104d29784a..8f5e347f7da 100644 --- a/inception/inception-api-render/src/main/java/de/tudarmstadt/ukp/inception/rendering/editorstate/ColoringPreferences.java +++ b/inception/inception-api-render/src/main/java/de/tudarmstadt/ukp/inception/rendering/editorstate/ColoringPreferences.java @@ -20,11 +20,11 @@ import java.util.Map; import de.tudarmstadt.ukp.inception.rendering.coloring.ColoringStrategyType; -import de.tudarmstadt.ukp.inception.rendering.coloring.ReadonlyColoringBehaviour; +import de.tudarmstadt.ukp.inception.rendering.coloring.ReadonlyColoringStrategy; public interface ColoringPreferences { Map getColorPerLayer(); - ReadonlyColoringBehaviour getReadonlyLayerColoringBehaviour(); + ReadonlyColoringStrategy getReadonlyLayerColoringBehaviour(); } diff --git a/inception/inception-diam-editor/pom.xml b/inception/inception-diam-editor/pom.xml index 4246a0788ac..d6f60bb660f 100644 --- a/inception/inception-diam-editor/pom.xml +++ b/inception/inception-diam-editor/pom.xml @@ -93,6 +93,10 @@ json-schema-validator + + org.springframework + spring-core + org.springframework spring-context diff --git a/inception/inception-diam-editor/src/main/java/de/tudarmstadt/ukp/inception/diam/sidebar/DiamSidebarFactory.java b/inception/inception-diam-editor/src/main/java/de/tudarmstadt/ukp/inception/diam/sidebar/DiamSidebarFactory.java index 5ea5cd270a9..e5dd06ee1c4 100644 --- a/inception/inception-diam-editor/src/main/java/de/tudarmstadt/ukp/inception/diam/sidebar/DiamSidebarFactory.java +++ b/inception/inception-diam-editor/src/main/java/de/tudarmstadt/ukp/inception/diam/sidebar/DiamSidebarFactory.java @@ -22,6 +22,7 @@ import java.util.Optional; import org.apache.wicket.model.IModel; +import org.springframework.core.annotation.Order; import com.networknt.schema.JsonSchema; @@ -45,6 +46,7 @@ * {@link AnnotationBrowserSidebarAutoConfiguration#annotationBrowserSidebarFactory}. *

*/ +@Order(1000) public class DiamSidebarFactory extends AnnotationSidebarFactory_ImplBase implements ClientSideUserPreferencesProvider diff --git a/inception/inception-image/pom.xml b/inception/inception-image/pom.xml index 23a128fee71..2acf386c257 100644 --- a/inception/inception-image/pom.xml +++ b/inception/inception-image/pom.xml @@ -76,6 +76,10 @@ commons-lang3
+ + org.springframework + spring-core + org.springframework spring-context diff --git a/inception/inception-image/src/main/java/de/tudarmstadt/ukp/inception/image/sidebar/ImageSidebarFactory.java b/inception/inception-image/src/main/java/de/tudarmstadt/ukp/inception/image/sidebar/ImageSidebarFactory.java index 4f1372e59c3..3b99d2d7fab 100644 --- a/inception/inception-image/src/main/java/de/tudarmstadt/ukp/inception/image/sidebar/ImageSidebarFactory.java +++ b/inception/inception-image/src/main/java/de/tudarmstadt/ukp/inception/image/sidebar/ImageSidebarFactory.java @@ -21,6 +21,7 @@ import org.apache.wicket.Component; import org.apache.wicket.model.IModel; +import org.springframework.core.annotation.Order; import de.agilecoders.wicket.core.markup.html.bootstrap.image.Icon; import de.agilecoders.wicket.extensions.markup.html.bootstrap.icon.FontAwesome5IconType; @@ -40,6 +41,7 @@ * {@link ImageSupportAutoConfiguration#imageSidebarFactory}. *

*/ +@Order(10000) public class ImageSidebarFactory extends AnnotationSidebarFactory_ImplBase { diff --git a/inception/inception-layer-docmetadata/pom.xml b/inception/inception-layer-docmetadata/pom.xml index 8aa2a661f7e..12a485e72ae 100644 --- a/inception/inception-layer-docmetadata/pom.xml +++ b/inception/inception-layer-docmetadata/pom.xml @@ -92,6 +92,10 @@ commons-lang3
+ + org.springframework + spring-core + org.springframework spring-context diff --git a/inception/inception-layer-docmetadata/src/main/java/de/tudarmstadt/ukp/inception/ui/core/docanno/sidebar/DocumentMetadataSidebarFactory.java b/inception/inception-layer-docmetadata/src/main/java/de/tudarmstadt/ukp/inception/ui/core/docanno/sidebar/DocumentMetadataSidebarFactory.java index fe532617443..846d8e3c69e 100644 --- a/inception/inception-layer-docmetadata/src/main/java/de/tudarmstadt/ukp/inception/ui/core/docanno/sidebar/DocumentMetadataSidebarFactory.java +++ b/inception/inception-layer-docmetadata/src/main/java/de/tudarmstadt/ukp/inception/ui/core/docanno/sidebar/DocumentMetadataSidebarFactory.java @@ -19,6 +19,7 @@ import org.apache.wicket.Component; import org.apache.wicket.model.IModel; +import org.springframework.core.annotation.Order; import de.agilecoders.wicket.core.markup.html.bootstrap.image.Icon; import de.agilecoders.wicket.extensions.markup.html.bootstrap.icon.FontAwesome5IconType; @@ -40,6 +41,7 @@ * {@link DocumentMetadataLayerSupportAutoConfiguration#documentMetadataSidebarFactory}. *

*/ +@Order(1500) public class DocumentMetadataSidebarFactory extends AnnotationSidebarFactory_ImplBase { diff --git a/inception/inception-preferences/src/main/java/de/tudarmstadt/ukp/inception/preferences/PreferencesService.java b/inception/inception-preferences/src/main/java/de/tudarmstadt/ukp/inception/preferences/PreferencesService.java index 99cc6c10bf8..3f7d6ae2832 100644 --- a/inception/inception-preferences/src/main/java/de/tudarmstadt/ukp/inception/preferences/PreferencesService.java +++ b/inception/inception-preferences/src/main/java/de/tudarmstadt/ukp/inception/preferences/PreferencesService.java @@ -18,6 +18,7 @@ package de.tudarmstadt.ukp.inception.preferences; import java.util.List; +import java.util.Optional; import de.tudarmstadt.ukp.clarin.webanno.model.Project; import de.tudarmstadt.ukp.clarin.webanno.security.model.User; @@ -32,6 +33,8 @@ public interface PreferencesService T loadTraitsForUserAndProject(Key aKey, User aUser, Project aProject); + Optional loadOptionalTraitsForUserAndProject(Key aKey, User aUser, Project aProject); + void saveTraitsForUserAndProject(Key aKey, User aUser, Project aProject, T aTraits); List listUserPreferencesForProject(Project aProject); diff --git a/inception/inception-preferences/src/main/java/de/tudarmstadt/ukp/inception/preferences/PreferencesServiceImpl.java b/inception/inception-preferences/src/main/java/de/tudarmstadt/ukp/inception/preferences/PreferencesServiceImpl.java index c250ab1906e..69c2aee5a3b 100644 --- a/inception/inception-preferences/src/main/java/de/tudarmstadt/ukp/inception/preferences/PreferencesServiceImpl.java +++ b/inception/inception-preferences/src/main/java/de/tudarmstadt/ukp/inception/preferences/PreferencesServiceImpl.java @@ -104,14 +104,14 @@ public void saveTraitsForUser(Key aKey, User aUser, T aTraits) private Optional getRawUserPreference(Key aKey, User aUser) { - String query = String.join("\n", // + var query = String.join("\n", // "FROM UserPreference ", // "WHERE user = :user ", // "AND name = :name"); - String name = aKey.getName(); + var name = aKey.getName(); try { - UserPreference pref = entityManager.createQuery(query, UserPreference.class) // + var pref = entityManager.createQuery(query, UserPreference.class) // .setParameter("user", aUser) // .setParameter("name", name) // .getSingleResult(); @@ -123,14 +123,36 @@ private Optional getRawUserPreference(Key aKey, User aUse } } + @Override + @Transactional + public Optional loadOptionalTraitsForUserAndProject(Key aKey, User aUser, + Project aProject) + { + try { + var pref = getUserProjectPreference(aKey, aUser, aProject); + if (pref.isPresent()) { + var json = pref.get().getTraits(); + T result = JSONUtil.fromJsonString(aKey.getTraitClass(), json); + LOG.debug("Loaded preferences for key {} and user {} and project {}: [{}]", aKey, + aUser, aProject, result); + return Optional.of(result); + } + return Optional.empty(); + } + catch (IOException e) { + LOG.error("Error while loading traits, returning empty", e); + return Optional.empty(); + } + } + @Override @Transactional public T loadTraitsForUserAndProject(Key aKey, User aUser, Project aProject) { try { - Optional pref = getUserProjectPreference(aKey, aUser, aProject); + var pref = getUserProjectPreference(aKey, aUser, aProject); if (pref.isPresent()) { - String json = pref.get().getTraits(); + var json = pref.get().getTraits(); T result = JSONUtil.fromJsonString(aKey.getTraitClass(), json); LOG.debug("Loaded preferences for key {} and user {} and project {}: [{}]", aKey, aUser, aProject, result); diff --git a/inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/sidebar/RecommendationSidebarFactory.java b/inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/sidebar/RecommendationSidebarFactory.java index 11e8b29c2f9..5c869ab623b 100644 --- a/inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/sidebar/RecommendationSidebarFactory.java +++ b/inception/inception-recommendation/src/main/java/de/tudarmstadt/ukp/inception/recommendation/sidebar/RecommendationSidebarFactory.java @@ -20,6 +20,7 @@ import org.apache.wicket.Component; import org.apache.wicket.model.IModel; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.annotation.Order; import de.agilecoders.wicket.core.markup.html.bootstrap.image.Icon; import de.agilecoders.wicket.extensions.markup.html.bootstrap.icon.FontAwesome5IconType; @@ -39,6 +40,7 @@ * {@link RecommenderServiceAutoConfiguration#recommendationSidebarFactory}. *

*/ +@Order(5000) public class RecommendationSidebarFactory extends AnnotationSidebarFactory_ImplBase { diff --git a/inception/inception-support-bootstrap/src/main/java/de/tudarmstadt/ukp/inception/bootstrap/IconToggleBox.java b/inception/inception-support-bootstrap/src/main/java/de/tudarmstadt/ukp/inception/bootstrap/IconToggleBox.java index 661b8bf7f59..f997ef2b2d6 100644 --- a/inception/inception-support-bootstrap/src/main/java/de/tudarmstadt/ukp/inception/bootstrap/IconToggleBox.java +++ b/inception/inception-support-bootstrap/src/main/java/de/tudarmstadt/ukp/inception/bootstrap/IconToggleBox.java @@ -24,7 +24,7 @@ import org.apache.wicket.behavior.Behavior; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.FormComponentUpdatingBehavior; -import org.apache.wicket.markup.html.panel.Panel; +import org.apache.wicket.markup.html.panel.GenericPanel; import org.apache.wicket.model.IModel; import de.agilecoders.wicket.core.markup.html.bootstrap.image.IconType; @@ -33,7 +33,7 @@ import de.agilecoders.wicket.extensions.markup.html.bootstrap.icon.FontAwesome5IconType; public class IconToggleBox - extends Panel + extends GenericPanel { private static final long serialVersionUID = 4721646397508723919L; @@ -75,12 +75,14 @@ public MarkupContainer setDefaultModel(IModel aModel) return super.setDefaultModel(aModel); } + @Override public IconToggleBox setModel(IModel aModel) { this.setDefaultModel(aModel); return this; } + @Override @SuppressWarnings("unchecked") public IModel getModel() { diff --git a/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/AnnotationPage.java b/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/AnnotationPage.java index 601ba3d925e..71dce0b5d85 100755 --- a/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/AnnotationPage.java +++ b/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/AnnotationPage.java @@ -354,7 +354,7 @@ private SidebarPanel createLeftSidebar() private WebMarkupContainer createRightSidebar() { - WebMarkupContainer rightSidebar = new WebMarkupContainer("rightSidebar"); + var rightSidebar = new WebMarkupContainer("rightSidebar"); rightSidebar.setOutputMarkupPlaceholderTag(true); // Override sidebar width from preferences rightSidebar.add(new AttributeModifier("style", @@ -372,7 +372,7 @@ private WebMarkupContainer createRightSidebar() @Override public List getListOfDocs() { - AnnotatorState state = getModelObject(); + var state = getModelObject(); return new ArrayList<>(documentService .listAnnotatableDocuments(state.getProject(), state.getUser()).keySet()); } diff --git a/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/config/AnnotationUIAutoConfiguration.java b/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/config/AnnotationUIAutoConfiguration.java index 7840779d383..826572b53cc 100644 --- a/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/config/AnnotationUIAutoConfiguration.java +++ b/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/config/AnnotationUIAutoConfiguration.java @@ -37,6 +37,7 @@ import de.tudarmstadt.ukp.clarin.webanno.ui.annotation.actionbar.undo.actions.SpanAnnotationActionUndoSupport; import de.tudarmstadt.ukp.clarin.webanno.ui.annotation.actionbar.undo.actions.UndoableActionSupportRegistryImpl; import de.tudarmstadt.ukp.clarin.webanno.ui.annotation.actionbar.undo.actions.UndoableAnnotationActionSupport; +import de.tudarmstadt.ukp.clarin.webanno.ui.annotation.sidebar.layer.LayerVisibilitySidebarFactory; import de.tudarmstadt.ukp.inception.project.api.ProjectService; @ConditionalOnWebApplication @@ -92,4 +93,10 @@ public CloseSessionActionBarExtension closeSessionActionBarExtension() { return new CloseSessionActionBarExtension(); } + + @Bean + public LayerVisibilitySidebarFactory layerVisibilitySidebarFactory() + { + return new LayerVisibilitySidebarFactory(); + } } diff --git a/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/AnnotationSidebarFactory_ImplBase.java b/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/AnnotationSidebarFactory_ImplBase.java index 80e78c33d68..06f1d2e1a4b 100644 --- a/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/AnnotationSidebarFactory_ImplBase.java +++ b/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/AnnotationSidebarFactory_ImplBase.java @@ -18,10 +18,9 @@ package de.tudarmstadt.ukp.clarin.webanno.ui.annotation.sidebar; import org.springframework.beans.factory.BeanNameAware; -import org.springframework.core.Ordered; public abstract class AnnotationSidebarFactory_ImplBase - implements BeanNameAware, Ordered, AnnotationSidebarFactory + implements BeanNameAware, AnnotationSidebarFactory { private String beanName; @@ -36,10 +35,4 @@ public String getBeanName() { return beanName; } - - @Override - public int getOrder() - { - return Ordered.LOWEST_PRECEDENCE; - } } diff --git a/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/AnnotationSidebar_ImplBase.java b/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/AnnotationSidebar_ImplBase.java index 58e012ef72f..11ddf6ebf43 100644 --- a/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/AnnotationSidebar_ImplBase.java +++ b/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/AnnotationSidebar_ImplBase.java @@ -20,7 +20,7 @@ import java.io.IOException; import org.apache.wicket.ajax.AjaxRequestTarget; -import org.apache.wicket.markup.html.panel.Panel; +import org.apache.wicket.markup.html.panel.GenericPanel; import org.apache.wicket.model.IModel; import org.apache.wicket.spring.injection.annot.SpringBean; @@ -32,7 +32,7 @@ import de.tudarmstadt.ukp.inception.rendering.editorstate.AnnotatorState; public abstract class AnnotationSidebar_ImplBase - extends Panel + extends GenericPanel { private static final long serialVersionUID = 8637373389151630602L; @@ -59,22 +59,14 @@ public AnnotationSidebar_ImplBase(final String aId, final IModel setOutputMarkupPlaceholderTag(true); } - public void setModel(IModel aModel) - { - setDefaultModel(aModel); - } - + @Override @SuppressWarnings("unchecked") public IModel getModel() { return (IModel) getDefaultModel(); } - public void setModelObject(AnnotatorState aModel) - { - setDefaultModelObject(aModel); - } - + @Override public AnnotatorState getModelObject() { return (AnnotatorState) getDefaultModelObject(); diff --git a/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/SidebarTabbedPanel.java b/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/SidebarTabbedPanel.java index dc6c330131b..9180d40205a 100644 --- a/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/SidebarTabbedPanel.java +++ b/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/SidebarTabbedPanel.java @@ -118,7 +118,7 @@ public TabbedPanel setSelectedTab(int aIndex) private void saveSidebarState() { - AnnotationSidebarState sidebarState = new AnnotationSidebarState(); + var sidebarState = new AnnotationSidebarState(); sidebarState.setSelectedTab(getTabs().get(getSelectedTab()).getFactoryId()); sidebarState.setExpanded(expanded); User user = userService.getCurrentUser(); @@ -128,9 +128,9 @@ private void saveSidebarState() private void loadSidebarState() { - User user = userService.getCurrentUser(); - AnnotationSidebarState sidebarState = prefService.loadTraitsForUserAndProject( - KEY_SIDEBAR_STATE, user, state.getObject().getProject()); + var user = userService.getCurrentUser(); + var sidebarState = prefService.loadTraitsForUserAndProject(KEY_SIDEBAR_STATE, user, + state.getObject().getProject()); if (isNotBlank(sidebarState.getSelectedTab())) { var tabFactories = getTabs().stream().map(SidebarTab::getFactoryId) .collect(Collectors.toList()); diff --git a/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/docinfo/DocumentInfoSidebarFactory.java b/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/docinfo/DocumentInfoSidebarFactory.java index b7dedaa58ac..acee3bcb1a0 100644 --- a/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/docinfo/DocumentInfoSidebarFactory.java +++ b/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/docinfo/DocumentInfoSidebarFactory.java @@ -19,6 +19,7 @@ import org.apache.wicket.Component; import org.apache.wicket.model.IModel; +import org.springframework.core.annotation.Order; import de.agilecoders.wicket.core.markup.html.bootstrap.image.Icon; import de.agilecoders.wicket.extensions.markup.html.bootstrap.icon.FontAwesome5IconType; @@ -31,6 +32,7 @@ import de.tudarmstadt.ukp.inception.rendering.editorstate.AnnotatorState; // This now mainly serves as example code - we do not actually use it +@Order(1) public class DocumentInfoSidebarFactory extends AnnotationSidebarFactory_ImplBase { diff --git a/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/layer/LayerVisibilitySidebar.html b/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/layer/LayerVisibilitySidebar.html new file mode 100644 index 00000000000..1d5dfe6454e --- /dev/null +++ b/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/layer/LayerVisibilitySidebar.html @@ -0,0 +1,37 @@ + + + + +
+
+
+ +
+
+
    +
  • + + +
  • +
+
+
+
+
+ diff --git a/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/layer/LayerVisibilitySidebar.java b/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/layer/LayerVisibilitySidebar.java new file mode 100644 index 00000000000..00d6fa6f2fa --- /dev/null +++ b/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/layer/LayerVisibilitySidebar.java @@ -0,0 +1,117 @@ +/* + * 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.clarin.webanno.ui.annotation.sidebar.layer; + +import static de.tudarmstadt.ukp.inception.support.lambda.HtmlElementEvents.CHANGE_EVENT; + +import java.io.IOException; +import java.util.List; + +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.markup.html.list.ListItem; +import org.apache.wicket.markup.html.list.ListView; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.LoadableDetachableModel; +import org.apache.wicket.model.Model; +import org.apache.wicket.spring.injection.annot.SpringBean; + +import de.agilecoders.wicket.extensions.markup.html.bootstrap.icon.FontAwesome5IconType; +import de.tudarmstadt.ukp.clarin.webanno.api.annotation.preferences.UserPreferencesService; +import de.tudarmstadt.ukp.clarin.webanno.api.casstorage.CasProvider; +import de.tudarmstadt.ukp.clarin.webanno.model.AnnotationLayer; +import de.tudarmstadt.ukp.clarin.webanno.security.UserDao; +import de.tudarmstadt.ukp.clarin.webanno.ui.annotation.AnnotationPage; +import de.tudarmstadt.ukp.clarin.webanno.ui.annotation.sidebar.AnnotationSidebar_ImplBase; +import de.tudarmstadt.ukp.inception.bootstrap.IconToggleBox; +import de.tudarmstadt.ukp.inception.editor.action.AnnotationActionHandler; +import de.tudarmstadt.ukp.inception.rendering.editorstate.AnnotatorState; +import de.tudarmstadt.ukp.inception.schema.api.AnnotationSchemaService; +import de.tudarmstadt.ukp.inception.schema.api.config.AnnotationSchemaProperties; +import de.tudarmstadt.ukp.inception.support.lambda.LambdaAjaxFormComponentUpdatingBehavior; + +public class LayerVisibilitySidebar + extends AnnotationSidebar_ImplBase +{ + private static final long serialVersionUID = 6127948490101336779L; + + private @SpringBean AnnotationSchemaService annotationService; + private @SpringBean AnnotationSchemaProperties annotationEditorProperties; + private @SpringBean UserPreferencesService userPreferencesService; + private @SpringBean UserDao userService; + + public LayerVisibilitySidebar(String aId, IModel aModel, + AnnotationActionHandler aActionHandler, CasProvider aCasProvider, + AnnotationPage aAnnotationPage) + { + super(aId, aModel, aActionHandler, aCasProvider, aAnnotationPage); + + add(createLayerContainer("annotationLayers", LoadableDetachableModel.of(this::listLayers))); + } + + private List listLayers() + { + return annotationService.listSupportedLayers(getModelObject().getProject()).stream() // + .filter(AnnotationLayer::isEnabled) // + .filter(layer -> !annotationEditorProperties.isLayerBlocked(layer)) // + .toList(); + } + + private void actionToggleVisibility(AnnotationLayer aLayer, boolean aHidden, + AjaxRequestTarget aTarget) + throws IOException + { + getModelObject().getPreferences().setLayerVisible(aLayer, !aHidden); + + var sessionOwner = userService.getCurrentUsername(); + userPreferencesService.savePreferences(getModelObject(), sessionOwner); + userPreferencesService.loadPreferences(getModelObject(), sessionOwner); + + getAnnotationPage().actionRefreshDocument(aTarget); + } + + private ListView createLayerContainer(String aId, + IModel> aLayers) + { + return new ListView(aId, aLayers) + { + private static final long serialVersionUID = -4040731191748923013L; + + @Override + protected void populateItem(ListItem aItem) + { + var prefs = LayerVisibilitySidebar.this.getModelObject().getPreferences(); + var layer = aItem.getModelObject(); + var hiddenLayerIds = prefs.getHiddenAnnotationLayerIds(); + + var layerVisible = new IconToggleBox("annotationLayerActive") // + .setCheckedIcon(FontAwesome5IconType.eye_s) + .setCheckedTitle(Model.of("Visible")) + .setUncheckedIcon(FontAwesome5IconType.eye_slash_s) + .setUncheckedTitle(Model.of("Hidden")) + .setModel(Model.of(!hiddenLayerIds.contains(layer.getId()))); + layerVisible.add(new LambdaAjaxFormComponentUpdatingBehavior(CHANGE_EVENT, + _target -> actionToggleVisibility(layer, layerVisible.getModelObject(), + _target))); + aItem.add(layerVisible); + + aItem.add(new Label("annotationLayerDesc", layer.getUiName())); + } + }; + } +} diff --git a/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/layer/LayerVisibilitySidebar.properties b/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/layer/LayerVisibilitySidebar.properties new file mode 100644 index 00000000000..ebfb183fda5 --- /dev/null +++ b/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/layer/LayerVisibilitySidebar.properties @@ -0,0 +1,18 @@ +# 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. +layers=Layers +layer=Layer +show=Show diff --git a/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/layer/LayerVisibilitySidebarFactory.java b/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/layer/LayerVisibilitySidebarFactory.java new file mode 100644 index 00000000000..1ff683b3b6d --- /dev/null +++ b/inception/inception-ui-annotation/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/annotation/sidebar/layer/LayerVisibilitySidebarFactory.java @@ -0,0 +1,63 @@ +/* + * 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.clarin.webanno.ui.annotation.sidebar.layer; + +import org.apache.wicket.Component; +import org.apache.wicket.model.IModel; +import org.springframework.core.annotation.Order; + +import de.agilecoders.wicket.core.markup.html.bootstrap.image.Icon; +import de.agilecoders.wicket.extensions.markup.html.bootstrap.icon.FontAwesome5IconType; +import de.tudarmstadt.ukp.clarin.webanno.api.casstorage.CasProvider; +import de.tudarmstadt.ukp.clarin.webanno.ui.annotation.AnnotationPage; +import de.tudarmstadt.ukp.clarin.webanno.ui.annotation.sidebar.AnnotationSidebarFactory_ImplBase; +import de.tudarmstadt.ukp.clarin.webanno.ui.annotation.sidebar.AnnotationSidebar_ImplBase; +import de.tudarmstadt.ukp.inception.editor.action.AnnotationActionHandler; +import de.tudarmstadt.ukp.inception.rendering.editorstate.AnnotatorState; + +@Order(2000) +public class LayerVisibilitySidebarFactory + extends AnnotationSidebarFactory_ImplBase +{ + @Override + public String getDisplayName() + { + return "Layers"; + } + + @Override + public String getDescription() + { + return "Allows showing/hiding layers"; + } + + @Override + public Component createIcon(String aId, IModel aState) + { + return new Icon(aId, FontAwesome5IconType.layer_group_s); + } + + @Override + public AnnotationSidebar_ImplBase create(String aId, IModel aModel, + AnnotationActionHandler aActionHandler, CasProvider aCasProvider, + AnnotationPage aAnnotationPage) + { + return new LayerVisibilitySidebar(aId, aModel, aActionHandler, aCasProvider, + aAnnotationPage); + } +} diff --git a/inception/inception-ui-curation/src/main/java/de/tudarmstadt/ukp/inception/ui/curation/sidebar/CurationSidebarFactory.java b/inception/inception-ui-curation/src/main/java/de/tudarmstadt/ukp/inception/ui/curation/sidebar/CurationSidebarFactory.java index aeed0f1ad51..ba4ad5e03c7 100644 --- a/inception/inception-ui-curation/src/main/java/de/tudarmstadt/ukp/inception/ui/curation/sidebar/CurationSidebarFactory.java +++ b/inception/inception-ui-curation/src/main/java/de/tudarmstadt/ukp/inception/ui/curation/sidebar/CurationSidebarFactory.java @@ -24,6 +24,7 @@ import org.apache.wicket.Component; import org.apache.wicket.model.IModel; import org.slf4j.Logger; +import org.springframework.core.annotation.Order; import de.tudarmstadt.ukp.clarin.webanno.api.casstorage.CasProvider; import de.tudarmstadt.ukp.clarin.webanno.security.UserDao; @@ -41,6 +42,7 @@ * {@link CurationSidebarAutoConfiguration#curationSidebarFactory}. *

*/ +@Order(3000) public class CurationSidebarFactory extends AnnotationSidebarFactory_ImplBase { diff --git a/inception/inception-ui-external-search/src/main/java/de/tudarmstadt/ukp/inception/app/ui/externalsearch/sidebar/ExternalSearchAnnotationSidebarFactory.java b/inception/inception-ui-external-search/src/main/java/de/tudarmstadt/ukp/inception/app/ui/externalsearch/sidebar/ExternalSearchAnnotationSidebarFactory.java index 3219d91babe..174509389cf 100644 --- a/inception/inception-ui-external-search/src/main/java/de/tudarmstadt/ukp/inception/app/ui/externalsearch/sidebar/ExternalSearchAnnotationSidebarFactory.java +++ b/inception/inception-ui-external-search/src/main/java/de/tudarmstadt/ukp/inception/app/ui/externalsearch/sidebar/ExternalSearchAnnotationSidebarFactory.java @@ -19,6 +19,7 @@ import org.apache.wicket.Component; import org.apache.wicket.model.IModel; +import org.springframework.core.annotation.Order; import de.agilecoders.wicket.core.markup.html.bootstrap.image.Icon; import de.agilecoders.wicket.extensions.markup.html.bootstrap.icon.FontAwesome5IconType; @@ -39,6 +40,7 @@ * {@link ExternalSearchUIAutoConfiguration#externalSearchAnnotationSidebarFactory}. *

*/ +@Order(3600) public class ExternalSearchAnnotationSidebarFactory extends AnnotationSidebarFactory_ImplBase { diff --git a/inception/inception-ui-search/pom.xml b/inception/inception-ui-search/pom.xml index 139e1b9370a..6f0dfc933b7 100644 --- a/inception/inception-ui-search/pom.xml +++ b/inception/inception-ui-search/pom.xml @@ -87,6 +87,10 @@ commons-collections4
+ + org.springframework + spring-core + org.springframework spring-context diff --git a/inception/inception-ui-search/src/main/java/de/tudarmstadt/ukp/inception/app/ui/search/sidebar/SearchAnnotationSidebarFactory.java b/inception/inception-ui-search/src/main/java/de/tudarmstadt/ukp/inception/app/ui/search/sidebar/SearchAnnotationSidebarFactory.java index 6076ef1cdd6..9ed206e2b0e 100644 --- a/inception/inception-ui-search/src/main/java/de/tudarmstadt/ukp/inception/app/ui/search/sidebar/SearchAnnotationSidebarFactory.java +++ b/inception/inception-ui-search/src/main/java/de/tudarmstadt/ukp/inception/app/ui/search/sidebar/SearchAnnotationSidebarFactory.java @@ -19,6 +19,7 @@ import org.apache.wicket.Component; import org.apache.wicket.model.IModel; +import org.springframework.core.annotation.Order; import de.agilecoders.wicket.core.markup.html.bootstrap.image.Icon; import de.agilecoders.wicket.extensions.markup.html.bootstrap.icon.FontAwesome5IconType; @@ -36,6 +37,7 @@ * {@link SearchServiceUIAutoConfiguration#searchAnnotationSidebarFactory}. *

*/ +@Order(3500) public class SearchAnnotationSidebarFactory extends AnnotationSidebarFactory_ImplBase { diff --git a/inception/inception-ui-search/src/main/java/de/tudarmstadt/ukp/inception/app/ui/search/sidebar/StatisticsAnnotationSidebarFactory.java b/inception/inception-ui-search/src/main/java/de/tudarmstadt/ukp/inception/app/ui/search/sidebar/StatisticsAnnotationSidebarFactory.java index a0be99f7f42..fea108d8865 100644 --- a/inception/inception-ui-search/src/main/java/de/tudarmstadt/ukp/inception/app/ui/search/sidebar/StatisticsAnnotationSidebarFactory.java +++ b/inception/inception-ui-search/src/main/java/de/tudarmstadt/ukp/inception/app/ui/search/sidebar/StatisticsAnnotationSidebarFactory.java @@ -19,6 +19,7 @@ import org.apache.wicket.Component; import org.apache.wicket.model.IModel; +import org.springframework.core.annotation.Order; import de.agilecoders.wicket.core.markup.html.bootstrap.image.Icon; import de.agilecoders.wicket.extensions.markup.html.bootstrap.icon.FontAwesome5IconType; @@ -36,6 +37,7 @@ * {@link StatsServiceUIAutoConfiguration#statisticsAnnotationSidebarFactory}. *

*/ +@Order(11000) public class StatisticsAnnotationSidebarFactory extends AnnotationSidebarFactory_ImplBase {