Commit 46fee41d authored by Piotr Gawron's avatar Piotr Gawron
Browse files

Merge branch '493-use-spring-jackson-object-mapping-in-rest-api' into 'master'

Resolve "Use Spring/Jackson object mapping in REST API"

See merge request !1344
parents a06afd80 ea9430ed
Pipeline #47126 passed with stage
in 38 minutes and 17 seconds
......@@ -9,6 +9,10 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lcsb.mapviewer.annotation.data.serializer.MeSHSerializer;
/**
* This class represents <a href="http://www.nlm.nih.gov/cgi/mesh//">MeSH</a>
* object.
......@@ -17,6 +21,7 @@ import org.apache.logging.log4j.Logger;
*
*/
@XmlRootElement
@JsonSerialize(using = MeSHSerializer.class)
public class MeSH implements Serializable {
/**
......
package lcsb.mapviewer.annotation.data.serializer;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import lcsb.mapviewer.annotation.data.MeSH;
public class MeSHSerializer extends JsonSerializer<MeSH> {
@Override
public void serialize(final MeSH mesh, final JsonGenerator gen, final SerializerProvider serializers)
throws IOException {
gen.writeStartObject();
gen.writeStringField("name", mesh.getName());
gen.writeStringField("id", mesh.getMeSHId());
gen.writeStringField("description", mesh.getDescription());
gen.writeObjectField("synonyms", mesh.getSynonyms());
gen.writeEndObject();
}
}
\ No newline at end of file
......@@ -2,6 +2,7 @@ package lcsb.mapviewer.annotation.services.dapi;
import java.util.List;
import lcsb.mapviewer.annotation.services.dapi.dto.DapiDatabase;
import lcsb.mapviewer.annotation.services.dapi.dto.ReleaseDto;
import lcsb.mapviewer.annotation.services.dapi.dto.UserDto;
......@@ -20,7 +21,7 @@ public interface DapiConnector {
void resetConnection();
List<String> getDatabases() throws DapiConnectionException;
List<DapiDatabase> getDatabases() throws DapiConnectionException;
List<ReleaseDto> getReleases(String database) throws DapiConnectionException;
......
......@@ -32,6 +32,7 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonParser;
import lcsb.mapviewer.annotation.cache.CachableInterface;
import lcsb.mapviewer.annotation.services.dapi.dto.DapiDatabase;
import lcsb.mapviewer.annotation.services.dapi.dto.ListReleaseDto;
import lcsb.mapviewer.annotation.services.dapi.dto.ReleaseDto;
import lcsb.mapviewer.annotation.services.dapi.dto.UserDto;
......@@ -237,9 +238,9 @@ public class DapiConnectorImpl extends CachableInterface implements DapiConnecto
}
@Override
public List<String> getDatabases() throws DapiConnectionException {
public List<DapiDatabase> getDatabases() throws DapiConnectionException {
try {
List<String> result = new ArrayList<>();
List<DapiDatabase> result = new ArrayList<>();
String url = DAPI_BASE_URL + "database/";
String content = getWebPageDownloader().getFromNetwork(url);
JsonArray array = new JsonParser()
......@@ -249,7 +250,7 @@ public class DapiConnectorImpl extends CachableInterface implements DapiConnecto
.getAsJsonArray();
for (int i = 0; i < array.size(); i++) {
result.add(array.get(i).getAsJsonObject().get("name").getAsString());
result.add(new DapiDatabase(array.get(i).getAsJsonObject().get("name").getAsString()));
}
return result;
} catch (Exception e) {
......
package lcsb.mapviewer.annotation.services.dapi.dto;
public class DapiDatabase {
public String name;
public DapiDatabase(String name) {
this.name = name;
}
}
package lcsb.mapviewer.modelutils.serializer;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import lcsb.mapviewer.modelutils.map.ClassTreeNode;
public class ClassTreeNodeSerializer extends JsonSerializer<ClassTreeNode> {
@Override
public void serialize(final ClassTreeNode node, final JsonGenerator gen,
final SerializerProvider serializers)
throws IOException {
gen.writeStartObject();
gen.writeStringField("className", node.getClazz().getName());
gen.writeStringField("name", node.getCommonName());
if (node.getParent() == null) {
gen.writeStringField("parentClass", null);
} else {
gen.writeStringField("parentClass", node.getParent().getClazz().getName());
}
gen.writeEndObject();
}
}
\ No newline at end of file
package lcsb.mapviewer.modelutils.serializer.model.map.layout;
import java.io.IOException;
import java.util.function.Function;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import lcsb.mapviewer.model.map.layout.ReferenceGenomeGeneMapping;
public class ReferenceGenomeGeneMappingSerializer extends JsonSerializer<ReferenceGenomeGeneMapping> {
private Function<String, String> getLocalUrl;
public ReferenceGenomeGeneMappingSerializer(Function<String, String> getLocalUrl) {
this.getLocalUrl = getLocalUrl;
}
@Override
public void serialize(final ReferenceGenomeGeneMapping mapping, final JsonGenerator gen,
final SerializerProvider serializers)
throws IOException {
gen.writeStartObject();
gen.writeNumberField("downloadProgress", mapping.getDownloadProgress());
gen.writeStringField("localUrl", getLocalUrl.apply(mapping.getSourceUrl()));
gen.writeStringField("sourceUrl", mapping.getSourceUrl());
gen.writeStringField("name", mapping.getName());
gen.writeNumberField("idObject", mapping.getId());
gen.writeEndObject();
}
}
\ No newline at end of file
package lcsb.mapviewer.modelutils.serializer.model.map.layout;
import java.io.IOException;
import java.util.function.Function;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import lcsb.mapviewer.model.map.layout.ReferenceGenome;
public class ReferenceGenomeSerializer extends JsonSerializer<ReferenceGenome> {
private Function<String, String> getLocalUrl;
public ReferenceGenomeSerializer(Function<String, String> getLocalUrl) {
this.getLocalUrl = getLocalUrl;
}
@Override
public void serialize(final ReferenceGenome genome, final JsonGenerator gen,
final SerializerProvider serializers)
throws IOException {
gen.writeStartObject();
gen.writeObjectField("organism", genome.getOrganism());
gen.writeStringField("version", genome.getVersion());
gen.writeObjectField("type", genome.getType());
gen.writeNumberField("downloadProgress", genome.getDownloadProgress());
gen.writeStringField("sourceUrl", genome.getSourceUrl());
gen.writeStringField("localUrl", getLocalUrl.apply(genome.getSourceUrl()));
gen.writeNumberField("idObject", genome.getId());
gen.writeObjectField("geneMapping", genome.getGeneMapping());
gen.writeEndObject();
}
}
\ No newline at end of file
......@@ -95,4 +95,12 @@ public abstract class BaseController {
.header("Content-Disposition", "attachment; filename=" + originalFile.getOriginalFileName() + ".zip")
.body(baos.toByteArray());
}
protected Map<String, Object> okStatus() {
Map<String, Object> result = new HashMap<>();
result.put("status", "OK");
return result;
}
}
package lcsb.mapviewer.api.configuration;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import lcsb.mapviewer.common.Pair;
import lcsb.mapviewer.converter.graphics.AbstractImageGenerator;
import lcsb.mapviewer.converter.graphics.ImageGenerators;
public class AbstractImageGeneratorSerializer extends JsonSerializer<Class<? extends AbstractImageGenerator>> {
private static final ImageGenerators imageGenerators = new ImageGenerators();
@Override
public void serialize(final Class<? extends AbstractImageGenerator> clazz, final JsonGenerator gen,
final SerializerProvider serializers)
throws IOException {
gen.writeStartObject();
for (Pair<String, Class<? extends AbstractImageGenerator>> pair: imageGenerators.getAvailableImageGenerators()) {
if (pair.getRight()==clazz) {
gen.writeStringField("name", pair.getLeft());
gen.writeStringField("handler", clazz.getCanonicalName());
gen.writeStringField("extension", imageGenerators.getExtension(clazz.getCanonicalName()));
}
}
gen.writeEndObject();
}
}
\ No newline at end of file
package lcsb.mapviewer.api.configuration;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import lcsb.mapviewer.model.user.annotator.BioEntityField;
public class BioEntityFieldSerializer extends JsonSerializer<BioEntityField> {
@Override
public void serialize(final BioEntityField type, final JsonGenerator gen,
final SerializerProvider serializers)
throws IOException {
gen.writeStartObject();
gen.writeStringField("commonName", type.getCommonName());
gen.writeStringField("name", type.name());
gen.writeEndObject();
}
}
\ No newline at end of file
package lcsb.mapviewer.api.configuration;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.TreeMap;
import java.util.stream.Collectors;
import javax.servlet.ServletContext;
......@@ -13,12 +19,18 @@ import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import lcsb.mapviewer.annotation.services.ModelAnnotator;
import lcsb.mapviewer.annotation.services.annotators.ElementAnnotator;
import lcsb.mapviewer.annotation.services.dapi.DapiConnectionException;
import lcsb.mapviewer.annotation.services.dapi.DapiConnector;
import lcsb.mapviewer.annotation.services.dapi.dto.DapiDatabase;
import lcsb.mapviewer.annotation.services.dapi.dto.ReleaseDto;
import lcsb.mapviewer.annotation.services.dapi.dto.UserDto;
import lcsb.mapviewer.api.BaseController;
......@@ -71,25 +83,25 @@ public class ConfigurationController extends BaseController {
}
@GetMapping(value = "/")
public Map<String, Object> getConfiguration(Authentication authentication) {
Map<String, Object> result = new TreeMap<>();
result.put("options", getOptions(authentication));
result.put("imageFormats", getImageFormats());
result.put("modelFormats", getModelFormats());
result.put("overlayTypes", getOverlayTypes());
result.put("elementTypes", getElementTypes());
result.put("reactionTypes", getReactionTypes());
result.put("miriamTypes", getMiriamTypes());
result.put("mapTypes", getMapTypes());
result.put("mapCanvasTypes", getMapCanvasTypes());
result.put("unitTypes", getUnitTypes());
result.put("modificationStateTypes", getModificationStateTypes());
result.put("privilegeTypes", getPrivilegeTypes());
result.put("version", configurationService.getSystemSvnVersion(context.getRealPath("/") + "META-INF/"));
result.put("buildDate", configurationService.getSystemBuild(context.getRealPath("/") + "META-INF/"));
result.put("gitHash", configurationService.getSystemGitVersion(context.getRealPath("/") + "META-INF/"));
result.put("annotators", getAnnotators());
result.put("bioEntityFields", getBioEntityFields());
public ConfigurationDto getConfiguration(Authentication authentication) {
ConfigurationDto result = new ConfigurationDto();
result.options = getOptions(authentication);
result.imageFormats = getImageFormats();
result.modelFormats = modelConverters;
result.overlayTypes = DataOverlayType.values();
result.elementTypes = getElementTypes();
result.reactionTypes = getReactionTypes();
result.miriamTypes = getMiriamTypes();
result.mapTypes = SubmodelType.values();
result.mapCanvasTypes = MapCanvasType.values();
result.unitTypes = SbmlUnitType.values();
result.modificationStateTypes = getModificationStateTypes();
result.privilegeTypes = getPrivilegeTypes();
result.version = configurationService.getSystemSvnVersion(context.getRealPath("/") + "META-INF/");
result.buildDate = configurationService.getSystemBuild(context.getRealPath("/") + "META-INF/");
result.gitHash = configurationService.getSystemGitVersion(context.getRealPath("/") + "META-INF/");
result.annotators = modelAnnotator.getAvailableAnnotators();
result.bioEntityFields = BioEntityField.values();
return result;
}
......@@ -102,11 +114,17 @@ public class ConfigurationController extends BaseController {
.collect(Collectors.toList());
}
static class DapiStatus {
public boolean validConnection;
public DapiStatus(boolean validConnection) {
this.validConnection = validConnection;
}
}
@GetMapping(value = "/dapi/")
public Map<String, Object> getDapi() {
Map<String, Object> result = new HashMap<>();
result.put("validConnection", dapiConnector.isValidConnection());
return result;
public DapiStatus getDapi() {
return new DapiStatus(dapiConnector.isValidConnection());
}
@PreAuthorize("hasAuthority('IS_ADMIN')")
......@@ -126,18 +144,13 @@ public class ConfigurationController extends BaseController {
}
@GetMapping(value = "/dapi/database/")
public List<Map<String, Object>> getDapiDatabases() {
List<Map<String, Object>> result = new ArrayList<>();
public List<DapiDatabase> getDapiDatabases() {
try {
for (String string : dapiConnector.getDatabases()) {
Map<String, Object> entry = new HashMap<>();
entry.put("name", string);
result.add(entry);
}
return dapiConnector.getDatabases();
} catch (DapiConnectionException e) {
logger.error("Problem with dapi", e);
}
return result;
return new ArrayList<>();
}
@GetMapping(value = "/dapi/database/{database}/release/")
......@@ -185,51 +198,22 @@ public class ConfigurationController extends BaseController {
return configurationService.getValue(type);
}
public List<Map<String, Object>> getImageFormats() {
List<Map<String, Object>> result = new ArrayList<>();
public List<Class<? extends AbstractImageGenerator>> getImageFormats() {
List<Class<? extends AbstractImageGenerator>> result = new ArrayList<>();
ImageGenerators imageGenerators = new ImageGenerators();
List<Pair<String, Class<? extends AbstractImageGenerator>>> imageGeneratorList = imageGenerators
.getAvailableImageGenerators();
for (Pair<String, Class<? extends AbstractImageGenerator>> element : imageGeneratorList) {
Map<String, Object> row = new TreeMap<>();
row.put("name", element.getLeft());
row.put("handler", element.getRight().getCanonicalName());
row.put("extension", imageGenerators.getExtension(element.getRight()));
result.add(row);
for (Pair<String, Class<? extends AbstractImageGenerator>> element : imageGenerators.getAvailableImageGenerators()) {
result.add(element.getRight());
}
return result;
}
public List<Map<String, Object>> getModelFormats() {
List<Map<String, Object>> result = new ArrayList<>();
for (Converter converter : modelConverters) {
Map<String, Object> row = new TreeMap<>();
row.put("name", converter.getCommonName());
row.put("handler", converter.getClass().getCanonicalName());
row.put("extension", converter.getFileExtension());
result.add(row);
}
return result;
}
public List<Map<String, Object>> getOverlayTypes() {
List<Map<String, Object>> result = new ArrayList<>();
for (DataOverlayType type : DataOverlayType.values()) {
Map<String, Object> map = new TreeMap<>();
map.put("name", type.name());
result.add(map);
}
return result;
}
public Set<Map<String, String>> getElementTypes() {
private List<ClassTreeNode> getElementTypes() {
return getClassStringTypesList(Element.class);
}
private Set<Map<String, String>> getClassStringTypesList(Class<?> elementClass) {
Set<Map<String, String>> result = new LinkedHashSet<>();
private List<ClassTreeNode> getClassStringTypesList(Class<?> elementClass) {
List<ClassTreeNode> result = new ArrayList<>();
ElementUtils elementUtils = new ElementUtils();
ClassTreeNode top = elementUtils.getAnnotatedElementClassTree();
Queue<ClassTreeNode> queue = new LinkedList<>();
......@@ -238,137 +222,37 @@ public class ConfigurationController extends BaseController {
ClassTreeNode clazz = queue.poll();
queue.addAll(clazz.getChildren());
if (elementClass.isAssignableFrom(clazz.getClazz())) {
Map<String, String> row = new TreeMap<>();
row.put("className", clazz.getClazz().getName());
row.put("name", clazz.getCommonName());
if (clazz.getParent() == null) {
row.put("parentClass", null);
} else {
row.put("parentClass", clazz.getParent().getClazz().getName());
}
result.add(row);
result.add(clazz);
}
}
return result;
}
public Set<Map<String, String>> getReactionTypes() {
private List<ClassTreeNode> getReactionTypes() {
return getClassStringTypesList(Reaction.class);
}
public Map<String, Object> getMiriamTypes() {
Map<String, Object> result = new TreeMap<>();
private Map<String, MiriamType> getMiriamTypes() {
Map<String, MiriamType> result = new TreeMap<>();
for (MiriamType type : MiriamType.values()) {
result.put(type.name(), createMiriamTypeResponse(type));
result.put(type.name(), type);
}
return result;
}
private Map<String, Object> createMiriamTypeResponse(MiriamType type) {
Map<String, Object> result = new TreeMap<>();
result.put("commonName", type.getCommonName());
result.put("homepage", type.getDbHomepage());
result.put("registryIdentifier", type.getRegistryIdentifier());
result.put("uris", type.getUris());
return result;
}
public Object getModificationStateTypes() {
Map<String, Object> result = new TreeMap<>();
private Map<String, ModificationState> getModificationStateTypes() {
Map<String, ModificationState> result = new TreeMap<>();
for (ModificationState type : ModificationState.values()) {
result.put(type.name(), createModificationStateResponse(type));
result.put(type.name(), type);
}
return result;
}
private Map<String, Object> createModificationStateResponse(ModificationState type) {
Map<String, Object> result = new TreeMap<>();
result.put("commonName", type.getFullName());
result.put("abbreviation", type.getAbbreviation());
return result;
}
public List<Map<String, Object>> getMapTypes() {
List<Map<String, Object>> result = new ArrayList<>();
for (SubmodelType type : SubmodelType.values()) {
Map<String, Object> row = new TreeMap<>();
row.put("id", type.name());
row.put("name", type.getCommonName());
result.add(row);
}
return result;
}
public List<Map<String, Object>> getMapCanvasTypes() {
List<Map<String, Object>> result = new ArrayList<>();
for (MapCanvasType type : MapCanvasType.values()) {
Map<String, Object> row = new TreeMap<>();
row.put("id", type.name());
row.put("name", type.getCommonName());
result.add(row);
}
return result;
}
public List<Map<String, Object>> getUnitTypes() {
List<Map<String, Object>> result = new ArrayList<>();
for (SbmlUnitType type : SbmlUnitType.values()) {