<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"/>
--- /dev/null
+/**
+* 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 + "]";
+ }
+
+}
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
@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
return result;\r
}\r
\r
-\r
protected MediaRepresentationPart() {\r
super();\r
}\r
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
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;
media.setArtist(artist);
cdmBases.add(media);
cdmBases.add(artist);
+
+ MediaMetaData.NewInstance(imageFile, "Key", "Value");
}
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
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;
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;
}
<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"/>
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
<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"/>