Commit 495aeeaf authored by Piotr Gawron's avatar Piotr Gawron

Merge branch '1041-add-validation-of-the-project-data' into 'master'

Resolve "add validation of the project data"

Closes #1041

See merge request !1031
parents f188f2c7 8688ce28
Pipeline #17972 passed with stage
in 12 minutes and 38 seconds
minerva (15.0.0~alpha.2) stable; urgency=medium
* Small improvement: data not compliant with database constraints (for
instance too long species identifiers) will be automatically adjust instead
of crashing project upload (#1041)
* Small improvement: reaction lines in SBML files without layout are set
outside of the species (not in the center, #1023)
* Bug fix: import from CellDesigner rounded alias dimension to integer
......
......@@ -29,13 +29,14 @@ public class Project implements Serializable {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(unique = true, nullable = false)
@Column(unique = true, nullable = false, length = 255)
private String projectId;
@Cascade({ CascadeType.ALL })
@OneToOne
private MiriamData disease;
@Column(length = 255)
private String name;
private String version;
......
......@@ -31,7 +31,7 @@ public class ProjectLogEntry implements Serializable {
private String source;
@Column(nullable = false)
@Column(nullable = false, columnDefinition = "TEXT")
private String content;
public ProjectLogEntry() {
......
......@@ -39,6 +39,7 @@ public abstract class FileEntry implements Serializable {
/**
* Original name of the file.
*/
@Column(length=255)
private String originalFileName;
/**
......
......@@ -33,6 +33,7 @@ public class Comment implements Serializable {
/**
* What was the reason of removal.
*/
@Column(length = 255)
private String removeReason = "";
/**
......@@ -45,6 +46,7 @@ public class Comment implements Serializable {
/**
* Name of the user that insert this feedback.
*/
@Column(length = 255)
private String name;
/**
......@@ -62,6 +64,7 @@ public class Comment implements Serializable {
/**
* Email of the user who gave feedback.
*/
@Column(length = 255)
private String email;
/**
......
......@@ -51,6 +51,7 @@ public class MiriamData implements Comparable<MiriamData>, Serializable {
/**
* Resource identifier in the database.
*/
@Column(length = 255)
private String resource = "";
/**
......
......@@ -47,6 +47,7 @@ public class OverviewImage implements Serializable {
/**
* Name of the file in file system that represent this overview image.
*/
@Column(length = 255)
private String filename;
/**
......
......@@ -48,6 +48,7 @@ public class SearchIndex implements Serializable {
/**
* Data of the index.
*/
@Column(length = 255)
private String value;
/**
......
......@@ -38,8 +38,10 @@ public class SbmlFunction implements Serializable, SbmlArgument {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(length = 255)
private String functionId;
@Column(length = 255)
private String name;
@Column(columnDefinition = "TEXT")
......@@ -48,7 +50,7 @@ public class SbmlFunction implements Serializable, SbmlArgument {
@ElementCollection
@CollectionTable(name = "sbml_function_arguments", joinColumns = @JoinColumn(name = "sbml_function_id"))
@OrderColumn(name = "idx")
@Column(name = "argument_name")
@Column(name = "argument_name", length = 255)
private List<String> arguments = new ArrayList<>();
/**
......
......@@ -34,8 +34,10 @@ public class SbmlParameter implements Serializable, SbmlArgument {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(length=255)
private String parameterId;
@Column(length=255)
private String name;
private Double value;
......
......@@ -40,7 +40,10 @@ public class SbmlUnit implements Serializable {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(length = 255)
private String unitId;
@Column(length = 255)
private String name;
@Cascade({ CascadeType.ALL })
......
......@@ -55,7 +55,7 @@ public abstract class ColorSchema implements Serializable {
/**
* In which compartments (identified by name) the element can occur.
*/
private List<String> compartments = new ArrayList<String>();
private List<String> compartments = new ArrayList<>();
/**
* What types of element should be identified by this entry.
......
......@@ -47,6 +47,7 @@ public class DataOverlayImageLayer implements Serializable {
/**
* Directory where the images are stored.
*/
@Column(length=255)
private String directory;
/**
......
......@@ -57,6 +57,7 @@ public class Layout implements Serializable {
/**
* Title of this layout.
*/
@Column(length = 255)
private String title;
/**
......
......@@ -37,7 +37,7 @@ public class ReferenceGenome implements Serializable {
* Organism for which the genome is provided.
*/
@Cascade({ CascadeType.ALL })
@OneToOne
@OneToOne(optional = false)
private MiriamData organism;
/**
......@@ -45,12 +45,14 @@ public class ReferenceGenome implements Serializable {
* reference genome was taken.
*/
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private ReferenceGenomeType type;
/**
* Version of the reference genome (databases have different releases, this
* string represent specific release of data).
*/
@Column(length = 255)
private String version;
/**
......@@ -61,6 +63,7 @@ public class ReferenceGenome implements Serializable {
/**
* Source url used to obtain data.
*/
@Column(length = 255)
private String sourceUrl;
/**
......
......@@ -31,17 +31,19 @@ public class ReferenceGenomeGeneMapping implements Serializable {
/**
* {@link ReferenceGenome Reference genome} for which gene mapping is provided.
*/
@ManyToOne(fetch = FetchType.LAZY)
@ManyToOne(fetch = FetchType.LAZY, optional = false)
private ReferenceGenome referenceGenome;
/**
* Name of the mapping.
*/
@Column(nullable = false, length = 255)
private String name;
/**
* Url to source file which provides mapping.
*/
@Column(nullable = false, columnDefinition = "TEXT")
private String sourceUrl;
/**
......
......@@ -46,11 +46,13 @@ public class Layer implements Serializable {
/**
* Layer identifier (unique in single model).
*/
@Column(length=255)
private String layerId;
/**
* Layer name.
*/
@Column(length=255)
private String name;
/**
......
......@@ -37,21 +37,25 @@ public class Author implements Serializable {
/**
* First name.
*/
@Column(length = 255)
private String firstName;
/**
* Last name.
*/
@Column(length = 255)
private String lastName;
/**
* Email address.
*/
@Column(length = 255)
private String email;
/**
* Organization.
*/
@Column(length = 255)
private String organisation;
/**
......
......@@ -135,6 +135,7 @@ public class ModelData implements Serializable {
/**
* Name of the map.
*/
@Column(length = 255)
private String name;
/**
......
......@@ -47,6 +47,7 @@ public abstract class SubmodelConnection implements Serializable {
/**
* Name of the connection.
*/
@Column(length = 255)
private String name;
/**
......
......@@ -96,11 +96,13 @@ public class Reaction implements BioEntity {
/**
* Identifier of the reaction. Unique in the {@link Model}.
*/
@Column(length = 255)
private String idReaction = "";
/**
* Name of the reaction.
*/
@Column(length = 255)
private String name = "";
/**
......@@ -111,16 +113,19 @@ public class Reaction implements BioEntity {
/**
* Symbol of the reaction (RECON).
*/
@Column(length = 255)
private String symbol = null;
/**
* Abbreviation of the reaction (RECON).
*/
@Column(length = 255)
private String abbreviation = null;
/**
* Formula (RECON).
*/
@Column(length = 255)
private String formula = null;
/**
......@@ -141,11 +146,13 @@ public class Reaction implements BioEntity {
/**
* Subsystem (RECON).
*/
@Column(length = 255)
private String subsystem = null;
/**
* Gene protein reaction (RECON).
*/
@Column(length = 255)
private String geneProteinReaction = null;
/**
......@@ -156,6 +163,7 @@ public class Reaction implements BioEntity {
/**
* Z-index of elements on the map.
*/
@Column(nullable = false)
private Integer z = null;
/**
......@@ -163,7 +171,7 @@ public class Reaction implements BioEntity {
*/
@ElementCollection
@CollectionTable(name = "reaction_synonyms", joinColumns = @JoinColumn(name = "id"))
@Column(name = "synonym")
@Column(name = "synonym", length = 255)
@OrderColumn(name = "idx")
@Cascade({ org.hibernate.annotations.CascadeType.ALL })
private List<String> synonyms = new ArrayList<>();
......
......@@ -39,6 +39,7 @@ public abstract class Chemical extends Species {
* InChIKey</a> parameter for the chemical.
*/
@Column(length = 255)
private String inChIKey;
/**
......
......@@ -126,6 +126,7 @@ public abstract class Element implements BioEntity, Serializable, SbmlArgument {
/**
* Z-index of elements on the map.
*/
@Column(nullable = false)
private Integer z = null;
/**
......@@ -227,7 +228,7 @@ public abstract class Element implements BioEntity, Serializable, SbmlArgument {
*/
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "element_synonyms", joinColumns = @JoinColumn(name = "id"))
@Column(name = "synonym")
@Column(name = "synonym", length = 512)
@OrderColumn(name = "idx")
@Cascade({ org.hibernate.annotations.CascadeType.ALL })
private List<String> synonyms = new ArrayList<>();
......@@ -237,7 +238,7 @@ public abstract class Element implements BioEntity, Serializable, SbmlArgument {
*/
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "element_former_symbols", joinColumns = @JoinColumn(name = "id"))
@Column(name = "symbol")
@Column(name = "symbol", length = 255)
@OrderColumn(name = "idx")
@Cascade({ org.hibernate.annotations.CascadeType.ALL })
private List<String> formerSymbols = new ArrayList<>();
......
......@@ -49,6 +49,7 @@ public abstract class Species extends Element {
* State of the element visualization (should the inside be presented in details
* or not). TODO this should be transformed into enum
*/
@Column(length = 255)
private String state;
/**
......@@ -56,6 +57,7 @@ public abstract class Species extends Element {
* {@link #statePrefix prefix} and {@link #stateLabel label}. This value
* represent the first part of the state.
*/
@Column(length = 255)
private String statePrefix;
/**
......@@ -63,6 +65,7 @@ public abstract class Species extends Element {
* {@link #statePrefix prefix} and {@link #stateLabel label}. This value
* represent the second part of the state.
*/
@Column(length = 255)
private String stateLabel;
/**
......@@ -444,6 +447,11 @@ public abstract class Species extends Element {
this.uniprots = uniprots;
}
public void addUniprot(UniprotRecord uniprot) {
this.uniprots.add(uniprot);
uniprot.setSpecies(this);
}
/**
* @return the onlySubstanceUnits
* @see #onlySubstanceUnits
......
......@@ -46,11 +46,13 @@ public abstract class ModificationResidue implements Serializable {
/**
* Identifier of the modification. Must be unique in single map model.
*/
@Column(length = 255)
private String idModificationResidue = "";
/**
* Name of the modification.
*/
@Column(length = 255)
private String name = "";
@Type(type = "lcsb.mapviewer.persist.mapper.Point2DMapper")
......
......@@ -49,11 +49,13 @@ public class Structure implements Serializable {
/**
* the PDB ID which maps to the UniProt ID
*/
@Column(length = 255, nullable = false)
private String pdbId = null;
/**
* the specific chain of the PDB which maps to the UniProt ID
*/
@Column(length = 255, nullable = false)
private String chainId = null;
/**
......@@ -89,6 +91,7 @@ public class Structure implements Serializable {
/**
* type of experiment used to determine structure
*/
@Column(length = 255)
private String experimentalMethod = null;
/**
......
......@@ -2,8 +2,7 @@ package lcsb.mapviewer.model.map.species.field;
import java.io.Serializable;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
......@@ -35,8 +34,9 @@ public class TranscriptionSite extends AbstractRegionModification implements Ser
* Default class logger.
*/
@SuppressWarnings("unused")
private static Logger logger = LogManager.getLogger(TranscriptionSite.class);
private static Logger logger = LogManager.getLogger();
@Column(length = 255)
private String direction = null;
private Boolean active = false;
......
......@@ -37,7 +37,7 @@ public class UniprotRecord implements Serializable {
/**
* ID of the uniprot record
*/
@Column(nullable = false)
@Column(nullable = false, length = 255)
private String uniprotId = "";
/**
......@@ -165,6 +165,13 @@ public class UniprotRecord implements Serializable {
}
public void addStructures(Collection<Structure> structures) {
this.structures.addAll(structures);
for (Structure structure : structures) {
addStructure(structure);
}
}
public void addStructure(Structure structure) {
this.structures.add(structure);
structure.setUniprot(this);
}
}
......@@ -37,16 +37,19 @@ public class Plugin implements Serializable {
/**
* Hash of the plugin code used as identifier to distinguish between plugins.
*/
@Column(length = 255, nullable = false)
private String hash;
/**
* Name of the plugin.
*/
@Column(length = 255, nullable = false)
private String name;
/**
* Version of the plugin.
*/
@Column(length = 255, nullable = false)
private String version;
/**
......
......@@ -33,10 +33,10 @@ public class PluginDataEntry implements Serializable {
@ManyToOne(fetch = FetchType.LAZY, optional = false)
private Plugin plugin;
@Column(nullable = false)
@Column(nullable = false, length = 1024)
private String key;
@Column(nullable = false)
@Column(nullable = false, length = 2048)
private String value;
public int getId() {
......
......@@ -34,6 +34,7 @@ public class ConfigurationOption implements Serializable {
/**
* What is the value of the configuration parameter.
*/
@Column(length = 255)
private String value;
/**
......
......@@ -22,13 +22,16 @@ public class User implements Serializable {
@Column(unique = true, nullable = false)
private String login;
@Column(nullable = false)
@Column(nullable = false, length = 255)
private String cryptedPassword;
@Column(length = 255)
private String name;
@Column(length = 255)
private String surname;
@Column(length = 255)
private String email;
/**
......
......@@ -43,6 +43,7 @@ public class UserClassAnnotators implements Serializable {
/**
* Class for which this set of annotators is defined.
*/
@Column(length = 255)
private String className;
/**
......
......@@ -48,6 +48,7 @@ public class UserClassRequiredAnnotations implements Serializable {
/**
* Name of the class for which this set is defined.
*/
@Column(length = 255)
private String className;
/**
......
......@@ -38,6 +38,7 @@ public class UserClassValidAnnotations implements Serializable {
/**
* Name of the class for which this set is defined.
*/
@Column(length = 255)
private String className;
/**
......
......@@ -35,13 +35,13 @@ public class UserGuiPreference implements Serializable {
/**
* GUI parameter name.
*/
@Column(nullable = false)
@Column(nullable = false, length = 255)
private String key;
/**
* GUI parameter value.
*/
@Column(nullable = false)
@Column(nullable = false, length = 255)
private String value;
public UserAnnotationSchema getAnnotationSchema() {
......
......@@ -30,6 +30,7 @@ public class AnnotatorConfigParameter extends AnnotatorParameter implements Seri
/**
* Parameter value to be set.
*/
@Column(length = 255)
private String value;
/**
......
......@@ -62,7 +62,6 @@ public class ProjectTest extends ModelTestFunctions {
ProjectStatus status = ProjectStatus.ANNOTATING;
double progress = 4.5;
Set<ModelData> models = new HashSet<>();
String errors = "eerStr";
String directory = "dir";
String name = "name3";
MiriamData disease = new MiriamData();
......
......@@ -191,6 +191,14 @@
<scope>compile</scope>
</dependency>
<!-- mockito used for testing -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
......
package lcsb.mapviewer.persist.dao;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.criteria.*;
import org.apache.logging.log4j.LogManager;
......@@ -15,15 +11,12 @@ import org.hibernate.dialect.Dialect;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.util.ReflectionUtils;
import lcsb.mapviewer.common.Pair;
import lcsb.mapviewer.common.exception.InvalidStateException;
import lcsb.mapviewer.model.user.User;
import lcsb.mapviewer.persist.DbUtils;
/**
* Abstract interface for data access object in the system. Containts the basic
* Abstract interface for data access object in the system. Contains the basic
* generic functionality.
*
* @author Piotr Gawron
......@@ -37,7 +30,7 @@ public abstract class BaseDao<T> {
/**
* Default class logger.
*/
private static Logger logger = LogManager.getLogger(BaseDao.class);
private static Logger logger = LogManager.getLogger();
/**
* Sometimes objects have a flag that indicate that the object was removed from
......@@ -52,7 +45,7 @@ public abstract class BaseDao<T> {
*/
private Class<T> clazz;
/**
* Utils that help to manage the sessions in custom multithreaded
* Utility that helps to manage the sessions in custom multi-threaded
* implementation.
*/
@Autowired
......@@ -346,155 +339,4 @@ public abstract class BaseDao<T> {
return dbUtils.getDialect();
}
public List<String> getValidationIssues(T o) {
final List<String> result = new ArrayList<>();
processValidationIssues(o, new BiConsumer<Object, Field>() {
@Override
public void accept(Object t, Field u) {
try {
if (u