diff --git a/inception/inception-model/src/main/java/de/tudarmstadt/ukp/clarin/webanno/model/AnnotationLayer.java b/inception/inception-model/src/main/java/de/tudarmstadt/ukp/clarin/webanno/model/AnnotationLayer.java index a88d0b2328e..c61412fcea6 100644 --- a/inception/inception-model/src/main/java/de/tudarmstadt/ukp/clarin/webanno/model/AnnotationLayer.java +++ b/inception/inception-model/src/main/java/de/tudarmstadt/ukp/clarin/webanno/model/AnnotationLayer.java @@ -19,6 +19,8 @@ import static jakarta.persistence.ConstraintMode.NO_CONSTRAINT; import static java.util.Arrays.asList; +import static org.apache.commons.lang3.StringUtils.isBlank; +import static org.apache.commons.lang3.StringUtils.substringAfterLast; import java.io.Serializable; @@ -63,9 +65,15 @@ public class AnnotationLayer @Column(name = "id") private Long id; + @Column(name = "name", nullable = false) + private String name; + @Column(nullable = false) private String uiName; + @Column(name = "short_name", nullable = true) + private String shortName; + @Column(nullable = false) private String type; @@ -82,9 +90,6 @@ public class AnnotationLayer @Column(length = 64000) private String onClickJavascriptAction; - @Column(name = "name", nullable = false) - private String name; - @ManyToOne // @ForeignKey(ConstraintMode.NO_CONSTRAINT) @JoinColumn(name = "annotation_type", // @@ -148,6 +153,7 @@ private AnnotationLayer(Builder builder) { this.id = builder.id; this.uiName = builder.uiName; + this.shortName = builder.shortName; this.type = builder.type; this.description = builder.description; this.enabled = builder.enabled; @@ -223,6 +229,29 @@ public void setDescription(String aDescription) description = aDescription; } + /** + * The name under which the layer should be accessible when searching + * + * @param aShortName + */ + public void setShortName(String aShortName) + { + shortName = aShortName; + } + + public String getShortName() + { + if (isBlank(shortName)) { + if (name != null && name.contains(".")) { + return substringAfterLast(name, "."); + } + + return name; + } + + return shortName; + } + /** * The name displayed to the user in the UI. * @@ -588,14 +617,15 @@ public static Builder builder() public static final class Builder { private Long id; + private String name; private String uiName; + private String shortName; private String type; private String description; private boolean enabled = true; private boolean builtIn = false; private boolean readonly = false; private String onClickJavascriptAction; - private String name; private AnnotationLayer attachType; private AnnotationFeature attachFeature; private Project project; @@ -638,6 +668,12 @@ public Builder withUiName(String aUiName) return this; } + public Builder withShortName(String aShortName) + { + shortName = aShortName; + return this; + } + public Builder withType(String aType) { type = aType; diff --git a/inception/inception-model/src/main/resources/de/tudarmstadt/ukp/clarin/webanno/model/db-changelog.xml b/inception/inception-model/src/main/resources/de/tudarmstadt/ukp/clarin/webanno/model/db-changelog.xml index 8e642de4c80..a5546800ae4 100644 --- a/inception/inception-model/src/main/resources/de/tudarmstadt/ukp/clarin/webanno/model/db-changelog.xml +++ b/inception/inception-model/src/main/resources/de/tudarmstadt/ukp/clarin/webanno/model/db-changelog.xml @@ -1401,7 +1401,18 @@ ALTER TABLE annotation_feature ALTER "curatable" TYPE BOOLEAN USING ("curatable"::int::bool) - + + + + + + + + + + + + diff --git a/inception/inception-schema-api/src/main/java/de/tudarmstadt/ukp/inception/schema/api/AnnotationSchemaService.java b/inception/inception-schema-api/src/main/java/de/tudarmstadt/ukp/inception/schema/api/AnnotationSchemaService.java index 749f8d8ef20..d627ca00ad2 100644 --- a/inception/inception-schema-api/src/main/java/de/tudarmstadt/ukp/inception/schema/api/AnnotationSchemaService.java +++ b/inception/inception-schema-api/src/main/java/de/tudarmstadt/ukp/inception/schema/api/AnnotationSchemaService.java @@ -182,6 +182,17 @@ public interface AnnotationSchemaService */ boolean existsLayer(String name, Project project); + /** + * Check if an {@link AnnotationLayer} exists with this short name in the given {@link Project}. + * + * @param shortName + * the layer name. + * @param project + * the project. + * @return if the layer exists. + */ + boolean existsLayerWithShortName(String shortName, Project project); + /** * check if an {@link AnnotationLayer} exists with this name and type in this {@link Project} * diff --git a/inception/inception-schema/src/main/java/de/tudarmstadt/ukp/inception/schema/service/AnnotationSchemaServiceImpl.java b/inception/inception-schema/src/main/java/de/tudarmstadt/ukp/inception/schema/service/AnnotationSchemaServiceImpl.java index f33552d24f4..13d69f64d13 100644 --- a/inception/inception-schema/src/main/java/de/tudarmstadt/ukp/inception/schema/service/AnnotationSchemaServiceImpl.java +++ b/inception/inception-schema/src/main/java/de/tudarmstadt/ukp/inception/schema/service/AnnotationSchemaServiceImpl.java @@ -437,6 +437,23 @@ public boolean existsLayer(String aName, Project aProject) } } + @Override + @Transactional(noRollbackFor = NoResultException.class, readOnly = true) + public boolean existsLayerWithShortName(String aShortName, Project aProject) + { + try { + entityManager.createQuery( + "FROM AnnotationLayer WHERE shortName = :shortName AND project = :project", + AnnotationLayer.class).setParameter("shortName", aShortName) // + .setParameter("project", aProject) // + .getSingleResult(); + return true; + } + catch (NoResultException e) { + return false; + } + } + @Override @Transactional(noRollbackFor = NoResultException.class, readOnly = true) public boolean existsLayer(String aName, String aType, Project aProject) diff --git a/inception/inception-ui-core/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/core/WicketApplicationBase.utf8.properties b/inception/inception-ui-core/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/core/WicketApplicationBase.utf8.properties index 2deced219aa..eb530b0112c 100644 --- a/inception/inception-ui-core/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/core/WicketApplicationBase.utf8.properties +++ b/inception/inception-ui-core/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/core/WicketApplicationBase.utf8.properties @@ -47,6 +47,7 @@ enabled=Enabled id=ID name=Name +shortName=Short name slug=URL slug description=Description format=Format diff --git a/inception/inception-ui-project/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/project/layers/LayerDetailForm.java b/inception/inception-ui-project/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/project/layers/LayerDetailForm.java index fb8794aa01f..2f5a5ce304c 100644 --- a/inception/inception-ui-project/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/project/layers/LayerDetailForm.java +++ b/inception/inception-ui-project/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/project/layers/LayerDetailForm.java @@ -100,6 +100,7 @@ public class LayerDetailForm private DropDownChoice attachTypeSelect; private Label effectiveAttachType; private TextField uiName; + private TextField shortName; private FeatureSelectionForm featureSelectionForm; private FeatureDetailForm featureDetailForm; @@ -127,6 +128,11 @@ public LayerDetailForm(String id, IModel aSelectedLayer, uiName.setOutputMarkupId(true); uiName.setRequired(true); add(uiName); + + shortName = new TextField("shortName"); + shortName.setOutputMarkupId(true); + add(shortName); + add(new TextArea("description").setOutputMarkupPlaceholderTag(true)); add(new Label("name").add(visibleWhen(() -> isNotBlank(getModelObject().getName())))); @@ -373,6 +379,13 @@ private void actionSave(AjaxRequestTarget aTarget, Form aForm) return; } + if (annotationService.existsLayerWithShortName(shortLayerName, project)) { + error("A layer with the short name [" + shortLayerName + + "] already exists in this project."); + return; + } + + layer.setShortName(shortLayerName); layer.setName(layerName); } diff --git a/inception/inception-ui-project/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/project/layers/ProjectLayersPanel.html b/inception/inception-ui-project/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/project/layers/ProjectLayersPanel.html index 7734526341c..5cb4d2e4bb1 100644 --- a/inception/inception-ui-project/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/project/layers/ProjectLayersPanel.html +++ b/inception/inception-ui-project/src/main/java/de/tudarmstadt/ukp/clarin/webanno/ui/project/layers/ProjectLayersPanel.html @@ -154,6 +154,12 @@ +
+ + +