JSON export for Config-Key generation
This commit is contained in:
parent
6b9fc60981
commit
58c8b12ebe
20 changed files with 1034 additions and 181 deletions
pom.xml
src
main/java/ch/ethz/seb/sebserver
gbl
webservice
servicelayer/sebconfig
weblayer/api
test/java/ch/ethz/seb/sebserver/webservice
integration/api/exam
servicelayer/sebconfig/impl
4
pom.xml
4
pom.xml
|
@ -246,6 +246,10 @@
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-cache</artifactId>
|
<artifactId>spring-boot-starter-cache</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||||
|
<artifactId>jackson-dataformat-xml</artifactId>
|
||||||
|
</dependency>
|
||||||
<!-- NOTE since org.springframework.security.oauth is not fully migrated
|
<!-- NOTE since org.springframework.security.oauth is not fully migrated
|
||||||
to spring-boot-starter-security we have to declare a separate version here.
|
to spring-boot-starter-security we have to declare a separate version here.
|
||||||
This refers to the latest version of spring-security-oauth2 and should be
|
This refers to the latest version of spring-security-oauth2 and should be
|
||||||
|
|
|
@ -86,12 +86,18 @@ public class APIMessage implements Serializable {
|
||||||
|
|
||||||
public ResponseEntity<List<APIMessage>> createErrorResponse() {
|
public ResponseEntity<List<APIMessage>> createErrorResponse() {
|
||||||
final APIMessage message = of();
|
final APIMessage message = of();
|
||||||
return new ResponseEntity<>(Arrays.asList(message), this.httpStatus);
|
return new ResponseEntity<>(
|
||||||
|
Arrays.asList(message),
|
||||||
|
Utils.createJsonContentHeader(),
|
||||||
|
this.httpStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResponseEntity<Object> createErrorResponse(final String details, final String... attributes) {
|
public ResponseEntity<Object> createErrorResponse(final String details, final String... attributes) {
|
||||||
final APIMessage message = of(details, attributes);
|
final APIMessage message = of(details, attributes);
|
||||||
return new ResponseEntity<>(Arrays.asList(message), this.httpStatus);
|
return new ResponseEntity<>(
|
||||||
|
Arrays.asList(message),
|
||||||
|
Utils.createJsonContentHeader(),
|
||||||
|
this.httpStatus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,10 @@
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gbl.model.sebconfig;
|
package ch.ethz.seb.sebserver.gbl.model.sebconfig;
|
||||||
|
|
||||||
|
import java.text.Collator;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -36,6 +38,10 @@ public final class ConfigurationAttribute implements Entity, Comparable<Configur
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(ConfigurationAttribute.class);
|
private static final Logger log = LoggerFactory.getLogger(ConfigurationAttribute.class);
|
||||||
|
|
||||||
|
/** This is used to compare the attribute names for sorting used to generate the Config-Key
|
||||||
|
* See: https://www.safeexambrowser.org/developer/seb-config-key.html */
|
||||||
|
private static final Collator CULTURE_INVARIANT_COLLATOR = Collator.getInstance(Locale.ROOT);
|
||||||
|
|
||||||
/** This configuration attribute dependency key can be used to set a specific localized text key prefix for
|
/** This configuration attribute dependency key can be used to set a specific localized text key prefix for
|
||||||
* resources. This is usually convenient if two different attributes use the same resources and to avoid
|
* resources. This is usually convenient if two different attributes use the same resources and to avoid
|
||||||
* to multiply the resources for each attribute with the attribute name prefix, we can set a specific
|
* to multiply the resources for each attribute with the attribute name prefix, we can set a specific
|
||||||
|
@ -162,8 +168,9 @@ public final class ConfigurationAttribute implements Entity, Comparable<Configur
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(final ConfigurationAttribute attribute) {
|
public int compareTo(final ConfigurationAttribute attribute) {
|
||||||
// TODO check if this is correct in reference to https://www.safeexambrowser.org/developer/seb-config-key.html
|
return CULTURE_INVARIANT_COLLATOR.compare(
|
||||||
return this.name.compareToIgnoreCase(attribute.name);
|
this.name,
|
||||||
|
attribute.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -33,6 +33,9 @@ import org.joda.time.DateTime;
|
||||||
import org.joda.time.DateTimeZone;
|
import org.joda.time.DateTimeZone;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
|
import org.springframework.util.MultiValueMap;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
@ -391,4 +394,12 @@ public final class Utils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final MultiValueMap<String, String> createJsonContentHeader() {
|
||||||
|
final MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
|
||||||
|
headers.set(
|
||||||
|
HttpHeaders.CONTENT_TYPE,
|
||||||
|
org.springframework.http.MediaType.APPLICATION_JSON_UTF8_VALUE);
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,10 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||||
|
@ -18,7 +21,14 @@ import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
||||||
|
|
||||||
/** Defines the interface of a XML converter to be used to convert
|
/** Defines the interface of a XML converter to be used to convert
|
||||||
* ConfigurationValue for defined ConfigurationAttribute */
|
* ConfigurationValue for defined ConfigurationAttribute */
|
||||||
public interface XMLValueConverter {
|
public interface AttributeValueConverter {
|
||||||
|
|
||||||
|
/** This can be overwritten if a XMLValueConverter needs the XMLValueConverterService.
|
||||||
|
* The XMLValueConverterService is then injected by its self on initialization.
|
||||||
|
*
|
||||||
|
* @param xmlValueConverterService */
|
||||||
|
default void init(final AttributeValueConverterService xmlValueConverterService) {
|
||||||
|
}
|
||||||
|
|
||||||
/** Gives a Set of AttributeType's a concrete converter is able to
|
/** Gives a Set of AttributeType's a concrete converter is able to
|
||||||
* handle and convert ConfigurationValue of attributes of given types.
|
* handle and convert ConfigurationValue of attributes of given types.
|
||||||
|
@ -26,26 +36,42 @@ public interface XMLValueConverter {
|
||||||
* @return a Set of supported AttributeType's of the converter */
|
* @return a Set of supported AttributeType's of the converter */
|
||||||
Set<AttributeType> types();
|
Set<AttributeType> types();
|
||||||
|
|
||||||
/** The name of the Converter. This can be used if a Converter is specific to
|
/** The attribute names of the Converter. This can be used if a Converter is specific to
|
||||||
* an ConfigurationAttribute and not specific on a type of attribute.
|
* an ConfigurationAttribute and not specific on a type of attribute.
|
||||||
* This must give either the name if a specific ConfigurationAttribute or null/emptyString
|
* This must give either the name if a specific ConfigurationAttribute or empty set
|
||||||
*
|
*
|
||||||
* @return The name of a specific ConfigurationAttribute the converter works for. */
|
* @return The name of a specific ConfigurationAttribute the converter works for. */
|
||||||
String name();
|
default Set<String> names() {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
/** Used to convert the a given ConfigurationAttribute / ConfigurationValue
|
/** Used to convert the a given ConfigurationAttribute to plain XML text or block of SEB Configuration attribute.
|
||||||
* pair to plain XML text for block of this SEB Configuration attribute.
|
|
||||||
*
|
*
|
||||||
* @param out The output stream to write the plain XML text block to
|
* @param out The output stream to write the plain XML text block to
|
||||||
* @param attribute The ConfigurationAttribute containing all attribute information
|
* @param attribute The ConfigurationAttribute containing all attribute information
|
||||||
* @param value The ConfigurationValue containing the value
|
* @param valueSupplier The ConfigurationValue supplier
|
||||||
* @param xmlValueConverterService
|
|
||||||
* @throws IOException */
|
* @throws IOException */
|
||||||
void convertToXML(
|
void convertToXML(
|
||||||
OutputStream out,
|
OutputStream out,
|
||||||
ConfigurationAttribute attribute,
|
ConfigurationAttribute attribute,
|
||||||
ConfigurationValue value) throws IOException;
|
Function<ConfigurationAttribute, ConfigurationValue> valueSupplier) throws IOException;
|
||||||
|
|
||||||
|
/** Used to convert the a given ConfigurationAttribute to plain JSON text or block of SEB Configuration attribute.
|
||||||
|
*
|
||||||
|
* @param out The output stream to write the plain JSON text block to
|
||||||
|
* @param attribute The ConfigurationAttribute containing all attribute information
|
||||||
|
* @param valueSupplier The ConfigurationValue supplier
|
||||||
|
* @throws IOException */
|
||||||
|
void convertToJSON(
|
||||||
|
OutputStream out,
|
||||||
|
ConfigurationAttribute attribute,
|
||||||
|
Function<ConfigurationAttribute, ConfigurationValue> valueSupplier) throws IOException;
|
||||||
|
|
||||||
|
/** Get the real name of the SEB configuration attribute
|
||||||
|
* by cutting of the prefixed used for nested attributes
|
||||||
|
*
|
||||||
|
* @param attribute
|
||||||
|
* @return the SEB configuration attribute name */
|
||||||
default String extractName(final ConfigurationAttribute attribute) {
|
default String extractName(final ConfigurationAttribute attribute) {
|
||||||
final int lastIndexOf = attribute.name.lastIndexOf('.');
|
final int lastIndexOf = attribute.name.lastIndexOf('.');
|
||||||
if (lastIndexOf > 0) {
|
if (lastIndexOf > 0) {
|
||||||
|
@ -55,11 +81,8 @@ public interface XMLValueConverter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This can be overwritten if a XMLValueConverter needs the XMLValueConverterService.
|
default Stream<ConfigurationAttribute> convertAttribute(final ConfigurationAttribute attr) {
|
||||||
* The XMLValueConverterService is then injected by its self on initialization.
|
return Stream.of(attr);
|
||||||
*
|
|
||||||
* @param xmlValueConverterService */
|
|
||||||
default void init(final XMLValueConverterService xmlValueConverterService) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -11,12 +11,12 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||||
|
|
||||||
/** Interface of a SEB Exam Configuration XML conversion service */
|
/** Interface of a SEB Exam Configuration XML conversion service */
|
||||||
public interface XMLValueConverterService {
|
public interface AttributeValueConverterService {
|
||||||
|
|
||||||
/** Use this to get a XMLValueConverter for a given ConfigurationAttribute.
|
/** Use this to get a XMLValueConverter for a given ConfigurationAttribute.
|
||||||
*
|
*
|
||||||
* @param attribute The ConfigurationAttribute instance
|
* @param attribute The ConfigurationAttribute instance
|
||||||
* @return a XMLValueConverter for a given ConfigurationAttribute */
|
* @return a XMLValueConverter for a given ConfigurationAttribute */
|
||||||
XMLValueConverter getXMLConverter(ConfigurationAttribute attribute);
|
AttributeValueConverter getAttributeValueConverter(ConfigurationAttribute attribute);
|
||||||
|
|
||||||
}
|
}
|
|
@ -12,7 +12,6 @@ import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
@ -21,26 +20,26 @@ import org.springframework.stereotype.Service;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.XMLValueConverter;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.AttributeValueConverter;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.XMLValueConverterService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.AttributeValueConverterService;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Service
|
@Service
|
||||||
@WebServiceProfile
|
@WebServiceProfile
|
||||||
public class XMLValueConverterServiceImpl implements XMLValueConverterService {
|
public class AttributeValueConverterServiceImpl implements AttributeValueConverterService {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(XMLValueConverterServiceImpl.class);
|
private static final Logger log = LoggerFactory.getLogger(AttributeValueConverterServiceImpl.class);
|
||||||
|
|
||||||
private final Map<String, XMLValueConverter> convertersByAttributeName;
|
private final Map<String, AttributeValueConverter> convertersByAttributeName;
|
||||||
private final Map<AttributeType, XMLValueConverter> convertersByAttributeType;
|
private final Map<AttributeType, AttributeValueConverter> convertersByAttributeType;
|
||||||
|
|
||||||
public XMLValueConverterServiceImpl(final Collection<XMLValueConverter> converters) {
|
public AttributeValueConverterServiceImpl(final Collection<AttributeValueConverter> converters) {
|
||||||
this.convertersByAttributeName = new HashMap<>();
|
this.convertersByAttributeName = new HashMap<>();
|
||||||
this.convertersByAttributeType = new HashMap<>();
|
this.convertersByAttributeType = new HashMap<>();
|
||||||
for (final XMLValueConverter converter : converters) {
|
for (final AttributeValueConverter converter : converters) {
|
||||||
converter.init(this);
|
converter.init(this);
|
||||||
if (StringUtils.isNotBlank(converter.name())) {
|
for (final String attributeName : converter.names()) {
|
||||||
this.convertersByAttributeName.put(converter.name(), converter);
|
this.convertersByAttributeName.put(attributeName, converter);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final AttributeType aType : converter.types()) {
|
for (final AttributeType aType : converter.types()) {
|
||||||
|
@ -56,7 +55,7 @@ public class XMLValueConverterServiceImpl implements XMLValueConverterService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public XMLValueConverter getXMLConverter(final ConfigurationAttribute attribute) {
|
public AttributeValueConverter getAttributeValueConverter(final ConfigurationAttribute attribute) {
|
||||||
if (this.convertersByAttributeName.containsKey(attribute.name)) {
|
if (this.convertersByAttributeName.containsKey(attribute.name)) {
|
||||||
return this.convertersByAttributeName.get(attribute.name);
|
return this.convertersByAttributeName.get(attribute.name);
|
||||||
}
|
}
|
|
@ -15,6 +15,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -32,7 +33,8 @@ import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationAttributeDAO;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationAttributeDAO;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationDAO;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationDAO;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationValueDAO;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationValueDAO;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.XMLValueConverterService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.AttributeValueConverter;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.AttributeValueConverterService;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
|
@ -51,18 +53,18 @@ public class ExamConfigIO {
|
||||||
private final ConfigurationAttributeDAO configurationAttributeDAO;
|
private final ConfigurationAttributeDAO configurationAttributeDAO;
|
||||||
private final ConfigurationValueDAO configurationValueDAO;
|
private final ConfigurationValueDAO configurationValueDAO;
|
||||||
private final ConfigurationDAO configurationDAO;
|
private final ConfigurationDAO configurationDAO;
|
||||||
private final XMLValueConverterService xmlValueConverterService;
|
private final AttributeValueConverterService attributeValueConverterService;
|
||||||
|
|
||||||
protected ExamConfigIO(
|
protected ExamConfigIO(
|
||||||
final ConfigurationAttributeDAO configurationAttributeDAO,
|
final ConfigurationAttributeDAO configurationAttributeDAO,
|
||||||
final ConfigurationValueDAO configurationValueDAO,
|
final ConfigurationValueDAO configurationValueDAO,
|
||||||
final ConfigurationDAO configurationDAO,
|
final ConfigurationDAO configurationDAO,
|
||||||
final XMLValueConverterService xmlValueConverterService) {
|
final AttributeValueConverterService attributeValueConverterService) {
|
||||||
|
|
||||||
this.configurationAttributeDAO = configurationAttributeDAO;
|
this.configurationAttributeDAO = configurationAttributeDAO;
|
||||||
this.configurationValueDAO = configurationValueDAO;
|
this.configurationValueDAO = configurationValueDAO;
|
||||||
this.configurationDAO = configurationDAO;
|
this.configurationDAO = configurationDAO;
|
||||||
this.xmlValueConverterService = xmlValueConverterService;
|
this.attributeValueConverterService = attributeValueConverterService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Async(AsyncServiceSpringConfig.EXECUTOR_BEAN_NAME)
|
@Async(AsyncServiceSpringConfig.EXECUTOR_BEAN_NAME)
|
||||||
|
@ -75,17 +77,11 @@ public class ExamConfigIO {
|
||||||
log.debug("Start export SEB plain XML configuration asynconously");
|
log.debug("Start export SEB plain XML configuration asynconously");
|
||||||
}
|
}
|
||||||
|
|
||||||
// get all defined root configuration attributes
|
// get all defined root configuration attributes prepared and sorted
|
||||||
final Map<Long, ConfigurationAttribute> attributes = this.configurationAttributeDAO.getAllRootAttributes()
|
final List<ConfigurationAttribute> sortedAttributes = this.configurationAttributeDAO.getAllRootAttributes()
|
||||||
.getOrThrow()
|
.getOrThrow()
|
||||||
.stream()
|
.stream()
|
||||||
.collect(Collectors.toMap(
|
.flatMap(this::convertAttribute)
|
||||||
ConfigurationAttribute::getId,
|
|
||||||
Function.identity()));
|
|
||||||
|
|
||||||
final List<ConfigurationAttribute> sortedAttributes = attributes
|
|
||||||
.values()
|
|
||||||
.stream()
|
|
||||||
.sorted()
|
.sorted()
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
@ -94,14 +90,8 @@ public class ExamConfigIO {
|
||||||
.getFollowupConfiguration(configurationNodeId)
|
.getFollowupConfiguration(configurationNodeId)
|
||||||
.getOrThrow().id;
|
.getOrThrow().id;
|
||||||
|
|
||||||
// get all values for that attributes for given configurationId
|
final Function<ConfigurationAttribute, ConfigurationValue> configurationValueSupplier =
|
||||||
final Map<Long, ConfigurationValue> values = this.configurationValueDAO
|
getConfigurationValueSupplier(institutionId, configurationId);
|
||||||
.allRootAttributeValues(institutionId, configurationId)
|
|
||||||
.getOrThrow()
|
|
||||||
.stream()
|
|
||||||
.collect(Collectors.toMap(
|
|
||||||
ConfigurationValue::getAttributeId,
|
|
||||||
Function.identity()));
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// write headers
|
// write headers
|
||||||
|
@ -114,13 +104,10 @@ public class ExamConfigIO {
|
||||||
|
|
||||||
// write attributes
|
// write attributes
|
||||||
for (final ConfigurationAttribute attribute : sortedAttributes) {
|
for (final ConfigurationAttribute attribute : sortedAttributes) {
|
||||||
final ConfigurationValue configurationValue = values.get(attribute.id);
|
this.attributeValueConverterService.getAttributeValueConverter(attribute).convertToXML(
|
||||||
if (configurationValue != null) {
|
out,
|
||||||
this.xmlValueConverterService.getXMLConverter(attribute).convertToXML(
|
attribute,
|
||||||
out,
|
configurationValueSupplier);
|
||||||
attribute,
|
|
||||||
configurationValue);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// plist close
|
// plist close
|
||||||
|
@ -144,9 +131,34 @@ public class ExamConfigIO {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Stream<ConfigurationAttribute> convertAttribute(final ConfigurationAttribute attr) {
|
||||||
|
final AttributeValueConverter attributeValueConverter =
|
||||||
|
this.attributeValueConverterService.getAttributeValueConverter(attr);
|
||||||
|
if (attributeValueConverter != null) {
|
||||||
|
return attributeValueConverter.convertAttribute(attr);
|
||||||
|
} else {
|
||||||
|
return Stream.of(attr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Async(AsyncServiceSpringConfig.EXECUTOR_BEAN_NAME)
|
@Async(AsyncServiceSpringConfig.EXECUTOR_BEAN_NAME)
|
||||||
void importPlainXML(final InputStream in, final Long institutionId, final Long configurationNodeId) {
|
void importPlainXML(final InputStream in, final Long institutionId, final Long configurationNodeId) {
|
||||||
// TODO version 1
|
// TODO version 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Function<ConfigurationAttribute, ConfigurationValue> getConfigurationValueSupplier(
|
||||||
|
final Long institutionId,
|
||||||
|
final Long configurationId) {
|
||||||
|
|
||||||
|
final Map<Long, ConfigurationValue> mapping = this.configurationValueDAO
|
||||||
|
.allRootAttributeValues(institutionId, configurationId)
|
||||||
|
.getOrThrow()
|
||||||
|
.stream()
|
||||||
|
.collect(Collectors.toMap(
|
||||||
|
ConfigurationValue::getAttributeId,
|
||||||
|
Function.identity()));
|
||||||
|
|
||||||
|
return attr -> mapping.get(attr.id);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,6 +161,9 @@ public class SebExamConfigServiceImpl implements SebExamConfigService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String generateConfigKey(final Long configurationNodeId) {
|
public String generateConfigKey(final Long configurationNodeId) {
|
||||||
|
|
||||||
|
//DigestUtils.sha1Hex(data)
|
||||||
|
|
||||||
// TODO https://www.safeexambrowser.org/developer/seb-config-key.html
|
// TODO https://www.safeexambrowser.org/developer/seb-config-key.html
|
||||||
throw new UnsupportedOperationException("TODO");
|
throw new UnsupportedOperationException("TODO");
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
@ -25,23 +26,29 @@ import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.XMLValueConverter;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.AttributeValueConverter;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@WebServiceProfile
|
@WebServiceProfile
|
||||||
public class ArrayOfStringConverter implements XMLValueConverter {
|
public class ArrayOfStringConverter implements AttributeValueConverter {
|
||||||
|
|
||||||
public static final String ATTRIBUTE_NAME = "ExceptionsList";
|
public static final Set<String> ATTRIBUTE_NAMES = Utils.immutableSetOf("ExceptionsList");
|
||||||
|
|
||||||
public static final Set<AttributeType> SUPPORTED_TYPES = Collections.unmodifiableSet(
|
public static final Set<AttributeType> SUPPORTED_TYPES = Collections.unmodifiableSet(
|
||||||
new HashSet<>(Arrays.asList(
|
new HashSet<>(Arrays.asList(
|
||||||
AttributeType.MULTI_CHECKBOX_SELECTION,
|
AttributeType.MULTI_CHECKBOX_SELECTION,
|
||||||
AttributeType.MULTI_SELECTION)));
|
AttributeType.MULTI_SELECTION)));
|
||||||
|
|
||||||
private static final String TEMPLATE = "<key>%s</key><array>";
|
private static final String XML_TEMPLATE = "<key>%s</key><array>";
|
||||||
private static final String TEMPLATE_ENTRY = "<string>%s</string>";
|
private static final String XML_TEMPLATE_ENTRY = "<string>%s</string>";
|
||||||
private static final String TEMPLATE_EMPTY = "<key>%s</key><array></array>";
|
private static final String XML_TEMPLATE_EMPTY = "<key>%s</key><array></array>";
|
||||||
|
private static final String XML_ARRAY_CLOSE = "</array>";
|
||||||
|
|
||||||
|
private static final String JSON_TEMPLATE = "\"%s\":[";
|
||||||
|
private static final String JSON_TEMPLATE_ENTRY = "\"%s\"";
|
||||||
|
private static final String JSON_TEMPLATE_EMPTY = "\"%s\":[]";
|
||||||
|
private static final String JSON_ARRAY_CLOSE = "]";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<AttributeType> types() {
|
public Set<AttributeType> types() {
|
||||||
|
@ -49,28 +56,63 @@ public class ArrayOfStringConverter implements XMLValueConverter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String name() {
|
public Set<String> names() {
|
||||||
return ATTRIBUTE_NAME;
|
return ATTRIBUTE_NAMES;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void convertToXML(
|
public void convertToXML(
|
||||||
final OutputStream out,
|
final OutputStream out,
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final ConfigurationValue value) throws IOException {
|
final Function<ConfigurationAttribute, ConfigurationValue> valueSupplier) throws IOException {
|
||||||
|
|
||||||
|
convert(out, attribute, valueSupplier.apply(attribute), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void convertToJSON(
|
||||||
|
final OutputStream out,
|
||||||
|
final ConfigurationAttribute attribute,
|
||||||
|
final Function<ConfigurationAttribute, ConfigurationValue> valueSupplier) throws IOException {
|
||||||
|
|
||||||
|
convert(out, attribute, valueSupplier.apply(attribute), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void convert(
|
||||||
|
final OutputStream out,
|
||||||
|
final ConfigurationAttribute attribute,
|
||||||
|
final ConfigurationValue value,
|
||||||
|
final boolean xml) throws IOException {
|
||||||
|
|
||||||
final String val = (value.value != null) ? value.value : attribute.getDefaultValue();
|
final String val = (value.value != null) ? value.value : attribute.getDefaultValue();
|
||||||
if (StringUtils.isNotBlank(val)) {
|
if (StringUtils.isNotBlank(val)) {
|
||||||
|
|
||||||
final String[] values = StringUtils.split(val, Constants.LIST_SEPARATOR);
|
final String[] values = StringUtils.split(val, Constants.LIST_SEPARATOR);
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
sb.append(String.format(TEMPLATE, extractName(attribute)));
|
sb.append(String.format(
|
||||||
|
(xml) ? XML_TEMPLATE : JSON_TEMPLATE,
|
||||||
|
extractName(attribute)));
|
||||||
|
|
||||||
for (final String v : values) {
|
for (final String v : values) {
|
||||||
sb.append(String.format(TEMPLATE_ENTRY, v));
|
sb.append(String.format(
|
||||||
|
(xml) ? XML_TEMPLATE_ENTRY : JSON_TEMPLATE_ENTRY,
|
||||||
|
v));
|
||||||
|
if (!xml) {
|
||||||
|
sb.append(Constants.LIST_SEPARATOR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sb.append("</array>");
|
|
||||||
|
if (!xml) {
|
||||||
|
// delete tailing LIST_SEPARATOR (',') from loop
|
||||||
|
sb.deleteCharAt(sb.length() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.append((xml) ? XML_ARRAY_CLOSE : JSON_ARRAY_CLOSE);
|
||||||
out.write(Utils.toByteArray(sb.toString()));
|
out.write(Utils.toByteArray(sb.toString()));
|
||||||
} else {
|
} else {
|
||||||
out.write(Utils.toByteArray(String.format(TEMPLATE_EMPTY, extractName(attribute))));
|
out.write(Utils.toByteArray(String.format(
|
||||||
|
(xml) ? XML_TEMPLATE_EMPTY : JSON_TEMPLATE_EMPTY,
|
||||||
|
extractName(attribute))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,8 @@ import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@ -25,23 +25,19 @@ import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.XMLValueConverter;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.AttributeValueConverter;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@WebServiceProfile
|
@WebServiceProfile
|
||||||
public class BooleanConverter implements XMLValueConverter {
|
public class BooleanConverter implements AttributeValueConverter {
|
||||||
|
|
||||||
public static final Set<AttributeType> SUPPORTED_TYPES = Collections.unmodifiableSet(
|
public static final Set<AttributeType> SUPPORTED_TYPES = Collections.unmodifiableSet(
|
||||||
new HashSet<>(Arrays.asList(
|
new HashSet<>(Arrays.asList(
|
||||||
AttributeType.CHECKBOX)));
|
AttributeType.CHECKBOX)));
|
||||||
|
|
||||||
private static final String TEMPLATE = "<key>%s</key><%s />";
|
private static final String XML_TEMPLATE = "<key>%s</key><%s />";
|
||||||
|
private static final String JSON_TEMPLATE = "\"%s\":%s";
|
||||||
@Override
|
|
||||||
public String name() {
|
|
||||||
return StringUtils.EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<AttributeType> types() {
|
public Set<AttributeType> types() {
|
||||||
|
@ -52,14 +48,31 @@ public class BooleanConverter implements XMLValueConverter {
|
||||||
public void convertToXML(
|
public void convertToXML(
|
||||||
final OutputStream out,
|
final OutputStream out,
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final ConfigurationValue value) throws IOException {
|
final Function<ConfigurationAttribute, ConfigurationValue> valueSupplier) throws IOException {
|
||||||
|
|
||||||
|
convert(out, attribute, valueSupplier.apply(attribute), XML_TEMPLATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void convertToJSON(
|
||||||
|
final OutputStream out,
|
||||||
|
final ConfigurationAttribute attribute,
|
||||||
|
final Function<ConfigurationAttribute, ConfigurationValue> valueSupplier) throws IOException {
|
||||||
|
|
||||||
|
convert(out, attribute, valueSupplier.apply(attribute), JSON_TEMPLATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void convert(
|
||||||
|
final OutputStream out,
|
||||||
|
final ConfigurationAttribute attribute,
|
||||||
|
final ConfigurationValue value,
|
||||||
|
final String template) throws IOException {
|
||||||
|
|
||||||
out.write(Utils.toByteArray(
|
out.write(Utils.toByteArray(
|
||||||
String.format(
|
String.format(
|
||||||
TEMPLATE,
|
template,
|
||||||
extractName(attribute),
|
extractName(attribute),
|
||||||
(value.value != null) ? value.value : Constants.FALSE_STRING)));
|
(value.value != null) ? value.value : Constants.FALSE_STRING)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,10 @@ import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@ -24,12 +26,14 @@ import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.XMLValueConverter;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.AttributeValueConverter;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@WebServiceProfile
|
@WebServiceProfile
|
||||||
public class IntegerConverter implements XMLValueConverter {
|
public class IntegerConverter implements AttributeValueConverter {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(IntegerConverter.class);
|
||||||
|
|
||||||
public static final Set<AttributeType> SUPPORTED_TYPES = Collections.unmodifiableSet(
|
public static final Set<AttributeType> SUPPORTED_TYPES = Collections.unmodifiableSet(
|
||||||
new HashSet<>(Arrays.asList(
|
new HashSet<>(Arrays.asList(
|
||||||
|
@ -38,31 +42,52 @@ public class IntegerConverter implements XMLValueConverter {
|
||||||
AttributeType.SINGLE_SELECTION,
|
AttributeType.SINGLE_SELECTION,
|
||||||
AttributeType.RADIO_SELECTION)));
|
AttributeType.RADIO_SELECTION)));
|
||||||
|
|
||||||
private static final String TEMPLATE = "<key>%s</key><integer>%s</integer>";
|
private static final String XML_TEMPLATE = "<key>%s</key><integer>%s</integer>";
|
||||||
private static final String TEMPLATE_EMPTY = "<key>%s</key><integer />";
|
private static final String JSON_TEMPLATE = "\"%s\":%s";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<AttributeType> types() {
|
public Set<AttributeType> types() {
|
||||||
return SUPPORTED_TYPES;
|
return SUPPORTED_TYPES;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String name() {
|
|
||||||
return StringUtils.EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void convertToXML(
|
public void convertToXML(
|
||||||
final OutputStream out,
|
final OutputStream out,
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final ConfigurationValue value) throws IOException {
|
final Function<ConfigurationAttribute, ConfigurationValue> valueSupplier) throws IOException {
|
||||||
|
|
||||||
|
convert(out, attribute, valueSupplier.apply(attribute), XML_TEMPLATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void convertToJSON(
|
||||||
|
final OutputStream out,
|
||||||
|
final ConfigurationAttribute attribute,
|
||||||
|
final Function<ConfigurationAttribute, ConfigurationValue> valueSupplier) throws IOException {
|
||||||
|
|
||||||
|
convert(out, attribute, valueSupplier.apply(attribute), JSON_TEMPLATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void convert(
|
||||||
|
final OutputStream out,
|
||||||
|
final ConfigurationAttribute attribute,
|
||||||
|
final ConfigurationValue value,
|
||||||
|
final String template) throws IOException {
|
||||||
|
|
||||||
final String val = (value.value != null) ? value.value : attribute.getDefaultValue();
|
final String val = (value.value != null) ? value.value : attribute.getDefaultValue();
|
||||||
if (StringUtils.isNotBlank(val)) {
|
int intVal = 0;
|
||||||
out.write(Utils.toByteArray(String.format(TEMPLATE, extractName(attribute), val)));
|
|
||||||
} else {
|
try {
|
||||||
out.write(Utils.toByteArray(String.format(TEMPLATE_EMPTY, extractName(attribute))));
|
intVal = Integer.parseInt(val);
|
||||||
|
} catch (final NumberFormatException nfe) {
|
||||||
|
log.error("Failed to convert SEB configuration attribute value of type integer: {}", val, nfe);
|
||||||
|
intVal = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out.write(Utils.toByteArray(String.format(
|
||||||
|
template,
|
||||||
|
extractName(attribute),
|
||||||
|
intVal)));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@ import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
@ -22,20 +24,28 @@ import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.XMLValueConverter;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.AttributeValueConverter;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@WebServiceProfile
|
@WebServiceProfile
|
||||||
public class KioskModeConverter implements XMLValueConverter {
|
public class KioskModeConverter implements AttributeValueConverter {
|
||||||
|
|
||||||
public static final String NAME = "kioskMode";
|
public static final String ATTR_NAME_KIOSK_MODE = "kioskMode";
|
||||||
|
public static final String ATTR_NAME_CREATE_NEW_DESKTOP = "createNewDesktop";
|
||||||
|
public static final String ATTR_NAME_KILL_SHELL = "killExplorerShell";
|
||||||
|
|
||||||
private static final String TEMPLATE = "<key>createNewDesktop</key><%s /><key>killExplorerShell</key><%s />";
|
public static final Set<String> NAMES = Utils.immutableSetOf(
|
||||||
|
ATTR_NAME_KIOSK_MODE,
|
||||||
|
ATTR_NAME_CREATE_NEW_DESKTOP,
|
||||||
|
ATTR_NAME_KILL_SHELL);
|
||||||
|
|
||||||
|
private static final String XML_TEMPLATE = "<key>%s</key><%s />";
|
||||||
|
private static final String JSON_TEMPLATE = "\"%s\":%s";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String name() {
|
public Set<String> names() {
|
||||||
return NAME;
|
return NAMES;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -43,18 +53,53 @@ public class KioskModeConverter implements XMLValueConverter {
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stream<ConfigurationAttribute> convertAttribute(final ConfigurationAttribute attr) {
|
||||||
|
return Stream.of(
|
||||||
|
convertFrom(attr, ATTR_NAME_CREATE_NEW_DESKTOP),
|
||||||
|
convertFrom(attr, ATTR_NAME_KILL_SHELL));
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConfigurationAttribute convertFrom(final ConfigurationAttribute attr, final String name) {
|
||||||
|
return new ConfigurationAttribute(
|
||||||
|
attr.id, attr.parentId, name,
|
||||||
|
attr.type, attr.resources, attr.validator,
|
||||||
|
attr.dependencies, attr.defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void convertToXML(
|
public void convertToXML(
|
||||||
final OutputStream out,
|
final OutputStream out,
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final ConfigurationValue value) throws IOException {
|
final Function<ConfigurationAttribute, ConfigurationValue> valueSupplier) throws IOException {
|
||||||
|
|
||||||
final String val = value.getValue();
|
convert(out, valueSupplier.apply(attribute), attribute.name, XML_TEMPLATE);
|
||||||
out.write(Utils.toByteArray(
|
}
|
||||||
String.format(
|
|
||||||
TEMPLATE,
|
@Override
|
||||||
(val != null == "0".equals(val)) ? Constants.TRUE_STRING : Constants.FALSE_STRING,
|
public void convertToJSON(
|
||||||
(val != null == "1".equals(val)) ? Constants.TRUE_STRING : Constants.FALSE_STRING)));
|
final OutputStream out,
|
||||||
|
final ConfigurationAttribute attribute,
|
||||||
|
final Function<ConfigurationAttribute, ConfigurationValue> valueSupplier) throws IOException {
|
||||||
|
|
||||||
|
convert(out, valueSupplier.apply(attribute), attribute.name, JSON_TEMPLATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void convert(
|
||||||
|
final OutputStream out,
|
||||||
|
final ConfigurationValue value,
|
||||||
|
final String name,
|
||||||
|
final String template) throws IOException {
|
||||||
|
|
||||||
|
final String val = (ATTR_NAME_CREATE_NEW_DESKTOP.equals(name))
|
||||||
|
? value.getValue() == null || "0".equals(value.getValue())
|
||||||
|
? Constants.TRUE_STRING
|
||||||
|
: Constants.FALSE_STRING
|
||||||
|
: value.getValue() == null || "0".equals(value.getValue())
|
||||||
|
? Constants.FALSE_STRING
|
||||||
|
: Constants.TRUE_STRING;
|
||||||
|
|
||||||
|
out.write(Utils.toByteArray(String.format(template, name, val)));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
@ -24,12 +25,12 @@ import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.XMLValueConverter;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.AttributeValueConverter;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@WebServiceProfile
|
@WebServiceProfile
|
||||||
public class StringConverter implements XMLValueConverter {
|
public class StringConverter implements AttributeValueConverter {
|
||||||
|
|
||||||
public static final Set<AttributeType> SUPPORTED_TYPES = Collections.unmodifiableSet(
|
public static final Set<AttributeType> SUPPORTED_TYPES = Collections.unmodifiableSet(
|
||||||
new HashSet<>(Arrays.asList(
|
new HashSet<>(Arrays.asList(
|
||||||
|
@ -39,32 +40,61 @@ public class StringConverter implements XMLValueConverter {
|
||||||
AttributeType.DECIMAL,
|
AttributeType.DECIMAL,
|
||||||
AttributeType.COMBO_SELECTION)));
|
AttributeType.COMBO_SELECTION)));
|
||||||
|
|
||||||
private static final String TEMPLATE = "<key>%s</key><string>%s</string>";
|
private static final String XML_TEMPLATE = "<key>%s</key><string>%s</string>";
|
||||||
private static final String TEMPLATE_EMPTY = "<key>%s</key><string />";
|
private static final String XML_TEMPLATE_EMPTY = "<key>%s</key><string />";
|
||||||
|
|
||||||
|
private static final String JSON_TEMPLATE = "\"%s\":\"%s\"";
|
||||||
|
private static final String JSON_TEMPLATE_EMPTY = "\"%s\":";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<AttributeType> types() {
|
public Set<AttributeType> types() {
|
||||||
return SUPPORTED_TYPES;
|
return SUPPORTED_TYPES;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String name() {
|
|
||||||
return StringUtils.EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void convertToXML(
|
public void convertToXML(
|
||||||
final OutputStream out,
|
final OutputStream out,
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final ConfigurationValue value) throws IOException {
|
final Function<ConfigurationAttribute, ConfigurationValue> valueSupplier) throws IOException {
|
||||||
|
|
||||||
|
convert(
|
||||||
|
out,
|
||||||
|
attribute,
|
||||||
|
valueSupplier.apply(attribute),
|
||||||
|
XML_TEMPLATE, XML_TEMPLATE_EMPTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void convertToJSON(
|
||||||
|
final OutputStream out,
|
||||||
|
final ConfigurationAttribute attribute,
|
||||||
|
final Function<ConfigurationAttribute, ConfigurationValue> valueSupplier) throws IOException {
|
||||||
|
|
||||||
|
convert(
|
||||||
|
out,
|
||||||
|
attribute,
|
||||||
|
valueSupplier.apply(attribute),
|
||||||
|
JSON_TEMPLATE, JSON_TEMPLATE_EMPTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void convert(
|
||||||
|
final OutputStream out,
|
||||||
|
final ConfigurationAttribute attribute,
|
||||||
|
final ConfigurationValue value,
|
||||||
|
final String template,
|
||||||
|
final String emptyTemplate) throws IOException {
|
||||||
|
|
||||||
final String val = (value.value != null) ? value.value : attribute.getDefaultValue();
|
final String val = (value.value != null) ? value.value : attribute.getDefaultValue();
|
||||||
if (StringUtils.isNotBlank(val)) {
|
if (StringUtils.isNotBlank(val)) {
|
||||||
out.write(Utils.toByteArray(String.format(TEMPLATE, extractName(attribute), val)));
|
out.write(Utils.toByteArray(String.format(
|
||||||
|
template,
|
||||||
|
extractName(attribute),
|
||||||
|
val)));
|
||||||
} else {
|
} else {
|
||||||
out.write(Utils.toByteArray(String.format(TEMPLATE_EMPTY, extractName(attribute))));
|
out.write(Utils.toByteArray(String.format(
|
||||||
|
emptyTemplate,
|
||||||
|
extractName(attribute))));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,16 +13,18 @@ import java.io.OutputStream;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
||||||
|
@ -31,13 +33,13 @@ import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationAttributeDAO;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationAttributeDAO;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationValueDAO;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationValueDAO;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.XMLValueConverter;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.AttributeValueConverter;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.XMLValueConverterService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.AttributeValueConverterService;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@WebServiceProfile
|
@WebServiceProfile
|
||||||
public class TableConverter implements XMLValueConverter {
|
public class TableConverter implements AttributeValueConverter {
|
||||||
|
|
||||||
public static final Set<AttributeType> SUPPORTED_TYPES = Collections.unmodifiableSet(
|
public static final Set<AttributeType> SUPPORTED_TYPES = Collections.unmodifiableSet(
|
||||||
new HashSet<>(Arrays.asList(
|
new HashSet<>(Arrays.asList(
|
||||||
|
@ -45,16 +47,23 @@ public class TableConverter implements XMLValueConverter {
|
||||||
AttributeType.INLINE_TABLE,
|
AttributeType.INLINE_TABLE,
|
||||||
AttributeType.COMPOSITE_TABLE)));
|
AttributeType.COMPOSITE_TABLE)));
|
||||||
|
|
||||||
private static final String KEY_TEMPLATE = "<key>%s</key>";
|
private static final String XML_KEY_TEMPLATE = "<key>%s</key>";
|
||||||
private static final byte[] ARRAY_START = Utils.toByteArray("<array>");
|
private static final byte[] XML_ARRAY_START = Utils.toByteArray("<array>");
|
||||||
private static final byte[] ARRAY_END = Utils.toByteArray("</array>");
|
private static final byte[] XML_ARRAY_END = Utils.toByteArray("</array>");
|
||||||
private static final byte[] DICT_START = Utils.toByteArray("<dict>");
|
private static final byte[] XML_DICT_START = Utils.toByteArray("<dict>");
|
||||||
private static final byte[] DICT_END = Utils.toByteArray("</dict>");
|
private static final byte[] XML_DICT_END = Utils.toByteArray("</dict>");
|
||||||
private static final byte[] EMPTY_ARRAY = Utils.toByteArray("<array />");
|
private static final byte[] XML_EMPTY_ARRAY = Utils.toByteArray("<array />");
|
||||||
|
|
||||||
|
private static final String JSON_KEY_TEMPLATE = "\"%s\":";
|
||||||
|
private static final byte[] JSON_ARRAY_START = Utils.toByteArray("[");
|
||||||
|
private static final byte[] JSON_ARRAY_END = Utils.toByteArray("]");
|
||||||
|
private static final byte[] JSON_DICT_START = Utils.toByteArray("{");
|
||||||
|
private static final byte[] JSON_DICT_END = Utils.toByteArray("}");
|
||||||
|
private static final byte[] JSON_EMPTY_ARRAY = Utils.toByteArray("[]");
|
||||||
|
|
||||||
private final ConfigurationAttributeDAO configurationAttributeDAO;
|
private final ConfigurationAttributeDAO configurationAttributeDAO;
|
||||||
private final ConfigurationValueDAO configurationValueDAO;
|
private final ConfigurationValueDAO configurationValueDAO;
|
||||||
private XMLValueConverterService xmlValueConverterService;
|
private AttributeValueConverterService attributeValueConverterService;
|
||||||
|
|
||||||
public TableConverter(
|
public TableConverter(
|
||||||
final ConfigurationAttributeDAO configurationAttributeDAO,
|
final ConfigurationAttributeDAO configurationAttributeDAO,
|
||||||
|
@ -65,8 +74,8 @@ public class TableConverter implements XMLValueConverter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(final XMLValueConverterService xmlValueConverterService) {
|
public void init(final AttributeValueConverterService attributeValueConverterService) {
|
||||||
this.xmlValueConverterService = xmlValueConverterService;
|
this.attributeValueConverterService = attributeValueConverterService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -74,76 +83,127 @@ public class TableConverter implements XMLValueConverter {
|
||||||
return SUPPORTED_TYPES;
|
return SUPPORTED_TYPES;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String name() {
|
|
||||||
return StringUtils.EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void convertToXML(
|
public void convertToXML(
|
||||||
final OutputStream out,
|
final OutputStream out,
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final ConfigurationValue value) throws IOException {
|
final Function<ConfigurationAttribute, ConfigurationValue> valueSupplier) throws IOException {
|
||||||
|
|
||||||
out.write(Utils.toByteArray(String.format(KEY_TEMPLATE, extractName(attribute))));
|
convert(out, attribute, valueSupplier.apply(attribute), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void convertToJSON(
|
||||||
|
final OutputStream out,
|
||||||
|
final ConfigurationAttribute attribute,
|
||||||
|
final Function<ConfigurationAttribute, ConfigurationValue> valueSupplier) throws IOException {
|
||||||
|
|
||||||
|
convert(out, attribute, valueSupplier.apply(attribute), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void convert(
|
||||||
|
final OutputStream out,
|
||||||
|
final ConfigurationAttribute attribute,
|
||||||
|
final ConfigurationValue value,
|
||||||
|
final boolean xml) throws IOException {
|
||||||
|
|
||||||
final List<List<ConfigurationValue>> values = this.configurationValueDAO.getOrderedTableValues(
|
final List<List<ConfigurationValue>> values = this.configurationValueDAO.getOrderedTableValues(
|
||||||
value.institutionId,
|
value.institutionId,
|
||||||
value.configurationId,
|
value.configurationId,
|
||||||
attribute.id).getOrThrow();
|
attribute.id)
|
||||||
|
.getOrThrow();
|
||||||
|
|
||||||
if (values == null || values.isEmpty()) {
|
final boolean noValues = CollectionUtils.isEmpty(values);
|
||||||
out.write(EMPTY_ARRAY);
|
|
||||||
out.flush();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attribute.type != AttributeType.COMPOSITE_TABLE) {
|
if (attribute.type != AttributeType.COMPOSITE_TABLE) {
|
||||||
out.write(ARRAY_START);
|
|
||||||
|
out.write(Utils.toByteArray(String.format(
|
||||||
|
(xml) ? XML_KEY_TEMPLATE : JSON_KEY_TEMPLATE,
|
||||||
|
extractName(attribute))));
|
||||||
|
|
||||||
|
if (noValues) {
|
||||||
|
out.write((xml) ? XML_EMPTY_ARRAY : JSON_EMPTY_ARRAY);
|
||||||
|
out.flush();
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
out.write((xml) ? XML_ARRAY_START : JSON_ARRAY_START);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (noValues) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
out.write(Utils.toByteArray(String.format(
|
||||||
|
(xml) ? XML_KEY_TEMPLATE : JSON_KEY_TEMPLATE,
|
||||||
|
extractName(attribute))));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writeRows(
|
writeRows(
|
||||||
out,
|
out,
|
||||||
getAttributes(attribute),
|
getSortedChildAttributes(attribute),
|
||||||
values,
|
values,
|
||||||
this.xmlValueConverterService);
|
this.attributeValueConverterService,
|
||||||
|
xml);
|
||||||
|
|
||||||
if (attribute.type != AttributeType.COMPOSITE_TABLE) {
|
if (attribute.type != AttributeType.COMPOSITE_TABLE) {
|
||||||
out.write(ARRAY_END);
|
out.write((xml) ? XML_ARRAY_END : JSON_ARRAY_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
out.flush();
|
out.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<Long, ConfigurationAttribute> getAttributes(final ConfigurationAttribute attribute) {
|
|
||||||
return this.configurationAttributeDAO
|
|
||||||
.allMatching(new FilterMap().putIfAbsent(
|
|
||||||
ConfigurationAttribute.FILTER_ATTR_PARENT_ID,
|
|
||||||
attribute.getModelId()))
|
|
||||||
.getOrThrow()
|
|
||||||
.stream()
|
|
||||||
.collect(Collectors.toMap(
|
|
||||||
attr -> attr.id,
|
|
||||||
Function.identity()));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeRows(
|
private void writeRows(
|
||||||
final OutputStream out,
|
final OutputStream out,
|
||||||
final Map<Long, ConfigurationAttribute> attributeMap,
|
final Map<Long, ConfigurationAttribute> attributeMap,
|
||||||
final List<List<ConfigurationValue>> values,
|
final List<List<ConfigurationValue>> values,
|
||||||
final XMLValueConverterService xmlValueConverterService) throws IOException {
|
final AttributeValueConverterService attributeValueConverterService,
|
||||||
|
final boolean xml) throws IOException {
|
||||||
|
|
||||||
for (final List<ConfigurationValue> rowValues : values) {
|
final Iterator<List<ConfigurationValue>> irows = values.iterator();
|
||||||
out.write(DICT_START);
|
|
||||||
for (final ConfigurationValue value : rowValues) {
|
while (irows.hasNext()) {
|
||||||
|
final List<ConfigurationValue> rowValues = irows.next();
|
||||||
|
out.write((xml) ? XML_DICT_START : JSON_DICT_START);
|
||||||
|
|
||||||
|
final Iterator<ConfigurationValue> ivalue = rowValues.iterator();
|
||||||
|
|
||||||
|
while (ivalue.hasNext()) {
|
||||||
|
final ConfigurationValue value = ivalue.next();
|
||||||
final ConfigurationAttribute attr = attributeMap.get(value.attributeId);
|
final ConfigurationAttribute attr = attributeMap.get(value.attributeId);
|
||||||
final XMLValueConverter converter = xmlValueConverterService.getXMLConverter(attr);
|
final AttributeValueConverter converter =
|
||||||
converter.convertToXML(out, attr, value);
|
attributeValueConverterService.getAttributeValueConverter(attr);
|
||||||
|
|
||||||
|
if (xml) {
|
||||||
|
converter.convertToXML(out, attr, a -> value);
|
||||||
|
} else {
|
||||||
|
converter.convertToJSON(out, attr, a -> value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!xml && ivalue.hasNext()) {
|
||||||
|
out.write(Utils.toByteArray(Constants.LIST_SEPARATOR));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
out.write(DICT_END);
|
out.write((xml) ? XML_DICT_END : JSON_DICT_END);
|
||||||
|
|
||||||
|
if (!xml && irows.hasNext()) {
|
||||||
|
out.write(Utils.toByteArray(Constants.LIST_SEPARATOR));
|
||||||
|
}
|
||||||
|
|
||||||
out.flush();
|
out.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Map<Long, ConfigurationAttribute> getSortedChildAttributes(final ConfigurationAttribute attribute) {
|
||||||
|
return this.configurationAttributeDAO
|
||||||
|
.allMatching(new FilterMap().putIfAbsent(
|
||||||
|
ConfigurationAttribute.FILTER_ATTR_PARENT_ID,
|
||||||
|
attribute.getModelId()))
|
||||||
|
.getOrThrow()
|
||||||
|
.stream()
|
||||||
|
.sorted()
|
||||||
|
.collect(Collectors.toMap(
|
||||||
|
attr -> attr.id,
|
||||||
|
Function.identity()));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExcep
|
||||||
import ch.ethz.seb.sebserver.gbl.api.APIMessage;
|
import ch.ethz.seb.sebserver.gbl.api.APIMessage;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.APIMessage.APIMessageException;
|
import ch.ethz.seb.sebserver.gbl.api.APIMessage.APIMessageException;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.APIMessage.FieldValidationException;
|
import ch.ethz.seb.sebserver.gbl.api.APIMessage.FieldValidationException;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.PermissionDeniedException;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.PermissionDeniedException;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ResourceNotFoundException;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ResourceNotFoundException;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationException;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationException;
|
||||||
|
@ -51,7 +52,10 @@ public class APIExceptionHandler extends ResponseEntityExceptionHandler {
|
||||||
|
|
||||||
log.error("Unexpected generic error catched at the API endpoint: ", ex);
|
log.error("Unexpected generic error catched at the API endpoint: ", ex);
|
||||||
final List<APIMessage> errors = Arrays.asList(APIMessage.ErrorMessage.GENERIC.of(ex.getMessage()));
|
final List<APIMessage> errors = Arrays.asList(APIMessage.ErrorMessage.GENERIC.of(ex.getMessage()));
|
||||||
return new ResponseEntity<>(errors, status);
|
return new ResponseEntity<>(
|
||||||
|
errors,
|
||||||
|
Utils.createJsonContentHeader(),
|
||||||
|
status);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -67,7 +71,10 @@ public class APIExceptionHandler extends ResponseEntityExceptionHandler {
|
||||||
.map(field -> APIMessage.fieldValidationError(field))
|
.map(field -> APIMessage.fieldValidationError(field))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
return new ResponseEntity<>(valErrors, HttpStatus.BAD_REQUEST);
|
return new ResponseEntity<>(
|
||||||
|
valErrors,
|
||||||
|
Utils.createJsonContentHeader(),
|
||||||
|
HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler(OAuth2Exception.class)
|
@ExceptionHandler(OAuth2Exception.class)
|
||||||
|
@ -77,7 +84,10 @@ public class APIExceptionHandler extends ResponseEntityExceptionHandler {
|
||||||
|
|
||||||
log.error("OAuth2Exception: ", ex);
|
log.error("OAuth2Exception: ", ex);
|
||||||
final APIMessage message = APIMessage.ErrorMessage.UNAUTHORIZED.of(ex.getMessage());
|
final APIMessage message = APIMessage.ErrorMessage.UNAUTHORIZED.of(ex.getMessage());
|
||||||
return new ResponseEntity<>(message, HttpStatus.UNAUTHORIZED);
|
return new ResponseEntity<>(
|
||||||
|
message,
|
||||||
|
Utils.createJsonContentHeader(),
|
||||||
|
HttpStatus.UNAUTHORIZED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler(BeanValidationException.class)
|
@ExceptionHandler(BeanValidationException.class)
|
||||||
|
@ -91,7 +101,10 @@ public class APIExceptionHandler extends ResponseEntityExceptionHandler {
|
||||||
.map(field -> APIMessage.fieldValidationError(field))
|
.map(field -> APIMessage.fieldValidationError(field))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
return new ResponseEntity<>(valErrors, HttpStatus.BAD_REQUEST);
|
return new ResponseEntity<>(
|
||||||
|
valErrors,
|
||||||
|
Utils.createJsonContentHeader(),
|
||||||
|
HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler(ResourceNotFoundException.class)
|
@ExceptionHandler(ResourceNotFoundException.class)
|
||||||
|
@ -149,6 +162,7 @@ public class APIExceptionHandler extends ResponseEntityExceptionHandler {
|
||||||
|
|
||||||
return new ResponseEntity<>(
|
return new ResponseEntity<>(
|
||||||
ex.getAPIMessages(),
|
ex.getAPIMessages(),
|
||||||
|
Utils.createJsonContentHeader(),
|
||||||
HttpStatus.BAD_REQUEST);
|
HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,6 +173,7 @@ public class APIExceptionHandler extends ResponseEntityExceptionHandler {
|
||||||
|
|
||||||
return new ResponseEntity<>(
|
return new ResponseEntity<>(
|
||||||
Arrays.asList(ex.apiMessage),
|
Arrays.asList(ex.apiMessage),
|
||||||
|
Utils.createJsonContentHeader(),
|
||||||
HttpStatus.BAD_REQUEST);
|
HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* 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.sebconfig.impl;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||||
|
|
||||||
|
public class ConfigAttributeSortOrderTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSortOrder() throws Exception {
|
||||||
|
// test example from: https://www.safeexambrowser.org/developer/seb-config-key.html
|
||||||
|
// For example the key <key>allowWlan</key> comes before <key>allowWLAN</key>
|
||||||
|
|
||||||
|
final ConfigurationAttribute aa = new ConfigurationAttribute(
|
||||||
|
1L,
|
||||||
|
null,
|
||||||
|
"aa",
|
||||||
|
AttributeType.CHECKBOX,
|
||||||
|
null, null, null, "false");
|
||||||
|
|
||||||
|
final ConfigurationAttribute allowWlan = new ConfigurationAttribute(
|
||||||
|
1L,
|
||||||
|
null,
|
||||||
|
"allowWlan",
|
||||||
|
AttributeType.CHECKBOX,
|
||||||
|
null, null, null, "false");
|
||||||
|
final ConfigurationAttribute allowWLAN = new ConfigurationAttribute(
|
||||||
|
1L,
|
||||||
|
null,
|
||||||
|
"allowWLAN",
|
||||||
|
AttributeType.CHECKBOX,
|
||||||
|
null, null, null, "false");
|
||||||
|
|
||||||
|
final ConfigurationAttribute zz = new ConfigurationAttribute(
|
||||||
|
1L,
|
||||||
|
null,
|
||||||
|
"zz",
|
||||||
|
AttributeType.CHECKBOX,
|
||||||
|
null, null, null, "false");
|
||||||
|
|
||||||
|
final List<ConfigurationAttribute> list = Arrays.asList(zz, allowWLAN, aa, allowWlan);
|
||||||
|
Collections.sort(list);
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
"[aa, allowWlan, allowWLAN, zz]",
|
||||||
|
list.stream()
|
||||||
|
.map(ConfigurationAttribute::getName)
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,161 @@
|
||||||
|
/*
|
||||||
|
* 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.sebconfig.impl.converter;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
||||||
|
|
||||||
|
public class ArrayOfStringConverterTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testXML() throws Exception {
|
||||||
|
final ArrayOfStringConverter arrayOfStringConverter = new ArrayOfStringConverter();
|
||||||
|
final ConfigurationAttribute attribute = new ConfigurationAttribute(
|
||||||
|
1L,
|
||||||
|
null,
|
||||||
|
"attribute",
|
||||||
|
AttributeType.CHECKBOX,
|
||||||
|
null, null, null, "defaultValue");
|
||||||
|
|
||||||
|
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
arrayOfStringConverter.convertToXML(
|
||||||
|
out,
|
||||||
|
attribute,
|
||||||
|
attr -> new ConfigurationValue(1l, 1l, 1l, 1l, 1, "one,two,tree"));
|
||||||
|
|
||||||
|
final String xmlString = new String(out.toByteArray());
|
||||||
|
assertEquals(
|
||||||
|
"<key>attribute</key><array><string>one</string><string>two</string><string>tree</string></array>",
|
||||||
|
xmlString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEmptyXML() throws Exception {
|
||||||
|
final ArrayOfStringConverter arrayOfStringConverter = new ArrayOfStringConverter();
|
||||||
|
final ConfigurationAttribute attribute = new ConfigurationAttribute(
|
||||||
|
1L,
|
||||||
|
null,
|
||||||
|
"attribute",
|
||||||
|
AttributeType.CHECKBOX,
|
||||||
|
null, null, null, "defaultValue");
|
||||||
|
|
||||||
|
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
arrayOfStringConverter.convertToXML(
|
||||||
|
out,
|
||||||
|
attribute,
|
||||||
|
attr -> new ConfigurationValue(1l, 1l, 1l, 1l, 1, ""));
|
||||||
|
|
||||||
|
final String xmlString = new String(out.toByteArray());
|
||||||
|
assertEquals(
|
||||||
|
"<key>attribute</key><array></array>",
|
||||||
|
xmlString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNullXML() throws Exception {
|
||||||
|
final ArrayOfStringConverter arrayOfStringConverter = new ArrayOfStringConverter();
|
||||||
|
final ConfigurationAttribute attribute = new ConfigurationAttribute(
|
||||||
|
1L,
|
||||||
|
null,
|
||||||
|
"attribute",
|
||||||
|
AttributeType.CHECKBOX,
|
||||||
|
null, null, null, "defaultValue");
|
||||||
|
|
||||||
|
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
arrayOfStringConverter.convertToXML(
|
||||||
|
out,
|
||||||
|
attribute,
|
||||||
|
attr -> new ConfigurationValue(1l, 1l, 1l, 1l, 1, null));
|
||||||
|
|
||||||
|
final String xmlString = new String(out.toByteArray());
|
||||||
|
assertEquals(
|
||||||
|
"<key>attribute</key><array><string>defaultValue</string></array>",
|
||||||
|
xmlString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testJSON() throws Exception {
|
||||||
|
final ArrayOfStringConverter arrayOfStringConverter = new ArrayOfStringConverter();
|
||||||
|
final ConfigurationAttribute attribute = new ConfigurationAttribute(
|
||||||
|
1L,
|
||||||
|
null,
|
||||||
|
"attribute",
|
||||||
|
AttributeType.CHECKBOX,
|
||||||
|
null, null, null, "defaultValue");
|
||||||
|
|
||||||
|
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
arrayOfStringConverter.convertToJSON(
|
||||||
|
out,
|
||||||
|
attribute,
|
||||||
|
attr -> new ConfigurationValue(1l, 1l, 1l, 1l, 1, "one,two,tree"));
|
||||||
|
|
||||||
|
final String xmlString = new String(out.toByteArray());
|
||||||
|
assertEquals(
|
||||||
|
"\"attribute\":[\"one\",\"two\",\"tree\"]",
|
||||||
|
xmlString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEmptyJSON() throws Exception {
|
||||||
|
final ArrayOfStringConverter arrayOfStringConverter = new ArrayOfStringConverter();
|
||||||
|
final ConfigurationAttribute attribute = new ConfigurationAttribute(
|
||||||
|
1L,
|
||||||
|
null,
|
||||||
|
"attribute",
|
||||||
|
AttributeType.CHECKBOX,
|
||||||
|
null, null, null, "defaultValue");
|
||||||
|
|
||||||
|
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
arrayOfStringConverter.convertToJSON(
|
||||||
|
out,
|
||||||
|
attribute,
|
||||||
|
attr -> new ConfigurationValue(1l, 1l, 1l, 1l, 1, ""));
|
||||||
|
|
||||||
|
final String xmlString = new String(out.toByteArray());
|
||||||
|
assertEquals(
|
||||||
|
"\"attribute\":[]",
|
||||||
|
xmlString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNullJSON() throws Exception {
|
||||||
|
final ArrayOfStringConverter arrayOfStringConverter = new ArrayOfStringConverter();
|
||||||
|
final ConfigurationAttribute attribute = new ConfigurationAttribute(
|
||||||
|
1L,
|
||||||
|
null,
|
||||||
|
"attribute",
|
||||||
|
AttributeType.CHECKBOX,
|
||||||
|
null, null, null, "defaultValue");
|
||||||
|
|
||||||
|
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
arrayOfStringConverter.convertToJSON(
|
||||||
|
out,
|
||||||
|
attribute,
|
||||||
|
attr -> new ConfigurationValue(1l, 1l, 1l, 1l, 1, null));
|
||||||
|
|
||||||
|
final String xmlString = new String(out.toByteArray());
|
||||||
|
assertEquals(
|
||||||
|
"\"attribute\":[\"defaultValue\"]",
|
||||||
|
xmlString);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,329 @@
|
||||||
|
/*
|
||||||
|
* 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.sebconfig.impl.converter;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationAttributeDAO;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationValueDAO;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.AttributeValueConverter;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.AttributeValueConverterService;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl.AttributeValueConverterServiceImpl;
|
||||||
|
|
||||||
|
public class TableConverterTest {
|
||||||
|
|
||||||
|
// ********************************
|
||||||
|
// **** table
|
||||||
|
// ********************************
|
||||||
|
private final ConfigurationAttribute TABLE_ATTR =
|
||||||
|
new ConfigurationAttribute(1L, null, "table", AttributeType.TABLE, null, null, null, null);
|
||||||
|
private final ConfigurationValue TABLE_VALUE =
|
||||||
|
new ConfigurationValue(1L, 1L, 1L, 1L, 0, null);
|
||||||
|
|
||||||
|
private final ConfigurationAttribute COLUMN_ATTR_1 =
|
||||||
|
new ConfigurationAttribute(2L, 1L, "attr1", AttributeType.TEXT_FIELD, null, null, null, null);
|
||||||
|
private final ConfigurationAttribute COLUMN_ATTR_2 =
|
||||||
|
new ConfigurationAttribute(3L, 1L, "attr2", AttributeType.TEXT_FIELD, null, null, null, null);
|
||||||
|
|
||||||
|
private final ConfigurationValue ROW_1_ATTR_1 =
|
||||||
|
new ConfigurationValue(2L, 1L, 1L, 2L, 0, "1");
|
||||||
|
private final ConfigurationValue ROW_1_ATTR_2 =
|
||||||
|
new ConfigurationValue(3L, 1L, 1L, 3L, 0, "2");
|
||||||
|
|
||||||
|
private final ConfigurationValue ROW_2_ATTR_1 =
|
||||||
|
new ConfigurationValue(4L, 1L, 1L, 2L, 1, "3");
|
||||||
|
private final ConfigurationValue ROW_2_ATTR_2 =
|
||||||
|
new ConfigurationValue(5L, 1L, 1L, 3L, 1, "4");
|
||||||
|
|
||||||
|
private final Collection<ConfigurationAttribute> TABLE_COLUMNS = Arrays.asList(
|
||||||
|
this.COLUMN_ATTR_1,
|
||||||
|
this.COLUMN_ATTR_2);
|
||||||
|
|
||||||
|
private final List<List<ConfigurationValue>> TABLE_VALUES = Arrays.asList(
|
||||||
|
Arrays.asList(this.ROW_1_ATTR_1, this.ROW_1_ATTR_2),
|
||||||
|
Arrays.asList(this.ROW_2_ATTR_1, this.ROW_2_ATTR_2));
|
||||||
|
|
||||||
|
// ********************************
|
||||||
|
// **** Composite table
|
||||||
|
// ********************************
|
||||||
|
private final ConfigurationAttribute COMPOSITE_TABLE_ATTR =
|
||||||
|
new ConfigurationAttribute(1L, null, "table", AttributeType.COMPOSITE_TABLE, null, null, null, null);
|
||||||
|
private final ConfigurationValue COMPOSITE_TABLE_VALUE =
|
||||||
|
new ConfigurationValue(1L, 1L, 1L, 1L, 0, null);
|
||||||
|
|
||||||
|
private final ConfigurationAttribute COMPOSITE_COLUMN_ATTR_1 =
|
||||||
|
new ConfigurationAttribute(2L, 1L, "attr1", AttributeType.TEXT_FIELD, null, null, null, null);
|
||||||
|
private final ConfigurationAttribute COMPOSITE_COLUMN_ATTR_2 =
|
||||||
|
new ConfigurationAttribute(3L, 1L, "attr2", AttributeType.TEXT_FIELD, null, null, null, null);
|
||||||
|
|
||||||
|
private final ConfigurationValue COMPOSITE_ROW_1_ATTR_1 =
|
||||||
|
new ConfigurationValue(2L, 1L, 1L, 2L, 0, "1");
|
||||||
|
private final ConfigurationValue COMPOSITE_ROW_1_ATTR_2 =
|
||||||
|
new ConfigurationValue(3L, 1L, 1L, 3L, 0, "2");
|
||||||
|
|
||||||
|
private final Collection<ConfigurationAttribute> COMPOSITE_TABLE_ENTRIES = Arrays.asList(
|
||||||
|
this.COMPOSITE_COLUMN_ATTR_1,
|
||||||
|
this.COMPOSITE_COLUMN_ATTR_2);
|
||||||
|
|
||||||
|
private final List<List<ConfigurationValue>> COMPOSITE_TABLE_VALUES = Arrays.asList(
|
||||||
|
Arrays.asList(this.COMPOSITE_ROW_1_ATTR_1, this.COMPOSITE_ROW_1_ATTR_2));
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testXMLNormalTable() throws Exception {
|
||||||
|
|
||||||
|
final ConfigurationAttributeDAO configurationAttributeDAO =
|
||||||
|
Mockito.mock(ConfigurationAttributeDAO.class);
|
||||||
|
Mockito.when(configurationAttributeDAO.allMatching(Mockito.any()))
|
||||||
|
.thenReturn(Result.of(this.TABLE_COLUMNS));
|
||||||
|
|
||||||
|
final ConfigurationValueDAO configurationValueDAO =
|
||||||
|
Mockito.mock(ConfigurationValueDAO.class);
|
||||||
|
Mockito.when(configurationValueDAO.getOrderedTableValues(1L, 1L, 1L))
|
||||||
|
.thenReturn(Result.of(this.TABLE_VALUES));
|
||||||
|
|
||||||
|
final TableConverter tableConverter = new TableConverter(configurationAttributeDAO, configurationValueDAO);
|
||||||
|
tableConverter.init(createAttributeValueConverterService());
|
||||||
|
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
tableConverter.convertToXML(out, this.TABLE_ATTR, attr -> this.TABLE_VALUE);
|
||||||
|
|
||||||
|
final String xmlString = new String(out.toByteArray());
|
||||||
|
assertEquals(
|
||||||
|
"<key>table</key>"
|
||||||
|
+ "<array>"
|
||||||
|
+ "<dict>"
|
||||||
|
+ "<key>attr1</key>"
|
||||||
|
+ "<string>1</string>"
|
||||||
|
+ "<key>attr2</key>"
|
||||||
|
+ "<string>2</string>"
|
||||||
|
+ "</dict>"
|
||||||
|
+ "<dict>"
|
||||||
|
+ "<key>attr1</key>"
|
||||||
|
+ "<string>3</string>"
|
||||||
|
+ "<key>attr2</key>"
|
||||||
|
+ "<string>4</string>"
|
||||||
|
+ "</dict>"
|
||||||
|
+ "</array>",
|
||||||
|
xmlString);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testXMLNormalTableNoValues() throws Exception {
|
||||||
|
|
||||||
|
final ConfigurationAttributeDAO configurationAttributeDAO =
|
||||||
|
Mockito.mock(ConfigurationAttributeDAO.class);
|
||||||
|
Mockito.when(configurationAttributeDAO.allMatching(Mockito.any()))
|
||||||
|
.thenReturn(Result.of(this.TABLE_COLUMNS));
|
||||||
|
|
||||||
|
final ConfigurationValueDAO configurationValueDAO =
|
||||||
|
Mockito.mock(ConfigurationValueDAO.class);
|
||||||
|
Mockito.when(configurationValueDAO.getOrderedTableValues(1L, 1L, 1L))
|
||||||
|
.thenReturn(Result.of(Collections.emptyList()));
|
||||||
|
|
||||||
|
final TableConverter tableConverter = new TableConverter(configurationAttributeDAO, configurationValueDAO);
|
||||||
|
tableConverter.init(createAttributeValueConverterService());
|
||||||
|
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
tableConverter.convertToXML(out, this.TABLE_ATTR, attr -> this.TABLE_VALUE);
|
||||||
|
|
||||||
|
final String xmlString = new String(out.toByteArray());
|
||||||
|
assertEquals(
|
||||||
|
"<key>table</key><array />",
|
||||||
|
xmlString);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testXMLCompositeTable() throws Exception {
|
||||||
|
|
||||||
|
final ConfigurationAttributeDAO configurationAttributeDAO =
|
||||||
|
Mockito.mock(ConfigurationAttributeDAO.class);
|
||||||
|
Mockito.when(configurationAttributeDAO.allMatching(Mockito.any()))
|
||||||
|
.thenReturn(Result.of(this.COMPOSITE_TABLE_ENTRIES));
|
||||||
|
|
||||||
|
final ConfigurationValueDAO configurationValueDAO =
|
||||||
|
Mockito.mock(ConfigurationValueDAO.class);
|
||||||
|
Mockito.when(configurationValueDAO.getOrderedTableValues(1L, 1L, 1L))
|
||||||
|
.thenReturn(Result.of(this.COMPOSITE_TABLE_VALUES));
|
||||||
|
|
||||||
|
final TableConverter tableConverter = new TableConverter(configurationAttributeDAO, configurationValueDAO);
|
||||||
|
tableConverter.init(createAttributeValueConverterService());
|
||||||
|
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
tableConverter.convertToXML(out, this.COMPOSITE_TABLE_ATTR, attr -> this.COMPOSITE_TABLE_VALUE);
|
||||||
|
|
||||||
|
final String xmlString = new String(out.toByteArray());
|
||||||
|
assertEquals(
|
||||||
|
"<key>table</key>"
|
||||||
|
+ "<dict>"
|
||||||
|
+ "<key>attr1</key>"
|
||||||
|
+ "<string>1</string>"
|
||||||
|
+ "<key>attr2</key>"
|
||||||
|
+ "<string>2</string>"
|
||||||
|
+ "</dict>",
|
||||||
|
xmlString);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testXMLCompositeTableEmpty() throws Exception {
|
||||||
|
|
||||||
|
final ConfigurationAttributeDAO configurationAttributeDAO =
|
||||||
|
Mockito.mock(ConfigurationAttributeDAO.class);
|
||||||
|
Mockito.when(configurationAttributeDAO.allMatching(Mockito.any()))
|
||||||
|
.thenReturn(Result.of(this.COMPOSITE_TABLE_ENTRIES));
|
||||||
|
|
||||||
|
final ConfigurationValueDAO configurationValueDAO =
|
||||||
|
Mockito.mock(ConfigurationValueDAO.class);
|
||||||
|
Mockito.when(configurationValueDAO.getOrderedTableValues(1L, 1L, 1L))
|
||||||
|
.thenReturn(Result.of(Collections.emptyList()));
|
||||||
|
|
||||||
|
final TableConverter tableConverter = new TableConverter(configurationAttributeDAO, configurationValueDAO);
|
||||||
|
tableConverter.init(createAttributeValueConverterService());
|
||||||
|
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
tableConverter.convertToXML(out, this.COMPOSITE_TABLE_ATTR, attr -> this.COMPOSITE_TABLE_VALUE);
|
||||||
|
|
||||||
|
final String xmlString = new String(out.toByteArray());
|
||||||
|
assertEquals(
|
||||||
|
"",
|
||||||
|
xmlString);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testJSONNormalTable() throws Exception {
|
||||||
|
|
||||||
|
final ConfigurationAttributeDAO configurationAttributeDAO =
|
||||||
|
Mockito.mock(ConfigurationAttributeDAO.class);
|
||||||
|
Mockito.when(configurationAttributeDAO.allMatching(Mockito.any()))
|
||||||
|
.thenReturn(Result.of(this.TABLE_COLUMNS));
|
||||||
|
|
||||||
|
final ConfigurationValueDAO configurationValueDAO =
|
||||||
|
Mockito.mock(ConfigurationValueDAO.class);
|
||||||
|
Mockito.when(configurationValueDAO.getOrderedTableValues(1L, 1L, 1L))
|
||||||
|
.thenReturn(Result.of(this.TABLE_VALUES));
|
||||||
|
|
||||||
|
final TableConverter tableConverter = new TableConverter(configurationAttributeDAO, configurationValueDAO);
|
||||||
|
tableConverter.init(createAttributeValueConverterService());
|
||||||
|
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
tableConverter.convertToJSON(out, this.TABLE_ATTR, attr -> this.TABLE_VALUE);
|
||||||
|
|
||||||
|
final String xmlString = new String(out.toByteArray());
|
||||||
|
// expected : "table":[{"attr1":"1","attr2":"2"},{"attr1":"3","attr2":"4"}]
|
||||||
|
assertEquals(
|
||||||
|
"\"table\":[{\"attr1\":\"1\",\"attr2\":\"2\"},{\"attr1\":\"3\",\"attr2\":\"4\"}]",
|
||||||
|
xmlString);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testJSONNormalTableEmpty() throws Exception {
|
||||||
|
|
||||||
|
final ConfigurationAttributeDAO configurationAttributeDAO =
|
||||||
|
Mockito.mock(ConfigurationAttributeDAO.class);
|
||||||
|
Mockito.when(configurationAttributeDAO.allMatching(Mockito.any()))
|
||||||
|
.thenReturn(Result.of(this.TABLE_COLUMNS));
|
||||||
|
|
||||||
|
final ConfigurationValueDAO configurationValueDAO =
|
||||||
|
Mockito.mock(ConfigurationValueDAO.class);
|
||||||
|
Mockito.when(configurationValueDAO.getOrderedTableValues(1L, 1L, 1L))
|
||||||
|
.thenReturn(Result.of(Collections.emptyList()));
|
||||||
|
|
||||||
|
final TableConverter tableConverter = new TableConverter(configurationAttributeDAO, configurationValueDAO);
|
||||||
|
tableConverter.init(createAttributeValueConverterService());
|
||||||
|
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
tableConverter.convertToJSON(out, this.TABLE_ATTR, attr -> this.TABLE_VALUE);
|
||||||
|
|
||||||
|
final String xmlString = new String(out.toByteArray());
|
||||||
|
// expected : "table":[]
|
||||||
|
assertEquals(
|
||||||
|
"\"table\":[]",
|
||||||
|
xmlString);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testJSONCompositeTable() throws Exception {
|
||||||
|
|
||||||
|
final ConfigurationAttributeDAO configurationAttributeDAO =
|
||||||
|
Mockito.mock(ConfigurationAttributeDAO.class);
|
||||||
|
Mockito.when(configurationAttributeDAO.allMatching(Mockito.any()))
|
||||||
|
.thenReturn(Result.of(this.COMPOSITE_TABLE_ENTRIES));
|
||||||
|
|
||||||
|
final ConfigurationValueDAO configurationValueDAO =
|
||||||
|
Mockito.mock(ConfigurationValueDAO.class);
|
||||||
|
Mockito.when(configurationValueDAO.getOrderedTableValues(1L, 1L, 1L))
|
||||||
|
.thenReturn(Result.of(this.COMPOSITE_TABLE_VALUES));
|
||||||
|
|
||||||
|
final TableConverter tableConverter = new TableConverter(configurationAttributeDAO, configurationValueDAO);
|
||||||
|
tableConverter.init(createAttributeValueConverterService());
|
||||||
|
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
tableConverter.convertToJSON(out, this.COMPOSITE_TABLE_ATTR, attr -> this.COMPOSITE_TABLE_VALUE);
|
||||||
|
|
||||||
|
final String xmlString = new String(out.toByteArray());
|
||||||
|
// expected : "table":{"attr1":"1","attr2":"2"}
|
||||||
|
assertEquals(
|
||||||
|
"\"table\":{\"attr1\":\"1\",\"attr2\":\"2\"}",
|
||||||
|
xmlString);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testJSONCompositeTableEmpty() throws Exception {
|
||||||
|
|
||||||
|
final ConfigurationAttributeDAO configurationAttributeDAO =
|
||||||
|
Mockito.mock(ConfigurationAttributeDAO.class);
|
||||||
|
Mockito.when(configurationAttributeDAO.allMatching(Mockito.any()))
|
||||||
|
.thenReturn(Result.of(this.COMPOSITE_TABLE_ENTRIES));
|
||||||
|
|
||||||
|
final ConfigurationValueDAO configurationValueDAO =
|
||||||
|
Mockito.mock(ConfigurationValueDAO.class);
|
||||||
|
Mockito.when(configurationValueDAO.getOrderedTableValues(1L, 1L, 1L))
|
||||||
|
.thenReturn(Result.of(Collections.emptyList()));
|
||||||
|
|
||||||
|
final TableConverter tableConverter = new TableConverter(configurationAttributeDAO, configurationValueDAO);
|
||||||
|
tableConverter.init(createAttributeValueConverterService());
|
||||||
|
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
tableConverter.convertToJSON(out, this.COMPOSITE_TABLE_ATTR, attr -> this.COMPOSITE_TABLE_VALUE);
|
||||||
|
|
||||||
|
final String xmlString = new String(out.toByteArray());
|
||||||
|
// expected :
|
||||||
|
assertEquals(
|
||||||
|
"",
|
||||||
|
xmlString);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private AttributeValueConverterService createAttributeValueConverterService() {
|
||||||
|
final List<AttributeValueConverter> converter = new ArrayList<>();
|
||||||
|
converter.add(new StringConverter());
|
||||||
|
return new AttributeValueConverterServiceImpl(converter);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue