fix #9009 add MediaMetaData
authorAndreas Müller <a.mueller@bgbm.org>
Wed, 10 Jun 2020 14:41:31 +0000 (16:41 +0200)
committerAndreas Müller <a.mueller@bgbm.org>
Wed, 10 Jun 2020 15:37:13 +0000 (17:37 +0200)
cdmlib-cache/src/main/resources/eu/etaxonomy/cdm/mappings/hibernate.cfg.xml
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/media/MediaMetaData.java [new file with mode: 0644]
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/media/MediaRepresentationPart.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/database/data/FullCoverageDataGenerator.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/database/update/TableCreator.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/database/update/v515_5151/SchemaUpdater_5150_5151.java
cdmlib-persistence/src/main/resources/eu/etaxonomy/cdm/hibernate.cfg.xml
cdmlib-test/src/main/resources/dbscripts/001-cdm.h2.sql
cdmlib-test/src/test/resources/eu/etaxonomy/cdm/hibernate.cfg.xml

index 8b0845f38fa96a54381e455e6ddf378a9e04cf49..7ca3d9aeaddb3a3000e8c322eb8df75f94ac95e7 100644 (file)
@@ -136,6 +136,7 @@ Difference are to be found in
       <mapping class="eu.etaxonomy.cdm.model.media.ExternalLink"/>
       <mapping class="eu.etaxonomy.cdm.model.media.ImageFile"/>
       <mapping class="eu.etaxonomy.cdm.model.media.Media"/>
+      <mapping class="eu.etaxonomy.cdm.model.media.MediaMetaData"/>
       <mapping class="eu.etaxonomy.cdm.model.media.MediaRepresentation"/>
       <mapping class="eu.etaxonomy.cdm.model.media.MediaRepresentationPart"/>
       <mapping class="eu.etaxonomy.cdm.model.media.MovieFile"/>
diff --git a/cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/media/MediaMetaData.java b/cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/media/MediaMetaData.java
new file mode 100644 (file)
index 0000000..b0c2c1d
--- /dev/null
@@ -0,0 +1,125 @@
+/**
+* Copyright (C) 2020 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.media;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlIDREF;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
+
+import org.hibernate.annotations.Cascade;
+import org.hibernate.annotations.CascadeType;
+import org.hibernate.envers.Audited;
+
+import eu.etaxonomy.cdm.model.common.CdmBase;
+
+/**
+ * This class is for storing metadata about media files
+ * (e.g. Exif, IPCT, PhotoshopMetadata, etc) in a key-value format.<BR>
+ * It is not audited as the metadata is considered to be cached
+ * only from the original file and therefore can be reconstructed
+ * and updated when ever the file is available.<BR>
+ * Data should only contain data which can not be stored otherwise
+ * (height, width, size, authorship, ...).
+ *
+ * see also #9009
+ *
+ * @author a.mueller
+ * @since 10.06.2020
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "MediaMetaData", propOrder = {
+    "mediaRepresentationPart",
+    "key",
+    "value"
+ })
+@Entity
+@Audited  //necessary because otherwise mapping from MediaRepresentationPart to MediaMetaData is not possible
+@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
+public class MediaMetaData extends CdmBase {
+
+    private static final long serialVersionUID = -2523716526037575324L;
+
+    @XmlElement(name = "MediaRepresentation")
+    @XmlIDREF
+    @XmlSchemaType(name = "IDREF")
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "mediaRepresentation_id")
+    @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
+    private MediaRepresentationPart mediaRepresentation;
+
+    @Column(name="pairkey") //to avoid conflicts with SQL keywords
+    private String key;
+
+    @Column(name="pairvalue")  //to avoid conflicts with SQL keywords
+    private String value;
+
+// ************************** FACTORY ***********************/
+
+    public static MediaMetaData NewInstance(MediaRepresentationPart mediaRepresentation,
+            String key, String value) {
+        return new MediaMetaData(mediaRepresentation, key, value);
+    }
+
+// ************************* CONSTRUCTOR *******************/
+
+    private MediaMetaData(){}
+
+    private MediaMetaData(MediaRepresentationPart mediaRepresentation, String key, String value){
+        setMediaRepresentation(mediaRepresentation);
+        this.key = key;
+        this.value = value;
+    }
+
+//*********************** GETTER / SETTER **********************/
+
+    public MediaRepresentationPart getMediaRepresentation() {
+        return mediaRepresentation;
+    }
+
+    protected void setMediaRepresentation(MediaRepresentationPart mediaRepresentation) {
+        this.mediaRepresentation = mediaRepresentation;
+        if (mediaRepresentation != null){
+            mediaRepresentation.addMediaMetaData(this);
+        }
+    }
+
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+// ************************** toString ************************/
+
+    @Override
+    public String toString() {
+        return "MediaMetaData [" + key + "=" + value + "]";
+    }
+
+}
index 554405394049b92671891970952775c0bb4af99f..ca594a478fd897a6f9f16c0db3d3e87948e6b430 100644 (file)
 package eu.etaxonomy.cdm.model.media;\r
 \r
 import java.net.URI;\r
+import java.util.HashSet;\r
+import java.util.Set;\r
 \r
 import javax.persistence.Entity;\r
 import javax.persistence.FetchType;\r
 import javax.persistence.JoinColumn;\r
 import javax.persistence.ManyToOne;\r
+import javax.persistence.OneToMany;\r
 import javax.xml.bind.annotation.XmlAccessType;\r
 import javax.xml.bind.annotation.XmlAccessorType;\r
 import javax.xml.bind.annotation.XmlElement;\r
+import javax.xml.bind.annotation.XmlElementWrapper;\r
 import javax.xml.bind.annotation.XmlIDREF;\r
 import javax.xml.bind.annotation.XmlSchemaType;\r
 import javax.xml.bind.annotation.XmlType;\r
@@ -69,6 +73,12 @@ public class MediaRepresentationPart extends VersionableEntity implements Clonea
        @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})\r
        private MediaRepresentation mediaRepresentation;\r
 \r
+    @XmlElementWrapper(name = "MediaMetaDatas")\r
+    @XmlElement(name = "MediaMetaData")\r
+    @OneToMany (mappedBy="mediaRepresentation", fetch= FetchType.LAZY, orphanRemoval=true)\r
+    @Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.DELETE, CascadeType.REFRESH})\r
+       private Set<MediaMetaData> mediaMetaData = new HashSet<>();\r
+\r
 \r
 // *************** FACTORY METHOD *********************************/\r
 \r
@@ -77,7 +87,6 @@ public class MediaRepresentationPart extends VersionableEntity implements Clonea
                return result;\r
        }\r
 \r
-\r
        protected MediaRepresentationPart() {\r
                super();\r
        }\r
@@ -119,6 +128,21 @@ public class MediaRepresentationPart extends VersionableEntity implements Clonea
                this.size = size;\r
        }\r
 \r
+       public void addMediaMetaData(MediaMetaData metaData){\r
+           this.mediaMetaData.add(metaData);\r
+           if(metaData.getMediaRepresentation() != this){\r
+               metaData.setMediaRepresentation(this);\r
+           }\r
+    }\r
+\r
+    public void removeMediaMetaData(MediaMetaData metaData){\r
+        this.mediaMetaData.remove(metaData);\r
+        if(metaData.getMediaRepresentation() == this){\r
+            metaData.setMediaRepresentation(null);\r
+        }\r
+    }\r
+\r
+\r
 //************************* CLONE **************************/\r
 \r
        @Override\r
index bc6c1ff8e96b1eb157bb8de9a27eedfeb04722b3..d9c4092083c40cb849338b736b093d080a58b1b9 100644 (file)
@@ -77,6 +77,7 @@ import eu.etaxonomy.cdm.model.media.ExternalLinkType;
 import eu.etaxonomy.cdm.model.media.IdentifiableMediaEntity;
 import eu.etaxonomy.cdm.model.media.ImageFile;
 import eu.etaxonomy.cdm.model.media.Media;
+import eu.etaxonomy.cdm.model.media.MediaMetaData;
 import eu.etaxonomy.cdm.model.media.MediaRepresentation;
 import eu.etaxonomy.cdm.model.media.MovieFile;
 import eu.etaxonomy.cdm.model.media.Rights;
@@ -549,6 +550,8 @@ public class FullCoverageDataGenerator {
                media.setArtist(artist);
                cdmBases.add(media);
                cdmBases.add(artist);
+
+               MediaMetaData.NewInstance(imageFile, "Key", "Value");
        }
 
 
index cff7b6cc62ec0bab431251a39d7eea75aee39dee..bd721c2cfba37fa776ce890e935301f4cc16967b 100644 (file)
@@ -59,6 +59,10 @@ public class TableCreator extends AuditedSchemaUpdaterStepBase {
                return new TableCreator(stepList, stepName, tableName, Arrays.asList(columnNames), Arrays.asList(columnTypes), null, null, Arrays.asList(referencedTables), includeAudTable, includeCdmBaseAttributes, false, false, false);\r
        }\r
 \r
+    public static final TableCreator NewAuditedCdmBaseInstance(List<ISchemaUpdaterStep> stepList, String stepName, String tableName, String[] columnNames, String[] columnTypes, String[] referencedTables){\r
+        return new TableCreator(stepList, stepName, tableName, Arrays.asList(columnNames), Arrays.asList(columnTypes), null, null, Arrays.asList(referencedTables), true, true, false, false, true);\r
+    }\r
+\r
        public static final TableCreator NewNonVersionableInstance(List<ISchemaUpdaterStep> stepList, String stepName, String tableName, String[] columnNames, String[] columnTypes, String[] referencedTables){\r
                return new TableCreator(stepList, stepName, tableName, Arrays.asList(columnNames), Arrays.asList(columnTypes), null, null, Arrays.asList(referencedTables), false, true, false, false, true);\r
        }\r
index 132af4a9ce3c3025556f0b92e851bf9443e4b326..75015ddcafc36c0dfbddf18b9a4ed474736a0f60 100644 (file)
@@ -18,6 +18,7 @@ import eu.etaxonomy.cdm.database.update.ColumnRemover;
 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.TableCreator;
 import eu.etaxonomy.cdm.database.update.v512_515.SchemaUpdater_5120_5150;
 import eu.etaxonomy.cdm.model.metadata.CdmMetaData.CdmVersion;
 
@@ -97,7 +98,13 @@ public class SchemaUpdater_5150_5151 extends SchemaUpdaterBase {
         columnName = "doubtful";
         ColumnRemover.NewInstance(stepList, stepName, tableName, columnName, INCLUDE_AUDIT);
 
-
+        //#9009
+        stepName = "Create MediaMetaData table";
+        tableName = "MediaMetaData";
+        String[] columnNames = new String[]{"pairkey","pairvalue","mediarepresentation_id"};
+        String[] columnTypes = new String[]{"string_255","string_255","int"};
+        String[] referencedTables = new String[]{null,null,"MediaRepresentationPart"};
+        TableCreator.NewAuditedCdmBaseInstance(stepList, stepName, tableName, columnNames, columnTypes, referencedTables);
 
         return stepList;
     }
index 6f614db29d0520bcdb6c6d755129a0b5dcd606d3..1cc5bc8dc7d7472cf8422f8c73d05055f1fe693b 100644 (file)
       <mapping class="eu.etaxonomy.cdm.model.media.ExternalLink"/>
       <mapping class="eu.etaxonomy.cdm.model.media.ImageFile"/>
       <mapping class="eu.etaxonomy.cdm.model.media.Media"/>
+      <mapping class="eu.etaxonomy.cdm.model.media.MediaMetaData"/>
       <mapping class="eu.etaxonomy.cdm.model.media.MediaRepresentation"/>
       <mapping class="eu.etaxonomy.cdm.model.media.MediaRepresentationPart"/>
       <mapping class="eu.etaxonomy.cdm.model.media.MovieFile"/>
index 13a9e646a21e9a4f4eeaf09f3857028983180128..5147b5f91f55aeb036f2bc9cad1296e7e5ca773d 100644 (file)
@@ -2634,6 +2634,28 @@ CREATE CACHED TABLE PUBLIC.MEDIA(
     CITATION_ID INTEGER
 );
 -- 0 +/- SELECT COUNT(*) FROM PUBLIC.MEDIA;
+CREATE CACHED TABLE PUBLIC.MEDIAMETADATA(
+    ID INTEGER NOT NULL,
+    CREATED TIMESTAMP,
+    UUID VARCHAR(36) NOT NULL,
+    CREATEDBY_ID INTEGER,
+    PAIRKEY VARCHAR(255),
+    PAIRVALUE VARCHAR(255),
+       REPRESENTATION_ID INTEGER NOT NULL
+);
+-- 0 +/- SELECT COUNT(*) FROM PUBLIC.MEDIAMETADATA;
+CREATE CACHED TABLE PUBLIC.MEDIAMETADATA_AUD(
+    REV INTEGER NOT NULL,
+    ID INTEGER NOT NULL,
+    CREATED TIMESTAMP,
+    UUID VARCHAR(36) NOT NULL,
+    CREATEDBY_ID INTEGER,
+    PAIRKEY VARCHAR(255),
+    PAIRVALUE VARCHAR(255),
+       REPRESENTATION_ID INTEGER NOT NULL,
+       REVTYPE TINYINT
+);
+-- 0 +/- SELECT COUNT(*) FROM PUBLIC.MEDIAMETADATA_AUD;
 CREATE CACHED TABLE PUBLIC.MEDIAKEY_COVEREDTAXON(
     MEDIAKEY_ID INTEGER NOT NULL,
     COVEREDTAXA_ID INTEGER NOT NULL
index c16191e8d66ff0a3c6e5be7625399413e61a3ade..d3dca32b91f0a7a00f9665c64afde8606c2c5955 100644 (file)
       <mapping class="eu.etaxonomy.cdm.model.media.ExternalLink"/>
       <mapping class="eu.etaxonomy.cdm.model.media.ImageFile"/>
       <mapping class="eu.etaxonomy.cdm.model.media.Media"/>
+      <mapping class="eu.etaxonomy.cdm.model.media.MediaMetaData"/>
       <mapping class="eu.etaxonomy.cdm.model.media.MediaRepresentation"/>
       <mapping class="eu.etaxonomy.cdm.model.media.MediaRepresentationPart"/>
       <mapping class="eu.etaxonomy.cdm.model.media.MovieFile"/>