diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/exam/Exam.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/exam/Exam.java index 0eaa0682..34e68ace 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/exam/Exam.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/exam/Exam.java @@ -18,6 +18,7 @@ import org.joda.time.DateTimeZone; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import ch.ethz.seb.sebserver.gbl.api.EntityType; @@ -26,6 +27,7 @@ import ch.ethz.seb.sebserver.gbl.model.Activatable; import ch.ethz.seb.sebserver.gbl.model.Domain.EXAM; import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.GrantEntity; +@JsonIgnoreProperties(ignoreUnknown = true) public final class Exam implements GrantEntity, Activatable { public static final String ATTR_STATUS = "examStatus"; @@ -243,31 +245,6 @@ public final class Exam implements GrantEntity, Activatable { return this.active; } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((this.id == null) ? 0 : this.id.hashCode()); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - final Exam other = (Exam) obj; - if (this.id == null) { - if (other.id != null) - return false; - } else if (!this.id.equals(other.id)) - return false; - return true; - } - @Override public String toString() { return "Exam [id=" + this.id + ", institutionId=" + this.institutionId + ", lmsSetupId=" + this.lmsSetupId diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/exam/Indicator.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/exam/Indicator.java index cc886fb4..be4c95e7 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/exam/Indicator.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/exam/Indicator.java @@ -15,6 +15,7 @@ import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import ch.ethz.seb.sebserver.gbl.api.EntityType; @@ -26,6 +27,7 @@ import ch.ethz.seb.sebserver.gbl.model.Domain.THRESHOLD; import ch.ethz.seb.sebserver.gbl.util.Utils; import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.GrantEntity; +@JsonIgnoreProperties(ignoreUnknown = true) public final class Indicator implements GrantEntity { public static final String FILTER_ATTR_EXAM = "exam"; @@ -61,6 +63,7 @@ public final class Indicator implements GrantEntity { @JsonProperty(THRESHOLD.REFERENCE_NAME) public final List thresholds; + @JsonProperty(EXAM.ATTR_OWNER) public final String examOwner; @JsonCreator @@ -154,13 +157,6 @@ public final class Indicator implements GrantEntity { public static final class Threshold { -// @JsonProperty(THRESHOLD.ATTR_ID) -// public final Long id; -// -// @JsonProperty(THRESHOLD.ATTR_INDICATOR_ID) -// @NotNull -// public final Long indicatorId; - @JsonProperty(THRESHOLD.ATTR_VALUE) @NotNull public final Double value; @@ -170,25 +166,13 @@ public final class Indicator implements GrantEntity { @JsonCreator public Threshold( -// @JsonProperty(THRESHOLD.ATTR_ID) final Long id, -// @JsonProperty(THRESHOLD.ATTR_INDICATOR_ID) final Long indicatorId, @JsonProperty(THRESHOLD.ATTR_VALUE) final Double value, @JsonProperty(THRESHOLD.ATTR_COLOR) final String color) { -// this.id = id; -// this.indicatorId = indicatorId; this.value = value; this.color = color; } -// public Long getId() { -// return this.id; -// } -// -// public Long getIndicatorId() { -// return this.indicatorId; -// } - public Double getValue() { return this.value; } @@ -197,12 +181,10 @@ public final class Indicator implements GrantEntity { return this.color; } -// @Override -// public String toString() { -// return "Threshold [id=" + this.id + ", indicatorId=" + this.indicatorId + ", value=" + this.value -// + ", color=" + this.color -// + "]"; -// } + @Override + public String toString() { + return "Threshold [value=" + this.value + ", color=" + this.color + "]"; + } } diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/exam/QuizData.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/exam/QuizData.java index 06e75a3d..c80eb06a 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/exam/QuizData.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/exam/QuizData.java @@ -149,11 +149,6 @@ public final class QuizData implements GrantEntity { return this.lmsType; } - @Override - public String getOwnerId() { - return null; - } - @Override public String getName() { return this.name; @@ -175,37 +170,6 @@ public final class QuizData implements GrantEntity { return this.startURL; } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((this.id == null) ? 0 : this.id.hashCode()); - result = prime * result + ((this.institutionId == null) ? 0 : this.institutionId.hashCode()); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - final QuizData other = (QuizData) obj; - if (this.id == null) { - if (other.id != null) - return false; - } else if (!this.id.equals(other.id)) - return false; - if (this.institutionId == null) { - if (other.institutionId != null) - return false; - } else if (!this.institutionId.equals(other.institutionId)) - return false; - return true; - } - @Override public String toString() { return "QuizData [id=" + this.id + ", institutionId=" + this.institutionId + ", lmsSetupId=" + this.lmsSetupId diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/Institution.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/Institution.java index f481dd92..7e912540 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/Institution.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/Institution.java @@ -94,11 +94,6 @@ public final class Institution implements GrantEntity, Activatable { return this.id; } - @Override - public String getOwnerId() { - return null; - } - @Override public String getName() { return this.name; diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/LmsSetup.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/LmsSetup.java index 585dd5f7..83d09303 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/LmsSetup.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/LmsSetup.java @@ -26,6 +26,7 @@ import ch.ethz.seb.sebserver.gbl.model.Domain.LMS_SETUP; import ch.ethz.seb.sebserver.gbl.model.EntityName; import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.GrantEntity; +@JsonIgnoreProperties(ignoreUnknown = true) public final class LmsSetup implements GrantEntity, Activatable { public static final String FILTER_ATTR_LMS_SETUP = "lms_setup"; @@ -70,7 +71,6 @@ public final class LmsSetup implements GrantEntity, Activatable { public final Boolean active; @JsonCreator - @JsonIgnoreProperties(ignoreUnknown = true) public LmsSetup( @JsonProperty(LMS_SETUP.ATTR_ID) final Long id, @JsonProperty(LMS_SETUP.ATTR_INSTITUTION_ID) final Long institutionId, @@ -110,12 +110,6 @@ public final class LmsSetup implements GrantEntity, Activatable { return EntityType.LMS_SETUP; } - @JsonIgnore - @Override - public String getOwnerId() { - return null; - } - public Long getId() { return this.id; } diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/SebClientConfig.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/SebClientConfig.java index 48ee77d7..8edba1f0 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/SebClientConfig.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/SebClientConfig.java @@ -83,11 +83,6 @@ public final class SebClientConfig implements GrantEntity, Activatable { return this.institutionId; } - @Override - public String getOwnerId() { - return null; - } - public Long getId() { return this.id; } diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/AttributeType.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/AttributeType.java new file mode 100644 index 00000000..bf032075 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/AttributeType.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package ch.ethz.seb.sebserver.gbl.model.sebconfig; + +import static ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeValueType.*; + +/** Enumeration of known SEB configuration attribute types */ +public enum AttributeType { + /** Single read-only label */ + LABEL(NONE), + /** Single lined text value */ + TEXT_FIELD(TEXT), + /** Multiple lined text value */ + TEXT_AREA(TEXT), + /** Check Box or boolean type */ + CHECKBOX(TEXT), + /** Check Box or boolean type without label (e.g.: used in a table) */ + CHECK_FIELD(TEXT), + + /** Integer number type */ + INTEGER(TEXT), + /** Decimal number type */ + DECIMAL(TEXT), + /** Single selection type (Drop-down) */ + SINGLE_SELECTION(TEXT), + /** Multiple selection type */ + MULTI_SELECTION(LIST), + /** Radio selection type (like single selection but with check-boxes) */ + RADIO_SELECTION(TEXT), + + FILE_UPLOAD(BASE64_BINARY), + + /** Table type is a list of composite */ + TABLE(COMPOSITE_LIST), + ; + + public final AttributeValueType attributeValueType; + + private AttributeType(final AttributeValueType attributeValueType) { + this.attributeValueType = attributeValueType; + } +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/AttributeValueType.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/AttributeValueType.java new file mode 100644 index 00000000..cb54decf --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/AttributeValueType.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package ch.ethz.seb.sebserver.gbl.model.sebconfig; + +/** Enumeration of known SEB configuration attribute value types */ +public enum AttributeValueType { + /** Not defined or unknown */ + NONE, + /** Short text (255 chars) */ + TEXT, + /** Large texts MEDIUMTEXT */ + LARGE_TEXT, + /** Base 64 encoded binary data */ + BASE64_BINARY, + /** A list of single values of the same type */ + LIST, + /** A composite of different typed values like a Map or Dictionary */ + COMPOSITE, + /** A list of composites of the same type like a Table */ + COMPOSITE_LIST +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/Configuration.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/Configuration.java new file mode 100644 index 00000000..beb98a0c --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/Configuration.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package ch.ethz.seb.sebserver.gbl.model.sebconfig; + +import javax.validation.constraints.NotNull; + +import org.joda.time.DateTime; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +import ch.ethz.seb.sebserver.gbl.Constants; +import ch.ethz.seb.sebserver.gbl.api.EntityType; +import ch.ethz.seb.sebserver.gbl.model.Domain.CONFIGURATION; +import ch.ethz.seb.sebserver.gbl.model.Domain.CONFIGURATION_NODE; +import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.GrantEntity; + +@JsonIgnoreProperties(ignoreUnknown = true) +public final class Configuration implements GrantEntity { + + @JsonProperty(CONFIGURATION.ATTR_ID) + public final Long id; + + @NotNull + @JsonProperty(CONFIGURATION_NODE.ATTR_INSTITUTION_ID) + public final Long institutionId; + + @NotNull + @JsonProperty(CONFIGURATION.ATTR_CONFIGURATION_NODE_ID) + public final Long nodeId; + + @JsonProperty(CONFIGURATION.ATTR_VERSION) + public final String version; + + @NotNull + @JsonProperty(CONFIGURATION.ATTR_VERSION_DATE) + public final DateTime versionDate; + + @NotNull + @JsonProperty(CONFIGURATION.ATTR_FOLLOWUP) + public final Boolean followup; + + @JsonCreator + public Configuration( + @JsonProperty(CONFIGURATION.ATTR_ID) final Long id, + @JsonProperty(CONFIGURATION_NODE.ATTR_INSTITUTION_ID) final Long institutionId, + @JsonProperty(CONFIGURATION.ATTR_CONFIGURATION_NODE_ID) final Long nodeId, + @JsonProperty(CONFIGURATION.ATTR_VERSION) final String version, + @JsonProperty(CONFIGURATION.ATTR_VERSION_DATE) final DateTime versionDate, + @JsonProperty(CONFIGURATION.ATTR_FOLLOWUP) final Boolean followup) { + + this.id = id; + this.institutionId = institutionId; + this.nodeId = nodeId; + this.version = version; + this.versionDate = versionDate; + this.followup = followup; + } + + @Override + public EntityType entityType() { + return EntityType.CONFIGURATION; + } + + @Override + public String getName() { + return (this.version != null) + ? this.version + : this.versionDate.toString(Constants.DEFAULT_DISPLAY_DATE_FORMAT); + } + + @Override + public String getModelId() { + return (this.id != null) + ? String.valueOf(this.id) + : null; + } + + @Override + public Long getInstitutionId() { + return this.institutionId; + } + + public Long getId() { + return this.id; + } + + public Long getNodeId() { + return this.nodeId; + } + + public String getVersion() { + return this.version; + } + + public DateTime getVersionDate() { + return this.versionDate; + } + + public Boolean getFollowup() { + return this.followup; + } + + @Override + public String toString() { + return "Configuration [id=" + this.id + ", nodeId=" + this.nodeId + ", version=" + this.version + + ", versionDate=" + + this.versionDate + ", followup=" + this.followup + "]"; + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/ConfigurationAttribute.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/ConfigurationAttribute.java new file mode 100644 index 00000000..0b5bfbf7 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/ConfigurationAttribute.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package ch.ethz.seb.sebserver.gbl.model.sebconfig; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +import ch.ethz.seb.sebserver.gbl.api.EntityType; +import ch.ethz.seb.sebserver.gbl.model.Domain.CONFIGURATION_ATTRIBUTE; +import ch.ethz.seb.sebserver.gbl.model.Entity; + +@JsonIgnoreProperties(ignoreUnknown = true) +public final class ConfigurationAttribute implements Entity { + + @JsonProperty(CONFIGURATION_ATTRIBUTE.ATTR_ID) + public final Long id; + + @JsonProperty(CONFIGURATION_ATTRIBUTE.ATTR_PARENT_ID) + public final Long parentId; + + @NotNull(message = "configurationAttribute:name:notNull") + @Size(min = 3, max = 255, message = "configurationAttribute:name:size:{min}:{max}:${validatedValue}") + @JsonProperty(CONFIGURATION_ATTRIBUTE.ATTR_NAME) + public final String name; + + @NotNull(message = "configurationAttribute:type:notNull") + @JsonProperty(CONFIGURATION_ATTRIBUTE.ATTR_TYPE) + public final AttributeType type; + + @JsonProperty(CONFIGURATION_ATTRIBUTE.ATTR_RESOURCES) + public final String resources; + + @JsonProperty(CONFIGURATION_ATTRIBUTE.ATTR_DEPENDENCIES) + public final String dependencies; + + @JsonProperty(CONFIGURATION_ATTRIBUTE.ATTR_DEFAULT_VALUE) + public final String defaultValue; + + @JsonCreator + public ConfigurationAttribute( + @JsonProperty(CONFIGURATION_ATTRIBUTE.ATTR_ID) final Long id, + @JsonProperty(CONFIGURATION_ATTRIBUTE.ATTR_PARENT_ID) final Long parentId, + @JsonProperty(CONFIGURATION_ATTRIBUTE.ATTR_NAME) final String name, + @JsonProperty(CONFIGURATION_ATTRIBUTE.ATTR_TYPE) final AttributeType type, + @JsonProperty(CONFIGURATION_ATTRIBUTE.ATTR_RESOURCES) final String resources, + @JsonProperty(CONFIGURATION_ATTRIBUTE.ATTR_DEPENDENCIES) final String dependencies, + @JsonProperty(CONFIGURATION_ATTRIBUTE.ATTR_DEFAULT_VALUE) final String defaultValue) { + + this.id = id; + this.parentId = parentId; + this.name = name; + this.type = type; + this.resources = resources; + this.dependencies = dependencies; + this.defaultValue = defaultValue; + } + + @Override + public String getModelId() { + return (this.id != null) + ? String.valueOf(this.id) + : null; + } + + @Override + public EntityType entityType() { + return EntityType.CONFIGURATION_ATTRIBUTE; + } + + public Long getId() { + return this.id; + } + + public Long getParentId() { + return this.parentId; + } + + @Override + public String getName() { + return this.name; + } + + public AttributeType getType() { + return this.type; + } + + public String getResources() { + return this.resources; + } + + public String getDependencies() { + return this.dependencies; + } + + public String getDefaultValue() { + return this.defaultValue; + } + + @Override + public String toString() { + return "ConfigurationAttribute [id=" + this.id + ", parentId=" + this.parentId + ", name=" + this.name + + ", type=" + this.type + + ", resources=" + this.resources + ", dependencies=" + this.dependencies + ", defaultValue=" + + this.defaultValue + + "]"; + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/ConfigurationNode.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/ConfigurationNode.java new file mode 100644 index 00000000..dae3817f --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/ConfigurationNode.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package ch.ethz.seb.sebserver.gbl.model.sebconfig; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +import ch.ethz.seb.sebserver.gbl.api.EntityType; +import ch.ethz.seb.sebserver.gbl.model.Domain.CONFIGURATION_NODE; +import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.GrantEntity; + +@JsonIgnoreProperties(ignoreUnknown = true) +public final class ConfigurationNode implements GrantEntity { + + public enum ConfigurationType { + TEMPLATE, + EXAM_CONFIG + } + + @JsonProperty(CONFIGURATION_NODE.ATTR_ID) + public final Long id; + + @NotNull + @JsonProperty(CONFIGURATION_NODE.ATTR_INSTITUTION_ID) + public final Long institutionId; + + @NotNull(message = "configurationNode:name:notNull") + @Size(min = 3, max = 255, message = "configurationNode:name:size:{min}:{max}:${validatedValue}") + @JsonProperty(CONFIGURATION_NODE.ATTR_NAME) + public final String name; + + @JsonProperty(CONFIGURATION_NODE.ATTR_DESCRIPTION) + public final String description; + + @NotNull + @JsonProperty(CONFIGURATION_NODE.ATTR_TYPE) + public final ConfigurationType type; + + @JsonProperty(CONFIGURATION_NODE.ATTR_TEMPLATE) + public final String templateName; + + @JsonProperty(CONFIGURATION_NODE.ATTR_OWNER) + public final String owner; + + @JsonCreator + public ConfigurationNode( + @JsonProperty(CONFIGURATION_NODE.ATTR_ID) final Long id, + @JsonProperty(CONFIGURATION_NODE.ATTR_INSTITUTION_ID) final Long institutionId, + @JsonProperty(CONFIGURATION_NODE.ATTR_NAME) final String name, + @JsonProperty(CONFIGURATION_NODE.ATTR_DESCRIPTION) final String description, + @JsonProperty(CONFIGURATION_NODE.ATTR_TYPE) final ConfigurationType type, + @JsonProperty(CONFIGURATION_NODE.ATTR_TEMPLATE) final String templateName, + @JsonProperty(CONFIGURATION_NODE.ATTR_OWNER) final String owner) { + + this.id = id; + this.institutionId = institutionId; + this.name = name; + this.description = description; + this.type = type; + this.templateName = templateName; + this.owner = owner; + } + + @Override + public EntityType entityType() { + return EntityType.CONFIGURATION_NODE; + } + + public Long getId() { + return this.id; + } + + @Override + public String getModelId() { + return (this.id != null) + ? String.valueOf(this.id) + : null; + } + + @Override + public Long getInstitutionId() { + return this.institutionId; + } + + @Override + public String getOwnerId() { + return this.owner; + } + + @Override + public String getName() { + return this.name; + } + + public String getDescription() { + return this.description; + } + + public ConfigurationType getType() { + return this.type; + } + + public String getTemplateName() { + return this.templateName; + } + + @Override + public String toString() { + return "ConfigurationNode [id=" + this.id + ", institutionId=" + this.institutionId + ", name=" + this.name + + ", description=" + + this.description + ", type=" + this.type + ", templateName=" + this.templateName + ", owner=" + + this.owner + "]"; + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/ConfigurationTableValue.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/ConfigurationTableValue.java new file mode 100644 index 00000000..3ed80f86 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/ConfigurationTableValue.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package ch.ethz.seb.sebserver.gbl.model.sebconfig; + +import java.util.Collections; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +import ch.ethz.seb.sebserver.gbl.model.Domain.CONFIGURATION_VALUE; + +@JsonIgnoreProperties(ignoreUnknown = true) +public final class ConfigurationTableValue { + + public static final String ATTR_COLUMNS = "columnAttributeIds"; + public static final String ATTR_VALUES = "values"; + + @JsonProperty(CONFIGURATION_VALUE.ATTR_CONFIGURATION_ID) + public final Long configurationId; + + @JsonProperty(CONFIGURATION_VALUE.ATTR_CONFIGURATION_ATTRIBUTE_ID) + public final long attributeId; + + @JsonProperty(ATTR_COLUMNS) + public final List columnAttributeIds; + + @JsonProperty(ATTR_VALUES) + public final List values; + + @JsonCreator + public ConfigurationTableValue( + @JsonProperty(CONFIGURATION_VALUE.ATTR_CONFIGURATION_ID) final Long configurationId, + @JsonProperty(CONFIGURATION_VALUE.ATTR_CONFIGURATION_ATTRIBUTE_ID) final Long attributeId, + @JsonProperty(ATTR_COLUMNS) final List columns, + @JsonProperty(ATTR_VALUES) final List values) { + + this.configurationId = configurationId; + this.attributeId = attributeId; + this.columnAttributeIds = Collections.unmodifiableList(columns); + this.values = Collections.unmodifiableList(values); + } + + public Long getConfigurationId() { + return this.configurationId; + } + + public long getAttributeId() { + return this.attributeId; + } + + public List getColumnAttributeIds() { + return this.columnAttributeIds; + } + + public List getValues() { + return this.values; + } + + @Override + public String toString() { + return "ConfigurationTableValue [configurationId=" + this.configurationId + ", attributeId=" + this.attributeId + + ", columnAttributeIds=" + this.columnAttributeIds + ", values=" + this.values + "]"; + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/ConfigurationValue.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/ConfigurationValue.java new file mode 100644 index 00000000..8b7a140d --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/ConfigurationValue.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package ch.ethz.seb.sebserver.gbl.model.sebconfig; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +import ch.ethz.seb.sebserver.gbl.api.EntityType; +import ch.ethz.seb.sebserver.gbl.model.Domain.CONFIGURATION_VALUE; +import ch.ethz.seb.sebserver.gbl.model.Entity; + +@JsonIgnoreProperties(ignoreUnknown = true) +public final class ConfigurationValue implements Entity { + + @JsonProperty(CONFIGURATION_VALUE.ATTR_ID) + public final Long id; + + @JsonProperty(CONFIGURATION_VALUE.ATTR_CONFIGURATION_ID) + public final Long configurationId; + + @JsonProperty(CONFIGURATION_VALUE.ATTR_CONFIGURATION_ATTRIBUTE_ID) + public final long attributeId; + + @JsonProperty(CONFIGURATION_VALUE.ATTR_LIST_INDEX) + public final Integer listIndex; + + @JsonProperty(CONFIGURATION_VALUE.ATTR_VALUE) + public final String value; + + @JsonCreator + public ConfigurationValue( + @JsonProperty(CONFIGURATION_VALUE.ATTR_ID) final Long id, + @JsonProperty(CONFIGURATION_VALUE.ATTR_CONFIGURATION_ID) final Long configurationId, + @JsonProperty(CONFIGURATION_VALUE.ATTR_CONFIGURATION_ATTRIBUTE_ID) final Long attributeId, + @JsonProperty(CONFIGURATION_VALUE.ATTR_LIST_INDEX) final Integer listIndex, + @JsonProperty(CONFIGURATION_VALUE.ATTR_VALUE) final String value) { + + this.id = id; + this.configurationId = configurationId; + this.attributeId = attributeId; + this.listIndex = listIndex; + this.value = value; + } + + @Override + public String getModelId() { + return (this.id != null) + ? String.valueOf(this.id) + : null; + } + + @Override + public EntityType entityType() { + return EntityType.CONFIGURATION_VALUE; + } + + @Override + public String getName() { + return getModelId(); + } + + public Long getId() { + return this.id; + } + + public Long getConfigurationId() { + return this.configurationId; + } + + public long getAttributeId() { + return this.attributeId; + } + + public int getListIndex() { + return this.listIndex; + } + + public String getValue() { + return this.value; + } + + @Override + public String toString() { + return "ConfigurationValue [id=" + this.id + ", configurationId=" + this.configurationId + ", attributeId=" + + this.attributeId + + ", listIndex=" + this.listIndex + ", value=" + this.value + "]"; + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/ExamConfiguration.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/ExamConfiguration.java new file mode 100644 index 00000000..8deed88a --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/ExamConfiguration.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package ch.ethz.seb.sebserver.gbl.model.sebconfig; + +import javax.validation.constraints.NotNull; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +import ch.ethz.seb.sebserver.gbl.api.EntityType; +import ch.ethz.seb.sebserver.gbl.model.Domain.EXAM; +import ch.ethz.seb.sebserver.gbl.model.Domain.EXAM_CONFIGURATION_MAP; +import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.GrantEntity; + +@JsonIgnoreProperties(ignoreUnknown = true) +public final class ExamConfiguration implements GrantEntity { + + @JsonProperty(EXAM_CONFIGURATION_MAP.ATTR_ID) + public final Long id; + + @NotNull + @JsonProperty(EXAM.ATTR_INSTITUTION_ID) + public final Long institutionId; + + @NotNull + @JsonProperty(EXAM_CONFIGURATION_MAP.ATTR_EXAM_ID) + public final Long examId; + + @NotNull + @JsonProperty(EXAM_CONFIGURATION_MAP.ATTR_CONFIGURATION_NODE_ID) + public final Long configurationNodeId; + + @JsonProperty(EXAM_CONFIGURATION_MAP.ATTR_USER_NAMES) + public final String userNames; + + @JsonCreator + public ExamConfiguration( + @JsonProperty(EXAM_CONFIGURATION_MAP.ATTR_ID) final Long id, + @JsonProperty(EXAM.ATTR_INSTITUTION_ID) final Long institutionId, + @JsonProperty(EXAM_CONFIGURATION_MAP.ATTR_EXAM_ID) final Long examId, + @JsonProperty(EXAM_CONFIGURATION_MAP.ATTR_CONFIGURATION_NODE_ID) final Long configurationNodeId, + @JsonProperty(EXAM_CONFIGURATION_MAP.ATTR_USER_NAMES) final String userNames) { + + this.id = id; + this.institutionId = institutionId; + this.examId = examId; + this.configurationNodeId = configurationNodeId; + this.userNames = userNames; + } + + @Override + public EntityType entityType() { + return EntityType.EXAM_CONFIGURATION_MAP; + } + + @Override + public String getName() { + return getModelId(); + } + + @Override + public String getModelId() { + return (this.id != null) + ? String.valueOf(this.id) + : null; + } + + @Override + public Long getInstitutionId() { + return this.institutionId; + } + + public Long getId() { + return this.id; + } + + public Long getExamId() { + return this.examId; + } + + public Long getConfigurationNodeId() { + return this.configurationNodeId; + } + + public String getUserNames() { + return this.userNames; + } + + @Override + public String toString() { + return "ExamConfiguration [id=" + this.id + ", institutionId=" + this.institutionId + ", examId=" + this.examId + + ", configurationNodeId=" + this.configurationNodeId + ", userNames=" + this.userNames + "]"; + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/Orientation.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/Orientation.java new file mode 100644 index 00000000..98cfe059 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/Orientation.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package ch.ethz.seb.sebserver.gbl.model.sebconfig; + +import javax.validation.constraints.NotNull; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +import ch.ethz.seb.sebserver.gbl.api.EntityType; +import ch.ethz.seb.sebserver.gbl.model.Domain.ORIENTATION; +import ch.ethz.seb.sebserver.gbl.model.Entity; + +@JsonIgnoreProperties(ignoreUnknown = true) +public final class Orientation implements Entity { + + public static final String FILTER_ATTR_TEMPLATE = "template"; + public static final String FILTER_ATTR_VIEW = "view"; + public static final String FILTER_ATTR_GROUP = "group"; + + @JsonProperty(ORIENTATION.ATTR_ID) + public final Long id; + + @NotNull + @JsonProperty(ORIENTATION.ATTR_CONFIG_ATTRIBUTE_ID) + public final Long attributeId; + + @JsonProperty(ORIENTATION.ATTR_TEMPLATE) + public final String template; + + @JsonProperty(ORIENTATION.ATTR_VIEW) + public final String view; + + @JsonProperty(ORIENTATION.ATTR_GROUP) + public final String group; + + @JsonProperty(ORIENTATION.ATTR_X_POSITION) + public final Integer xPosition; + + @JsonProperty(ORIENTATION.ATTR_Y_POSITION) + public final Integer yPosition; + + @JsonProperty(ORIENTATION.ATTR_WIDTH) + public final Integer width; + + @JsonProperty(ORIENTATION.ATTR_HEIGHT) + public final Integer height; + + @JsonCreator + public Orientation( + @JsonProperty(ORIENTATION.ATTR_ID) final Long id, + @JsonProperty(ORIENTATION.ATTR_CONFIG_ATTRIBUTE_ID) final Long attributeId, + @JsonProperty(ORIENTATION.ATTR_TEMPLATE) final String template, + @JsonProperty(ORIENTATION.ATTR_VIEW) final String view, + @JsonProperty(ORIENTATION.ATTR_GROUP) final String group, + @JsonProperty(ORIENTATION.ATTR_X_POSITION) final Integer xPosition, + @JsonProperty(ORIENTATION.ATTR_Y_POSITION) final Integer yPosition, + @JsonProperty(ORIENTATION.ATTR_WIDTH) final Integer width, + @JsonProperty(ORIENTATION.ATTR_HEIGHT) final Integer height) { + + this.id = id; + this.attributeId = attributeId; + this.template = template; + this.view = view; + this.group = group; + this.xPosition = xPosition; + this.yPosition = yPosition; + this.width = width; + this.height = height; + } + + @Override + public String getModelId() { + return (this.id != null) + ? String.valueOf(this.id) + : null; + } + + @Override + public EntityType entityType() { + return EntityType.ORIENTATION; + } + + @Override + public String getName() { + return getModelId(); + } + + public Long getId() { + return this.id; + } + + public Long getAttributeId() { + return this.attributeId; + } + + public String getTemplate() { + return this.template; + } + + public String getView() { + return this.view; + } + + public String getGroup() { + return this.group; + } + + public Integer getXPosition() { + return this.xPosition; + } + + public Integer getYPosition() { + return this.yPosition; + } + + public Integer getWidth() { + return this.width; + } + + public Integer getHeight() { + return this.height; + } + + @Override + public String toString() { + return "Orientation [id=" + this.id + ", attributeId=" + this.attributeId + ", template=" + this.template + + ", view=" + this.view + + ", group=" + this.group + ", xPosition=" + this.xPosition + ", yPosition=" + this.yPosition + + ", width=" + this.width + + ", height=" + this.height + "]"; + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserAccount.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserAccount.java index 3b7a7cee..5a304b6c 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserAccount.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserAccount.java @@ -17,37 +17,46 @@ import org.joda.time.DateTimeZone; import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.GrantEntity; +/** Defines a User-Account object */ public interface UserAccount extends GrantEntity { + /** The model id of the User-Account (UUID) */ @Override String getModelId(); + /** The institution identifier where the User-Account belongs to */ @Override Long getInstitutionId(); + /** The name of the User-Account */ @Override String getName(); + /** The user-name or login-name of the User-Account */ String getUsername(); + /** The email of the User-Account */ String getEmail(); + /** Indicates whether the User-Account is active or not */ Boolean getActive(); + /** Indicates whether the User-Account is active or not */ boolean isActive(); + /** The language of the User-Account */ Locale getLanguage(); + /** The time-zone of the User-Account */ DateTimeZone getTimeZone(); + /** The roles of the User-Account */ Set getRoles(); + /** The roles of the User-Account as UerRole */ EnumSet getUserRoles(); - String getNewPassword(); - - String getRetypedNewPassword(); - + /** The EntityKey (ModelId plus EntityType) of the User-Account */ @Override EntityKey getEntityKey(); diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserInfo.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserInfo.java index 218928f4..1332845e 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserInfo.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserInfo.java @@ -41,6 +41,7 @@ import ch.ethz.seb.sebserver.gbl.util.Utils; * to and from JSON within the Jackson library. * * This domain model is immutable and thread-save */ +@JsonIgnoreProperties(ignoreUnknown = true) public final class UserInfo implements UserAccount, Activatable, Serializable { private static final long serialVersionUID = 2526446136264377808L; @@ -98,7 +99,6 @@ public final class UserInfo implements UserAccount, Activatable, Serializable { public final Set roles; @JsonCreator - @JsonIgnoreProperties(ignoreUnknown = true) public UserInfo( @JsonProperty(USER.ATTR_UUID) final String uuid, @JsonProperty(USER.ATTR_INSTITUTION_ID) final Long institutionId, @@ -201,18 +201,6 @@ public final class UserInfo implements UserAccount, Activatable, Serializable { return this.roles.contains(userRole.name()); } - @JsonIgnore - @Override - public String getNewPassword() { - return null; - } - - @JsonIgnore - @Override - public String getRetypedNewPassword() { - return null; - } - @JsonIgnore @Override public EntityKey getEntityKey() { @@ -222,36 +210,11 @@ public final class UserInfo implements UserAccount, Activatable, Serializable { return new EntityKey(this.uuid, entityType()); } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((this.uuid == null) ? 0 : this.uuid.hashCode()); - return result; - } - @Override protected Object clone() throws CloneNotSupportedException { return UserInfo.of(this); } - @Override - public boolean equals(final Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - final UserInfo other = (UserInfo) obj; - if (this.uuid == null) { - if (other.uuid != null) - return false; - } else if (!this.uuid.equals(other.uuid)) - return false; - return true; - } - @Override public String toString() { return "UserInfo [uuid=" + this.uuid + ", institutionId=" + this.institutionId + ", name=" + this.name diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserMod.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserMod.java index 496ede86..0512051c 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserMod.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserMod.java @@ -34,8 +34,10 @@ import ch.ethz.seb.sebserver.gbl.model.Domain.USER; import ch.ethz.seb.sebserver.gbl.model.Domain.USER_ROLE; import ch.ethz.seb.sebserver.gbl.model.EntityKey; +@JsonIgnoreProperties(ignoreUnknown = true) public final class UserMod implements UserAccount { + @JsonProperty(USER.ATTR_UUID) public final String uuid; /** The foreign key identifier to the institution where the User belongs to */ @@ -86,7 +88,6 @@ public final class UserMod implements UserAccount { private final String confirmNewPassword; @JsonCreator - @JsonIgnoreProperties(ignoreUnknown = true) public UserMod( @JsonProperty(USER.ATTR_UUID) final String uuid, @JsonProperty(USER.ATTR_INSTITUTION_ID) final Long institutionId, @@ -146,7 +147,6 @@ public final class UserMod implements UserAccount { return this.uuid; } - @Override public String getNewPassword() { return this.newPassword; } @@ -190,7 +190,6 @@ public final class UserMod implements UserAccount { .collect(Collectors.toList())); } - @Override public String getRetypedNewPassword() { return this.confirmNewPassword; } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/authorization/GrantEntity.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/authorization/GrantEntity.java index 39649676..347aa7c5 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/authorization/GrantEntity.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/authorization/GrantEntity.java @@ -27,6 +27,8 @@ public interface GrantEntity extends Entity { * * @return The institution association of a GrantEntity */ @JsonIgnore - String getOwnerId(); + default String getOwnerId() { + return null; + } } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/FilterMap.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/FilterMap.java index c4aa5f0c..9a31744d 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/FilterMap.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/FilterMap.java @@ -18,6 +18,7 @@ import ch.ethz.seb.sebserver.gbl.model.exam.Exam; import ch.ethz.seb.sebserver.gbl.model.exam.Indicator; import ch.ethz.seb.sebserver.gbl.model.exam.QuizData; import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation; import ch.ethz.seb.sebserver.gbl.model.user.UserInfo; import ch.ethz.seb.sebserver.gbl.util.Utils; @@ -101,6 +102,18 @@ public class FilterMap extends POSTMapper { return getSQLWildcard(Indicator.FILTER_ATTR_NAME); } + public String getOrientationTemplate() { + return getSQLWildcard(Orientation.FILTER_ATTR_TEMPLATE); + } + + public String getOrientationView() { + return getSQLWildcard(Orientation.FILTER_ATTR_VIEW); + } + + public String getOrientationGroup() { + return getSQLWildcard(Orientation.FILTER_ATTR_GROUP); + } + public String getSQLWildcard(final String name) { return toSQLWildcard(this.params.getFirst(name)); } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/OrientationDAO.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/OrientationDAO.java new file mode 100644 index 00000000..8739f4e7 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/OrientationDAO.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package ch.ethz.seb.sebserver.webservice.servicelayer.dao; + +import java.util.Collection; + +import ch.ethz.seb.sebserver.gbl.model.EntityKey; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation; +import ch.ethz.seb.sebserver.gbl.util.Result; + +public interface OrientationDAO extends EntityDAO { + + Result> deleteAllOfTemplate(String templateName); + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamDAOImpl.java index cafb2537..a93dd9a5 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamDAOImpl.java @@ -34,6 +34,7 @@ import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.gbl.model.exam.Exam; import ch.ethz.seb.sebserver.gbl.model.exam.Exam.ExamType; import ch.ethz.seb.sebserver.gbl.model.exam.QuizData; +import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.gbl.util.Utils; import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ExamRecordDynamicSqlSupport; @@ -48,6 +49,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPIService; @Lazy @Component +@WebServiceProfile public class ExamDAOImpl implements ExamDAO { private final ExamRecordMapper examRecordMapper; diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/IndicatorDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/IndicatorDAOImpl.java index ead07c1a..66badb44 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/IndicatorDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/IndicatorDAOImpl.java @@ -30,6 +30,7 @@ import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.gbl.model.exam.Indicator; import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.IndicatorType; import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.Threshold; +import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ExamRecordDynamicSqlSupport; import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ExamRecordMapper; @@ -49,6 +50,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.TransactionHandler; @Lazy @Component +@WebServiceProfile public class IndicatorDAOImpl implements IndicatorDAO { private final IndicatorRecordMapper indicatorRecordMapper; diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/InstitutionDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/InstitutionDAOImpl.java index 3c68e42d..b7665aa9 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/InstitutionDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/InstitutionDAOImpl.java @@ -30,6 +30,7 @@ import ch.ethz.seb.sebserver.gbl.api.APIMessage.FieldValidationException; import ch.ethz.seb.sebserver.gbl.api.EntityType; import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.gbl.model.institution.Institution; +import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.InstitutionRecordDynamicSqlSupport; import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.InstitutionRecordMapper; @@ -43,6 +44,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.TransactionHandler; @Lazy @Component +@WebServiceProfile public class InstitutionDAOImpl implements InstitutionDAO { private final InstitutionRecordMapper institutionRecordMapper; diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/LmsSetupDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/LmsSetupDAOImpl.java index c8cae887..1e5a5439 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/LmsSetupDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/LmsSetupDAOImpl.java @@ -27,6 +27,7 @@ import ch.ethz.seb.sebserver.gbl.api.EntityType; import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup; import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType; +import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.LmsSetupRecordDynamicSqlSupport; import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.LmsSetupRecordMapper; @@ -42,6 +43,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.TransactionHandler; @Lazy @Component +@WebServiceProfile public class LmsSetupDAOImpl implements LmsSetupDAO { private final LmsSetupRecordMapper lmsSetupRecordMapper; diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/OrientationDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/OrientationDAOImpl.java new file mode 100644 index 00000000..ac0969d8 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/OrientationDAOImpl.java @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package ch.ethz.seb.sebserver.webservice.servicelayer.dao.impl; + +import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo; +import static org.mybatis.dynamic.sql.SqlBuilder.isIn; + +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import org.mybatis.dynamic.sql.SqlBuilder; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import ch.ethz.seb.sebserver.gbl.api.EntityType; +import ch.ethz.seb.sebserver.gbl.model.EntityKey; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation; +import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; +import ch.ethz.seb.sebserver.gbl.util.Result; +import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.OrientationRecordDynamicSqlSupport; +import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.OrientationRecordMapper; +import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.OrientationRecord; +import ch.ethz.seb.sebserver.webservice.servicelayer.dao.DAOLoggingSupport; +import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap; +import ch.ethz.seb.sebserver.webservice.servicelayer.dao.OrientationDAO; +import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ResourceNotFoundException; +import ch.ethz.seb.sebserver.webservice.servicelayer.dao.TransactionHandler; + +@Lazy +@Component +@WebServiceProfile +public class OrientationDAOImpl implements OrientationDAO { + + private final OrientationRecordMapper orientationRecordMapper; + + protected OrientationDAOImpl(final OrientationRecordMapper orientationRecordMapper) { + this.orientationRecordMapper = orientationRecordMapper; + } + + @Override + @Transactional(readOnly = true) + public EntityType entityType() { + return EntityType.ORIENTATION; + } + + @Override + @Transactional(readOnly = true) + public Result byPK(final Long id) { + return recordById(id) + .flatMap(OrientationDAOImpl::toDomainModel); + } + + @Override + @Transactional(readOnly = true) + public Result> byEntityKeys(final Set keys) { + return Result.tryCatch(() -> { + final List ids = extractPKsFromKeys(keys); + + return this.orientationRecordMapper.selectByExample() + .where(OrientationRecordDynamicSqlSupport.id, isIn(ids)) + .build() + .execute() + .stream() + .map(OrientationDAOImpl::toDomainModel) + .flatMap(DAOLoggingSupport::logUnexpectedErrorAndSkip) + .collect(Collectors.toList()); + }); + } + + @Override + @Transactional(readOnly = true) + public Result> allMatching( + final FilterMap filterMap, + final Predicate predicate) { + + return Result.tryCatch(() -> this.orientationRecordMapper + .selectByExample() + .where( + OrientationRecordDynamicSqlSupport.template, + SqlBuilder.isEqualToWhenPresent(filterMap.getOrientationTemplate())) + .and( + OrientationRecordDynamicSqlSupport.view, + SqlBuilder.isEqualToWhenPresent(filterMap.getOrientationView())) + .and( + OrientationRecordDynamicSqlSupport.group, + SqlBuilder.isEqualToWhenPresent(filterMap.getOrientationGroup())) + .build() + .execute() + .stream() + .map(OrientationDAOImpl::toDomainModel) + .flatMap(DAOLoggingSupport::logUnexpectedErrorAndSkip) + .filter(predicate) + .collect(Collectors.toList())); + } + + @Override + @Transactional + public Result createNew(final Orientation data) { + return Result.tryCatch(() -> { + + final OrientationRecord newRecord = new OrientationRecord( + null, + data.attributeId, + data.template, + data.view, + data.group, + data.xPosition, + data.yPosition, + data.width, + data.height); + + this.orientationRecordMapper.insert(newRecord); + return newRecord; + }) + .flatMap(OrientationDAOImpl::toDomainModel) + .onErrorDo(TransactionHandler::rollback); + } + + @Override + @Transactional + public Result save(final Orientation data) { + return Result.tryCatch(() -> { + + final OrientationRecord newRecord = new OrientationRecord( + data.id, + null, + null, + null, + data.group, + data.xPosition, + data.yPosition, + data.width, + data.height); + + this.orientationRecordMapper.updateByPrimaryKeySelective(newRecord); + return this.orientationRecordMapper.selectByPrimaryKey(data.id); + }) + .flatMap(OrientationDAOImpl::toDomainModel) + .onErrorDo(TransactionHandler::rollback); + } + + @Override + @Transactional + public Result> delete(final Set all) { + return Result.tryCatch(() -> { + + final List ids = extractPKsFromKeys(all); + + this.orientationRecordMapper.deleteByExample() + .where(OrientationRecordDynamicSqlSupport.id, isIn(ids)) + .build() + .execute(); + + return ids.stream() + .map(id -> new EntityKey(id, EntityType.ORIENTATION)) + .collect(Collectors.toList()); + }); + } + + @Override + @Transactional + public Result> deleteAllOfTemplate(final String templateName) { + return Result.tryCatch(() -> { + + final List ids = this.orientationRecordMapper.selectIdsByExample() + .where(OrientationRecordDynamicSqlSupport.template, isEqualTo(templateName)) + .build() + .execute(); + + this.orientationRecordMapper.deleteByExample() + .where(OrientationRecordDynamicSqlSupport.template, isEqualTo(templateName)) + .build() + .execute(); + + return ids.stream() + .map(id -> new EntityKey(id, EntityType.ORIENTATION)) + .collect(Collectors.toList()); + }); + } + + private Result recordById(final Long id) { + return Result.tryCatch(() -> { + final OrientationRecord record = this.orientationRecordMapper.selectByPrimaryKey(id); + if (record == null) { + throw new ResourceNotFoundException( + EntityType.ORIENTATION, + String.valueOf(id)); + } + return record; + }); + } + + private static Result toDomainModel(final OrientationRecord record) { + return Result.tryCatch(() -> new Orientation( + record.getId(), + record.getConfigAttributeId(), + record.getTemplate(), + record.getView(), + record.getGroup(), + record.getxPosition(), + record.getyPosition(), + record.getWidth(), + record.getHeight())); + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/SebClientConfigDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/SebClientConfigDAOImpl.java index 84bc4511..1f9a2b8d 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/SebClientConfigDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/SebClientConfigDAOImpl.java @@ -28,6 +28,7 @@ import org.springframework.transaction.annotation.Transactional; import ch.ethz.seb.sebserver.gbl.api.EntityType; import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.gbl.model.institution.SebClientConfig; +import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.SebClientConfigRecordDynamicSqlSupport; import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.SebClientConfigRecordMapper; @@ -43,6 +44,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.TransactionHandler; @Lazy @Component +@WebServiceProfile public class SebClientConfigDAOImpl implements SebClientConfigDAO { private final SebClientConfigRecordMapper sebClientConfigRecordMapper; diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserActivityLogDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserActivityLogDAOImpl.java index 48aff299..1eb49a98 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserActivityLogDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserActivityLogDAOImpl.java @@ -31,6 +31,7 @@ import ch.ethz.seb.sebserver.gbl.api.EntityType; import ch.ethz.seb.sebserver.gbl.model.Entity; import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.gbl.model.user.UserActivityLog; +import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.UserActivityLogRecordDynamicSqlSupport; import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.UserActivityLogRecordMapper; @@ -45,6 +46,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO; @Lazy @Component +@WebServiceProfile public class UserActivityLogDAOImpl implements UserActivityLogDAO { private static final Logger log = LoggerFactory.getLogger(UserActivityLogDAOImpl.class); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserDAOImpl.java index 81057b6a..3b579fc3 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserDAOImpl.java @@ -43,6 +43,7 @@ import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.gbl.model.user.UserAccount; import ch.ethz.seb.sebserver.gbl.model.user.UserInfo; import ch.ethz.seb.sebserver.gbl.model.user.UserMod; +import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.InstitutionRecordDynamicSqlSupport; import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.RoleRecordDynamicSqlSupport; @@ -60,6 +61,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserDAO; @Lazy @Component +@WebServiceProfile public class UserDAOImpl implements UserDAO { private static final Logger log = LoggerFactory.getLogger(UserDAOImpl.class); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/OpenEdxLmsAPITemplate.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/OpenEdxLmsAPITemplate.java index 95bd8a9c..3590d283 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/OpenEdxLmsAPITemplate.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/OpenEdxLmsAPITemplate.java @@ -46,7 +46,7 @@ import org.springframework.util.MultiValueMap; import ch.ethz.seb.sebserver.gbl.api.APIMessage; import ch.ethz.seb.sebserver.gbl.async.AsyncService; -import ch.ethz.seb.sebserver.gbl.async.CircuitBreakerSupplier; +import ch.ethz.seb.sebserver.gbl.async.MemoizingCircuitBreaker; import ch.ethz.seb.sebserver.gbl.model.exam.QuizData; import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup; import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetupTestResult; @@ -75,7 +75,7 @@ final class OpenEdxLmsAPITemplate implements LmsAPITemplate { private final Set knownTokenAccessPaths; private OAuth2RestTemplate restTemplate = null; - private final CircuitBreakerSupplier> allQuizzesSupplier; + private final MemoizingCircuitBreaker> allQuizzesSupplier; OpenEdxLmsAPITemplate( final AsyncService asyncService, diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ActivatableEntityController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ActivatableEntityController.java index defc6307..aa0f18d2 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ActivatableEntityController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ActivatableEntityController.java @@ -40,7 +40,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationSe * @param The concrete Entity domain-model type used on all GET, PUT * @param The concrete Entity domain-model type used for POST methods (new) */ public abstract class ActivatableEntityController - extends EntityController { + extends GrantEntityController { public ActivatableEntityController( final AuthorizationService authorizationGrantService, diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/EntityController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/GrantEntityController.java similarity index 96% rename from src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/EntityController.java rename to src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/GrantEntityController.java index c209b360..cfa4a4f8 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/EntityController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/GrantEntityController.java @@ -55,7 +55,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationSe * * @param The concrete Entity domain-model type used on all GET, PUT * @param The concrete Entity domain-model type used for POST methods (new) */ -public abstract class EntityController { +public abstract class GrantEntityController { protected final AuthorizationService authorization; protected final BulkActionService bulkActionService; @@ -64,7 +64,7 @@ public abstract class EntityController entityDAO, diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/IndicatorController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/IndicatorController.java index 62535887..817eb37b 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/IndicatorController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/IndicatorController.java @@ -29,7 +29,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationSe @WebServiceProfile @RestController @RequestMapping("/${sebserver.webservice.api.admin.endpoint}" + API.EXAM_INDICATOR_ENDPOINT) -public class IndicatorController extends EntityController { +public class IndicatorController extends GrantEntityController { private final ExamDAO examDao; diff --git a/src/test/java/ch/ethz/seb/sebserver/webservice/integration/api/admin/UserAPITest.java b/src/test/java/ch/ethz/seb/sebserver/webservice/integration/api/admin/UserAPITest.java index 81fe1b37..d59cf0e6 100644 --- a/src/test/java/ch/ethz/seb/sebserver/webservice/integration/api/admin/UserAPITest.java +++ b/src/test/java/ch/ethz/seb/sebserver/webservice/integration/api/admin/UserAPITest.java @@ -473,7 +473,7 @@ public class UserAPITest extends AdministrationAPIIntegrationTester { }); assertNotNull(createdUserGet); - assertEquals(createdUser, createdUserGet); + assertEquals(createdUser.getEntityKey(), createdUserGet.getEntityKey()); assertFalse(createdUserGet.isActive()); // check user activity log for newly created user