ref #2975 add noDataStatus to descriptive data
authorAndreas Müller <a.mueller@bgbm.org>
Tue, 27 Jun 2023 09:41:28 +0000 (11:41 +0200)
committerAndreas Müller <a.mueller@bgbm.org>
Wed, 5 Jul 2023 12:56:32 +0000 (14:56 +0200)
cdmlib-model/src/main/java/eu/etaxonomy/cdm/format/description/CategoricalDataFormatter.java
cdmlib-model/src/main/java/eu/etaxonomy/cdm/format/description/QuantitativeDataFormatter.java
cdmlib-model/src/main/java/eu/etaxonomy/cdm/hibernate/EnumUserType.java
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/description/CategoricalData.java
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/description/NoDescriptiveDataStatus.java [new file with mode: 0644]
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/description/QuantitativeData.java
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/metadata/CdmMetaData.java
cdmlib-model/src/test/java/eu/etaxonomy/cdm/format/description/CategoricalDataFormatterTest.java
cdmlib-model/src/test/java/eu/etaxonomy/cdm/format/description/QuantitativeDataFormatterTest.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/database/update/CdmUpdater.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/database/update/v538_540/SchemaUpdater_5380_5400.java [new file with mode: 0644]

index f7c4f5e291cca48691bc785b2d611a2179918068..b0b461189f624eb26444ea5e400746ef88386391 100644 (file)
@@ -10,6 +10,8 @@ package eu.etaxonomy.cdm.format.description;
 
 import java.util.List;
 
+import org.apache.commons.lang3.StringUtils;
+
 import eu.etaxonomy.cdm.common.CdmUtils;
 import eu.etaxonomy.cdm.model.common.Language;
 import eu.etaxonomy.cdm.model.description.CategoricalData;
@@ -38,6 +40,10 @@ public class CategoricalDataFormatter
     protected String doFormat(CategoricalData catData, List<Language> preferredLanguages) {
         List<StateData> stateDatas = catData.getStateData();
         String stateDataText = getStateDatasText(stateDatas, preferredLanguages);
+        if (catData.getNoDataStatus() != null) {
+            String noDataStatus = catData.getNoDataStatus().getLabel();
+            stateDataText = StringUtils.isEmpty(stateDataText) ? noDataStatus : noDataStatus +" (" + stateDataText + ")";
+        }
         return stateDataText;
     }
 
index d60e1fb6ac196af9b49da60612f22ccdd084a45e..c0a0d17f9b14e732504a945156709412a3367842 100644 (file)
@@ -11,6 +11,8 @@ package eu.etaxonomy.cdm.format.description;
 import java.math.BigDecimal;
 import java.util.List;
 
+import org.apache.commons.lang3.StringUtils;
+
 import eu.etaxonomy.cdm.common.CdmUtils;
 import eu.etaxonomy.cdm.common.UTF8;
 import eu.etaxonomy.cdm.model.common.Language;
@@ -123,10 +125,14 @@ public class QuantitativeDataFormatter
         BigDecimal n = quantData.getSampleSize();
         String size = (n == null) ? "" : "n="+String.valueOf(n);
         String strBracket = isNotBlank(size) ? "[" + size + "]" : "";
+        result = CdmUtils.concat(" ", result, strBracket);
 
-        //modif
+        //no data status
+        if (quantData.getNoDataStatus() != null) {
+            String noDataStatus = quantData.getNoDataStatus().getLabel();
+            result = StringUtils.isEmpty(result) ? noDataStatus : noDataStatus +" (" + result + ")";
+        }
 
-        result = CdmUtils.concat(" ", result, strBracket);
         return result;
     }
 }
\ No newline at end of file
index c3261d43e6b902537bc5419ac188ee092cc1a1c1..07b298268c7df7d774ff7f14b085f478550d34a4 100644 (file)
@@ -29,6 +29,7 @@ import eu.etaxonomy.cdm.model.common.AuthorityType;
 import eu.etaxonomy.cdm.model.common.CdmClass;
 import eu.etaxonomy.cdm.model.common.ExternallyManagedImport;
 import eu.etaxonomy.cdm.model.description.DescriptionType;
+import eu.etaxonomy.cdm.model.description.NoDescriptiveDataStatus;
 import eu.etaxonomy.cdm.model.media.ExternalLinkType;
 import eu.etaxonomy.cdm.model.metadata.CdmMetaDataPropertyName;
 import eu.etaxonomy.cdm.model.molecular.SequenceDirection;
@@ -184,6 +185,9 @@ public class EnumUserType<E extends Enum<E>>
         //AuthorityType
         }else if (clazz.equals(AuthorityType.class)){
             return AuthorityType.getByKey(val);
+        //NoDescriptiveDataStatus
+        }else if (clazz.equals(NoDescriptiveDataStatus.class)){
+            return NoDescriptiveDataStatus.getByKey(val);
         }else{
                throw new IllegalArgumentException(String.format("EnumType %s not supported by %s.", clazz.getSimpleName(), EnumUserType.class.getSimpleName()));
         }
index 4216230abba75679c5a693489d6104804eff4688..f756bd32213bc5395ed36d3d59a2015ae0723508 100644 (file)
@@ -12,6 +12,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
+import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.OneToMany;
@@ -19,6 +20,7 @@ import javax.persistence.Transient;
 import javax.validation.constraints.NotEmpty;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
@@ -29,6 +31,7 @@ import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.hibernate.annotations.Cascade;
 import org.hibernate.annotations.CascadeType;
+import org.hibernate.annotations.Type;
 import org.hibernate.envers.Audited;
 import org.hibernate.search.annotations.Indexed;
 import org.hibernate.search.annotations.IndexedEmbedded;
@@ -85,8 +88,17 @@ public class CategoricalData extends DescriptionElementBase {
     private List<StateData> stateData = new ArrayList<>();
 
     @XmlElement(name = "UnknownData")
+    @Deprecated   //will be replaced by #noDataStatus
     private final Boolean unknownData = false;
 
+    @XmlAttribute(name ="NoDataStatus")
+    @Column(name="noDataStatus", length=10)
+    @Type(type = "eu.etaxonomy.cdm.hibernate.EnumUserType",
+        parameters = {@org.hibernate.annotations.Parameter(name = "enumClass", value = "eu.etaxonomy.cdm.model.description.NoDescriptiveDataStatus")}
+    )
+    //see also QuantitativeData.noDataStatus
+    private NoDescriptiveDataStatus noDataStatus;
+
 //****************************** FACTORY METHOD *******************************/
 
     /**
@@ -204,6 +216,14 @@ public class CategoricalData extends DescriptionElementBase {
         this.orderRelevant = orderRelevant;
     }
 
+    //no data status, #2975
+    public NoDescriptiveDataStatus getNoDataStatus() {
+        return noDataStatus;
+    }
+    public void setNoDataStatus(NoDescriptiveDataStatus noDataStatus) {
+        this.noDataStatus = noDataStatus;
+    }
+
 // ********************* CONVENIENCE ******************************************/
 
     /**
@@ -263,7 +283,7 @@ public class CategoricalData extends DescriptionElementBase {
         return (getFeature()!=null ? getFeature().getLabel(): "") +
                 "[" + stateData +
                     (orderRelevant? ", orderRelevant=" + orderRelevant:"") +
-                    (unknownData? ", unknownData=" + unknownData:"")
+                    (noDataStatus != null ? ", noDataStatus=" + noDataStatus.getLabel() :"")
                 + "]";
     }
 
diff --git a/cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/description/NoDescriptiveDataStatus.java b/cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/description/NoDescriptiveDataStatus.java
new file mode 100644 (file)
index 0000000..9f6cb1f
--- /dev/null
@@ -0,0 +1,92 @@
+/**
+* Copyright (C) 2023 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+package eu.etaxonomy.cdm.model.description;
+
+import java.util.Set;
+import java.util.UUID;
+
+import javax.xml.bind.annotation.XmlEnumValue;
+
+import eu.etaxonomy.cdm.model.common.Language;
+import eu.etaxonomy.cdm.model.term.EnumeratedTermVoc;
+import eu.etaxonomy.cdm.model.term.IEnumTerm;
+
+/**
+ * Enumeration describing why descriptive data are not available.
+ * The enumeration values are taken from SDD.
+ *
+ * @see https://dev.e-taxonomy.eu/redmine/issues/2975
+ *
+ * @author a.mueller
+ * @date 27.06.2023
+ */
+public enum NoDescriptiveDataStatus implements IEnumTerm<NoDescriptiveDataStatus> {
+
+    @XmlEnumValue("NotApllicable")
+    NotApllicable(UUID.fromString("d8c7eedd-cd84-41e3-954f-910d73a367b0"), "not applicable","NA"),
+
+    @XmlEnumValue("DataUnavailable")
+    DataUnavailable(UUID.fromString("9826baa6-0bdb-4efa-957a-b5d4f0f4d7cc"), "data unavailable","DU"),
+
+    @XmlEnumValue("ToBeIgnored")
+    ToBeIgnored(UUID.fromString("47d3a9e6-22b5-4d12-bb53-c8a92afe5e83"), "to be ignored","TBI"),
+
+    @XmlEnumValue("ToBeChecked")
+    ToBeChecked(UUID.fromString("52952fe5-cb3d-4ab9-80a9-5cc93587cd0c"), "to be checked","TBC"),
+
+    @XmlEnumValue("NotInterpretable")
+    NotInterpretable(UUID.fromString("22305490-8ea5-487c-9068-b90d16045c8c"), "Not applicable","NI"),
+
+    @XmlEnumValue("DataWithheld")
+    DataWithheld(UUID.fromString("05b2abcf-0d41-463c-bd83-30a268fa32ae"), "data withheld","DW");
+
+    private NoDescriptiveDataStatus(UUID uuid, String defaultString, String key) {
+        this(uuid, defaultString, key, null);
+    }
+    private NoDescriptiveDataStatus(UUID uuid, String defaultString, String key, NoDescriptiveDataStatus parent) {
+        delegateVocTerm = EnumeratedTermVoc.addTerm(getClass(), this, uuid, defaultString, key, parent);
+    }
+
+    // *************************** DELEGATE **************************************/
+
+    private static EnumeratedTermVoc<NoDescriptiveDataStatus> delegateVoc;
+    private IEnumTerm<NoDescriptiveDataStatus> delegateVocTerm;
+
+    static {
+        delegateVoc = EnumeratedTermVoc.getVoc(NoDescriptiveDataStatus.class);
+    }
+
+    @Override
+    public String getKey(){return delegateVocTerm.getKey();}
+
+    @Override
+    public String getLabel(){return delegateVocTerm.getLabel();}
+
+    @Override
+    public String getLabel(Language language){return delegateVocTerm.getLabel(language);}
+
+
+    @Override
+    public UUID getUuid() {return delegateVocTerm.getUuid();}
+
+    @Override
+    public NoDescriptiveDataStatus getKindOf() {return delegateVocTerm.getKindOf();}
+
+    @Override
+    public Set<NoDescriptiveDataStatus> getGeneralizationOf() {return delegateVocTerm.getGeneralizationOf();}
+
+    @Override
+    public boolean isKindOf(NoDescriptiveDataStatus ancestor) {return delegateVocTerm.isKindOf(ancestor); }
+
+    @Override
+    public Set<NoDescriptiveDataStatus> getGeneralizationOf(boolean recursive) {return delegateVocTerm.getGeneralizationOf(recursive);}
+
+    public static NoDescriptiveDataStatus getByKey(String key){return delegateVoc.getByKey(key);}
+    public static NoDescriptiveDataStatus getByUuid(UUID uuid) {return delegateVoc.getByUuid(uuid);}
+}
\ No newline at end of file
index 89003e298bc60f960ffe7bd979ab74d63fb622b9..77e0dddef8d3e4e678b8bd5f073a6f6c87b1f56c 100644 (file)
@@ -14,6 +14,7 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;
 
+import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.ManyToOne;
@@ -22,6 +23,7 @@ import javax.persistence.Transient;
 import javax.validation.constraints.NotEmpty;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlIDREF;
@@ -34,6 +36,7 @@ import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.hibernate.annotations.Cascade;
 import org.hibernate.annotations.CascadeType;
+import org.hibernate.annotations.Type;
 import org.hibernate.envers.Audited;
 import org.hibernate.search.annotations.Indexed;
 
@@ -117,8 +120,17 @@ public class QuantitativeData
 //     private Integer sampleSize;
 
        @XmlElement(name = "UnknownData")
+    @Deprecated   //will be replaced by #noDataStatus
        private Boolean unknownData = false;
 
+    @XmlAttribute(name ="NoDataStatus")
+    @Column(name="noDataStatus", length=10)
+    @Type(type = "eu.etaxonomy.cdm.hibernate.EnumUserType",
+        parameters = {@org.hibernate.annotations.Parameter(name = "enumClass", value = "eu.etaxonomy.cdm.model.description.NoDescriptiveDataStatus")}
+    )
+    //see also CategoricalData.noDataStatus
+    private NoDescriptiveDataStatus noDataStatus;
+
 // ******************************** FACTORY METHODS *******************************/
 
        /**
@@ -574,14 +586,23 @@ public class QuantitativeData
 //        return result;
 //    }
 
+    @Deprecated   //will be replaced by #noDataStatus
        public Boolean getUnknownData() {
                return unknownData;
        }
-
+    @Deprecated   //will be replaced by #noDataStatus
        public void setUnknownData(Boolean unknownData) {
                this.unknownData = unknownData;
        }
 
+    //no data status, #2975
+    public NoDescriptiveDataStatus getNoDataStatus() {
+        return noDataStatus;
+    }
+    public void setNoDataStatus(NoDescriptiveDataStatus noDataStatus) {
+        this.noDataStatus = noDataStatus;
+    }
+
 //
 //     public BigDecimal getMinimum() {
 //             return minimum;
@@ -671,8 +692,7 @@ public class QuantitativeData
         return (getFeature()!=null ? getFeature().getLabel(): "") +
                 "[" + statisticalValues +
                 (unit!=null ? ", unit=" + unit : "") +
-                (unknownData? ", unknownData=" + unknownData:"")
+                (noDataStatus != null ? ", noDataStatus=" + noDataStatus.getLabel() :"")
                 + "]";
        }
-
-}
+}
\ No newline at end of file
index 757951692a0c580039c34d51ab84d02b039f4113..6d0e1af65669ec1e1cde32767e399cabbcfb3d98 100644 (file)
@@ -53,7 +53,7 @@ public class CdmMetaData extends CdmBase{
         * be handled by SCHEMA_VALIDATION.UPDATE
         * The last number represents the date of change.
         */
-       private static final String dbSchemaVersion = CdmVersion.V_05_38_00.versionString;
+       private static final String dbSchemaVersion = CdmVersion.V_05_40_00.versionString;
 
        public enum CdmVersion {
            V_05_12_00("5.12.0.0.20191202"),
@@ -80,7 +80,8 @@ public class CdmMetaData extends CdmBase{
         V_05_35_01("5.35.1.0.20221218"),
         V_05_36_00("5.36.0.0.20230106"),
         V_05_36_01("5.36.1.0.20230323"),
-        V_05_38_00("5.38.0.0.20230510")
+        V_05_38_00("5.38.0.0.20230510"),
+        V_05_40_00("5.40.0.0.20230627")
         ;
 
         private String versionString;
index 6bd3878021ccc26fcf68e99b67bfb501677f9dc2..606e4ecd30664ee697ab2bf74801e9cf482f6bb3 100644 (file)
@@ -16,6 +16,7 @@ import eu.etaxonomy.cdm.format.ICdmFormatter.FormatKey;
 import eu.etaxonomy.cdm.model.common.Language;
 import eu.etaxonomy.cdm.model.description.CategoricalData;
 import eu.etaxonomy.cdm.model.description.Feature;
+import eu.etaxonomy.cdm.model.description.NoDescriptiveDataStatus;
 import eu.etaxonomy.cdm.model.description.State;
 import eu.etaxonomy.cdm.model.description.StateData;
 import eu.etaxonomy.cdm.model.term.DefinedTerm;
@@ -78,6 +79,29 @@ public class CategoricalDataFormatterTest extends TermTestBase {
         Assert.assertEquals("female state1s, textmodi state2, male unknown state3", text);
 
         //TODO test with additional basedata like timeperiod etc.
+
+
     }
 
-}
+    @Test
+    public void testFormatNoData() {
+        //no data status
+        CategoricalData catData = CategoricalData.NewInstance(Feature.HABITAT());
+        FormatKey[] formatKey = null;
+        CategoricalDataFormatter formatter = new CategoricalDataFormatter(catData, formatKey);
+
+        //fully empty
+        String text = formatter.format(catData, formatKey);
+        Assert.assertEquals("", text);  //behavior may change in future
+
+        //data unavailable
+        catData.setNoDataStatus(NoDescriptiveDataStatus.DataUnavailable);
+        text = formatter.format(catData, formatKey);
+        Assert.assertEquals("data unavailable", text);
+
+        //data unavailable, but still data exists
+        catData.addStateData(stateData2);
+        text = formatter.format(catData, formatKey);
+        Assert.assertEquals("data unavailable (state2)", text);
+    }
+}
\ No newline at end of file
index 71873d1085378235c187f9f75d73890ffea4cc7d..4bfd182440701832bdd5ecf71d9e3ad3c2069ab1 100644 (file)
@@ -18,6 +18,7 @@ import eu.etaxonomy.cdm.format.ICdmFormatter.FormatKey;
 import eu.etaxonomy.cdm.model.common.Language;
 import eu.etaxonomy.cdm.model.description.Feature;
 import eu.etaxonomy.cdm.model.description.MeasurementUnit;
+import eu.etaxonomy.cdm.model.description.NoDescriptiveDataStatus;
 import eu.etaxonomy.cdm.model.description.QuantitativeData;
 import eu.etaxonomy.cdm.model.description.StatisticalMeasure;
 import eu.etaxonomy.cdm.model.description.StatisticalMeasurementValue;
@@ -93,6 +94,7 @@ public class QuantitativeDataFormatterTest extends TermTestBase {
     public void testFormatWithModifier() {
         QuantitativeData quantData = QuantitativeData.NewInstance(Feature.CHROMOSOME_NUMBER());
         FormatKey[] formatKey = null;
+        QuantitativeDataFormatter formatter = new QuantitativeDataFormatter(quantData, formatKey);
 
         quantData.addStatisticalValue(min1);
         quantData.addStatisticalValue(max1);
@@ -100,7 +102,6 @@ public class QuantitativeDataFormatterTest extends TermTestBase {
         MeasurementUnit unit = MeasurementUnit.METER();
         quantData.setUnit(unit);
 
-        QuantitativeDataFormatter formatter = new QuantitativeDataFormatter(quantData, formatKey);
         String text = formatter.format(quantData, formatKey);
         Assert.assertEquals("0.1"+lowerUpperSep+"1.3 m [n=2]", text);
 
@@ -132,4 +133,30 @@ public class QuantitativeDataFormatterTest extends TermTestBase {
         text = formatter.format(quantData, formatKey);
         Assert.assertEquals("about new mod (min"+modifierSep+"0.1"+minSep+")0.2"+lowerUpperSep+"max"+modifierSep+"1.3 m [n=2]", text);
     }
+
+    @Test
+    public void testFormatNoData() {
+        //no data status
+        QuantitativeData quantData = QuantitativeData.NewInstance(Feature.CHROMOSOME_NUMBER());
+        FormatKey[] formatKey = null;
+        QuantitativeDataFormatter formatter = new QuantitativeDataFormatter(quantData, formatKey);
+
+        //fully empty
+        String text = formatter.format(quantData, formatKey);
+        Assert.assertEquals("", text);  //behavior may change in future
+
+        //data unavailable
+        quantData.setNoDataStatus(NoDescriptiveDataStatus.DataUnavailable);
+        text = formatter.format(quantData, formatKey);
+        Assert.assertEquals("data unavailable", text);
+
+        //data unavailable, but still data exists
+        quantData.addStatisticalValue(min1);
+        quantData.addStatisticalValue(max1);
+        quantData.addStatisticalValue(n1);
+        MeasurementUnit unit = MeasurementUnit.METER();
+        quantData.setUnit(unit);
+        text = formatter.format(quantData, formatKey);
+        Assert.assertEquals("data unavailable (0.1"+lowerUpperSep+"1.3 m [n=2])", text);
+    }
 }
\ No newline at end of file
index b1e38c6cd79298faa19a705e9517882d4fd148c3..eb694b5ce999acffc1e16900cf5c5e9016c92810 100644 (file)
@@ -18,7 +18,7 @@ import eu.etaxonomy.cdm.common.monitor.DefaultProgressMonitor;
 import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
 import eu.etaxonomy.cdm.database.CdmDataSource;
 import eu.etaxonomy.cdm.database.ICdmDataSource;
-import eu.etaxonomy.cdm.database.update.v536_538.SchemaUpdater_5361_5380;
+import eu.etaxonomy.cdm.database.update.v538_540.SchemaUpdater_5380_5400;
 import eu.etaxonomy.cdm.model.metadata.CdmMetaData;
 
 /**
@@ -67,7 +67,7 @@ public class CdmUpdater {
     private static final Logger logger = LogManager.getLogger();
 
     private static final ISchemaUpdater getCurrentSchemaUpdater() {
-        return SchemaUpdater_5361_5380.NewInstance();
+        return SchemaUpdater_5380_5400.NewInstance();
     }
 
     public static CdmUpdater NewInstance(){
diff --git a/cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/database/update/v538_540/SchemaUpdater_5380_5400.java b/cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/database/update/v538_540/SchemaUpdater_5380_5400.java
new file mode 100644 (file)
index 0000000..bb51948
--- /dev/null
@@ -0,0 +1,69 @@
+/**
+ * Copyright (C) 2007 EDIT
+ * European Distributed Institute of Taxonomy
+ * http://www.e-taxonomy.eu
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * See LICENSE.TXT at the top of this package for the full license terms.
+ */
+package eu.etaxonomy.cdm.database.update.v538_540;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import eu.etaxonomy.cdm.database.update.ColumnAdder;
+import eu.etaxonomy.cdm.database.update.ISchemaUpdater;
+import eu.etaxonomy.cdm.database.update.ISchemaUpdaterStep;
+import eu.etaxonomy.cdm.database.update.SchemaUpdaterBase;
+import eu.etaxonomy.cdm.database.update.v536_538.SchemaUpdater_5361_5380;
+import eu.etaxonomy.cdm.model.metadata.CdmMetaData.CdmVersion;
+
+/**
+ * @author a.mueller
+ * @date 27.06.2023
+ */
+public class SchemaUpdater_5380_5400 extends SchemaUpdaterBase {
+
+       @SuppressWarnings("unused")
+       private static final Logger logger = LogManager.getLogger();
+
+       private static final CdmVersion startSchemaVersion = CdmVersion.V_05_38_00;
+       private static final CdmVersion endSchemaVersion = CdmVersion.V_05_40_00;
+
+// ********************** FACTORY METHOD *************************************
+
+    @Override
+    public ISchemaUpdater getPreviousUpdater() {
+        return SchemaUpdater_5361_5380.NewInstance();
+    }
+
+       public static SchemaUpdater_5380_5400 NewInstance() {
+               return new SchemaUpdater_5380_5400();
+       }
+
+       protected SchemaUpdater_5380_5400() {
+               super(startSchemaVersion.versionString(), endSchemaVersion.versionString());
+       }
+
+
+    @Override
+       protected List<ISchemaUpdaterStep> getUpdaterList() {
+
+               String stepName;
+               String tableName;
+               String columnName;
+
+               List<ISchemaUpdaterStep> stepList = new ArrayList<>();
+
+        //#2975 add noDataStatus column for descriptive data
+               stepName = "Add noDataStatus column for descriptive data";
+               tableName = "DescriptionElementBase";
+               columnName = "noDataStatus";
+        ColumnAdder.NewStringInstance(stepList, stepName, tableName, columnName, 10, INCLUDE_AUDIT);
+
+               return stepList;
+    }
+}
\ No newline at end of file