Commit 6d0b2e08 authored by Piotr Gawron's avatar Piotr Gawron
Browse files

ConverterConvtroller separated from service

parent 990b18fb
......@@ -4,8 +4,9 @@ import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager;
......@@ -18,6 +19,7 @@ import org.springframework.web.bind.annotation.*;
import lcsb.mapviewer.api.BaseController;
import lcsb.mapviewer.commands.CreateHierarchyCommand;
import lcsb.mapviewer.commands.MergeCommand;
import lcsb.mapviewer.common.MinervaLoggerAppender;
import lcsb.mapviewer.common.Pair;
import lcsb.mapviewer.common.exception.InvalidStateException;
......@@ -36,12 +38,10 @@ public class ConvertController extends BaseController {
private Logger logger = LogManager.getLogger();
private ConvertRestImpl convertController;
private List<Converter> modelConverters;
@Autowired
public ConvertController(ConvertRestImpl convertController, List<Converter> modelConverters) {
this.convertController = convertController;
public ConvertController(List<Converter> modelConverters) {
this.modelConverters = modelConverters;
}
......@@ -163,21 +163,101 @@ public class ConvertController extends BaseController {
@PathVariable(value = "toFormat") String toFormat,
@RequestBody byte[] body)
throws Exception {
byte[] bytea = convertController.mergeFiles(fromFormat, toFormat, body);
try {
ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(body));
ZipEntry zipEntry = zis.getNextEntry();
List<Pair<String, Model>> modelsWithFilename = new ArrayList<>();
while (zipEntry != null) {
String filename = zipEntry.getName();
if (!zipEntry.isDirectory() && filename.toLowerCase().startsWith("maps/")) {
Model model = getModelParserByNameOrClass(fromFormat)
.createModel(new ConverterParams().inputStream(convertZipInputStreamToInputStream(zis, zipEntry, "UTF-8"),
filename));
modelsWithFilename.add(new Pair<>(filename, model));
}
zipEntry = zis.getNextEntry();
}
zis.closeEntry();
zis.close();
modelsWithFilename.sort(new Comparator<Pair<String, Model>>() {
@Override
public int compare(Pair<String, Model> o1, Pair<String, Model> o2) {
return o1.getLeft().compareTo(o2.getLeft());
}
});
List<Model> models = new ArrayList<>();
for (Pair<String, Model> pair : modelsWithFilename) {
models.add(pair.getRight());
}
Model result = new MergeCommand(models).execute();
Converter exporter = getModelParserByNameOrClass(toFormat);
byte[] bytea = IOUtils.toByteArray(exporter.model2InputStream(result));
return ResponseEntity.ok().contentLength(bytea.length)
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.header("Content-Disposition", "attachment; filename=model" + toFormat)
.body(bytea);
} catch (InvalidInputDataExecption | ConverterException | InconsistentModelException e) {
throw new QueryException("Input file is invalid", e);
}
}
private InputStream convertZipInputStreamToInputStream(ZipInputStream in, ZipEntry entry, String encoding)
throws IOException {
final int BUFFER = 2048;
int count = 0;
byte data[] = new byte[BUFFER];
ByteArrayOutputStream out = new ByteArrayOutputStream();
while ((count = in.read(data)) != -1) {
out.write(data, 0, count);
}
return new ByteArrayInputStream(out.toByteArray());
}
@RequestMapping(value = "/", method = { RequestMethod.GET, RequestMethod.POST })
public Map<String, ?> getInformation() {
return convertController.getInformation();
public Map<String, List<Map<String, List<String>>>> getInformation() {
Map<String, List<Map<String, List<String>>>> info = new LinkedHashMap<>();
List<Map<String, List<String>>> converters = new ArrayList<>();
for (Converter converter : modelConverters) {
List<String> names = new ArrayList<>();
names.add(removeWhiteSpaces(converter.getCommonName()));
names.add(converter.getClass().getCanonicalName());
Map<String, List<String>> names_item = new LinkedHashMap<>();
names_item.put("available_names", names);
converters.add(names_item);
}
info.put("inputs", converters);
info.put("outputs", converters);
return info;
}
@RequestMapping(value = "/image/", method = { RequestMethod.GET, RequestMethod.POST })
public Map<String, ?> getInformationImage() {
return convertController.getInformationImage();
Map<String, List<Map<String, List<String>>>> info = getInformation();
List<Map<String, List<String>>> generators = new ArrayList<>();
ImageGenerators igs = new ImageGenerators();
for (Pair<String, Class<? extends AbstractImageGenerator>> generator : igs.getAvailableImageGenerators()) {
List<String> names = new ArrayList<>();
names.add(igs.getExtension(generator.getRight()));
names.add(generator.getRight().getCanonicalName());
Map<String, List<String>> names_item = new LinkedHashMap<>();
names_item.put("available_names", names);
generators.add(names_item);
}
info.remove("outputs");
info.put("outputs", generators);
return info;
}
private ConverterParams createConvertParams(byte[] input) {
......
package lcsb.mapviewer.api.convert;
import java.io.*;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.commons.io.IOUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import lcsb.mapviewer.api.BaseRestImpl;
import lcsb.mapviewer.commands.CommandExecutionException;
import lcsb.mapviewer.commands.MergeCommand;
import lcsb.mapviewer.common.Pair;
import lcsb.mapviewer.common.exception.InvalidStateException;
import lcsb.mapviewer.converter.*;
import lcsb.mapviewer.converter.graphics.AbstractImageGenerator;
import lcsb.mapviewer.converter.graphics.ImageGenerators;
import lcsb.mapviewer.model.map.InconsistentModelException;
import lcsb.mapviewer.model.map.model.Model;
import lcsb.mapviewer.services.QueryException;
@Transactional
@Service
public class ConvertRestImpl extends BaseRestImpl {
public byte[] mergeFiles(String fromFormat, String toFormat, byte[] input)
throws IOException, QueryException, CommandExecutionException {
try {
ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(input));
ZipEntry zipEntry = zis.getNextEntry();
List<Pair<String, Model>> modelsWithFilename = new ArrayList<>();
while (zipEntry != null) {
String filename = zipEntry.getName();
if (!zipEntry.isDirectory() && filename.toLowerCase().startsWith("maps/")) {
Model model = getModelParserByNameOrClass(fromFormat)
.createModel(new ConverterParams().inputStream(convertZipInputStreamToInputStream(zis, zipEntry, "UTF-8"),
filename));
modelsWithFilename.add(new Pair<>(filename, model));
}
zipEntry = zis.getNextEntry();
}
zis.closeEntry();
zis.close();
modelsWithFilename.sort(new Comparator<Pair<String, Model>>() {
@Override
public int compare(Pair<String, Model> o1, Pair<String, Model> o2) {
return o1.getLeft().compareTo(o2.getLeft());
}
});
List<Model> models = new ArrayList<>();
for (Pair<String, Model> pair : modelsWithFilename) {
models.add(pair.getRight());
}
Model result = new MergeCommand(models).execute();
Converter exporter = getModelParserByNameOrClass(toFormat);
return IOUtils.toByteArray(exporter.model2InputStream(result));
} catch (InvalidInputDataExecption | ConverterException | InconsistentModelException e) {
throw new QueryException("Input file is invalid", e);
}
}
private InputStream convertZipInputStreamToInputStream(ZipInputStream in, ZipEntry entry, String encoding)
throws IOException {
final int BUFFER = 2048;
int count = 0;
byte data[] = new byte[BUFFER];
ByteArrayOutputStream out = new ByteArrayOutputStream();
while ((count = in.read(data)) != -1) {
out.write(data, 0, count);
}
return new ByteArrayInputStream(out.toByteArray());
}
public Map<String, List<Map<String, List<String>>>> getInformation() {
Map<String, List<Map<String, List<String>>>> info = new LinkedHashMap<>();
List<Map<String, List<String>>> converters = new ArrayList<>();
for (Converter converter : getModelConverters()) {
List<String> names = new ArrayList<>();
names.add(removeWhiteSpaces(converter.getCommonName()));
names.add(converter.getClass().getCanonicalName());
Map<String, List<String>> names_item = new LinkedHashMap<>();
names_item.put("available_names", names);
converters.add(names_item);
}
info.put("inputs", converters);
info.put("outputs", converters);
return info;
}
public Map<String, List<Map<String, List<String>>>> getInformationImage() {
Map<String, List<Map<String, List<String>>>> info = getInformation();
List<Map<String, List<String>>> generators = new ArrayList<>();
ImageGenerators igs = new ImageGenerators();
for (Pair<String, Class<? extends AbstractImageGenerator>> generator : igs.getAvailableImageGenerators()) {
List<String> names = new ArrayList<>();
names.add(igs.getExtension(generator.getRight()));
names.add(generator.getRight().getCanonicalName());
Map<String, List<String>> names_item = new LinkedHashMap<>();
names_item.put("available_names", names);
generators.add(names_item);
}
info.remove("outputs");
info.put("outputs", generators);
return info;
}
private Converter getModelParserByNameOrClass(String id) throws QueryException {
try {
return getModelParserByName(id);
} catch (QueryException e) {
return getModelParser(id);
}
}
private String removeWhiteSpaces(String str) {
return str.replace(' ', '_');
}
private Converter getModelParserByName(String name) throws QueryException {
for (Converter converter : getModelConverters()) {
if (removeWhiteSpaces(converter.getCommonName()).equals(name)) {
try {
return converter.getClass().newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new InvalidStateException(e);
}
}
}
throw new QueryException("Unknown parser name: " + name);
}
}
......@@ -4,7 +4,6 @@ import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
import lcsb.mapviewer.api.convert.AllConvertTests;
import lcsb.mapviewer.api.files.AllFileTests;
import lcsb.mapviewer.api.genomics.AllGenomicsTests;
import lcsb.mapviewer.api.mesh.AllMeshTests;
......@@ -13,7 +12,6 @@ import lcsb.mapviewer.api.users.AllUserTests;
@RunWith(Suite.class)
@SuiteClasses({
AllConvertTests.class,
AllFileTests.class,
AllGenomicsTests.class,
AllMeshTests.class,
......
package lcsb.mapviewer.api.convert;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses({ ConvertRestImplTest.class })
public class AllConvertTests {
}
package lcsb.mapviewer.api.convert;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.List;
import java.util.Map;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.*;
import org.springframework.beans.factory.annotation.Autowired;
import lcsb.mapviewer.api.RestTestFunctions;
public class ConvertRestImplTest extends RestTestFunctions {
@Autowired
public ConvertRestImpl convertRestImpl;
@SuppressWarnings("unused")
private Logger logger = LogManager.getLogger();
@AfterClass
public static void tearDownAfterClass() throws Exception {
}
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@SuppressWarnings("unchecked")
@Test
public void testGetInformation() throws Exception {
Map<String, ?> result = convertRestImpl.getInformationImage();
assertTrue(result.keySet().size() == 2);
assertNotNull(result.get("inputs"));
assertNotNull(result.get("outputs"));
List<Object> inputs = (List<Object>) result.get("inputs");
List<Object> outputs = (List<Object>) result.get("outputs");
assertTrue(inputs.size() > 0);
assertTrue(outputs.size() > 0);
}
@SuppressWarnings("unchecked")
@Test
public void testGetInformationImage() throws Exception {
Map<String, ?> result = convertRestImpl.getInformationImage();
assertTrue(result.keySet().size() == 2);
assertNotNull(result.get("inputs"));
assertNotNull(result.get("outputs"));
List<Object> inputs = (List<Object>) result.get("inputs");
List<Object> outputs = (List<Object>) result.get("outputs");
assertTrue(inputs.size() > 0);
assertTrue(outputs.size() > 0);
}
}
......@@ -72,9 +72,8 @@ public class UserRestImplTest extends RestTestFunctions {
private Map<String, Object> deserialize(Map<String, Object> data)
throws JsonParseException, JsonMappingException, IOException {
String body = new Gson().toJson(data);
ObjectMapper mapper = new ObjectMapper();
ObjectNode result = mapper.readValue(body, ObjectNode.class);
ObjectNode result = mapper.readValue(mapper.writeValueAsString(data), ObjectNode.class);
return mapper.convertValue(result, Map.class);
}
......
This diff is collapsed.
This diff is collapsed.
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<sbgn xmlns="http://sbgn.org/libsbgn/0.2">
<map language="process description">
<glyph id="nwtN_f034af08-f2b3-4912-aaa8-58b4f55f43b9" class="macromolecule">
<label text="dffgdf"/>
<bbox x="707" y="292" w="60" h="30"/>
</glyph>
</map>
</sbgn>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -17,7 +17,6 @@ import java.nio.file.Files;
import java.util.*;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.Test;
......@@ -27,10 +26,11 @@ import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.RequestBuilder;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lcsb.mapviewer.api.convert.ConvertRestImpl;
import lcsb.mapviewer.converter.ConverterParams;
import lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser;
import lcsb.mapviewer.model.map.model.Model;
......@@ -39,9 +39,6 @@ import lcsb.mapviewer.model.map.species.Element;
@RunWith(SpringJUnit4ClassRunner.class)
public class ConvertControllerIntegrationTest extends ControllerIntegrationTest {
@Autowired
private ConvertRestImpl converterRestImpl;
@Autowired
private ObjectMapper objectMapper;
......@@ -98,9 +95,9 @@ public class ConvertControllerIntegrationTest extends ControllerIntegrationTest
.andDo(document("converter/merge_maps",
pathParameters(
parameterWithName("inputFormat")
.description("input format, available options: " + getConverters()),
.description("input format, available options: " + getModelInputConverters()),
parameterWithName("outputFormat")
.description("output format, available options: " + getConverters()))))
.description("output format, available options: " + getModelOutputConverters()))))
.andExpect(status().is2xxSuccessful())
.andReturn().getResponse().getContentAsByteArray();
......@@ -162,9 +159,9 @@ public class ConvertControllerIntegrationTest extends ControllerIntegrationTest
.andDo(document("converter/format_conversion",
pathParameters(
parameterWithName("inputFormat")
.description("input format, available options: " + getConverters()),
.description("input format, available options: " + getModelInputConverters()),
parameterWithName("outputFormat")
.description("output format, available options: " + getConverters()))))
.description("output format, available options: " + getModelOutputConverters()))))
.andExpect(status().is2xxSuccessful());
}
......@@ -203,28 +200,12 @@ public class ConvertControllerIntegrationTest extends ControllerIntegrationTest
.andDo(document("converter/image_conversion",
pathParameters(
parameterWithName("inputFormat")
.description("input format, available options: " + getConverters()),
.description("input format, available options: " + getModelInputConverters()),
parameterWithName("outputFormat")
.description("output format, available options: " + getImageConverters()))))
.description("output format, available options: " + getImageOutputConverters()))))
.andExpect(status().is2xxSuccessful());
}
private String getConverters() {
List<String> converters = new ArrayList<>();
for (Map<String, List<String>> entry : converterRestImpl.getInformation().get("inputs")) {
converters.addAll(entry.get("available_names"));
}
return StringUtils.join(converters, ", ");
}
private String getImageConverters() {
List<String> converters = new ArrayList<>();
for (Map<String, List<String>> entry : converterRestImpl.getInformation().get("outputs")) {
converters.addAll(entry.get("available_names"));
}
return StringUtils.join(converters, ", ");
}
@Test
public void testCelDesigner2Sbml1() throws Exception {
String content = readFile("src/test/resources/convert/sample-cd.xml");
......@@ -322,8 +303,31 @@ public class ConvertControllerIntegrationTest extends ControllerIntegrationTest
}
private List<String> getModelOutputConverters() throws Exception {
Map<String, List<Map<String, List<String>>>> data = getModelConverters();
List<String> result = new ArrayList<>();
for (Map<String, List<String>> entry : data.get("outputs")) {
result.add(entry.get("available_names").get(0));
}
return result;
}
private List<String> getModelInputConverters() throws Exception {
Map<String, List<Map<String, List<String>>>> data = getModelConverters();
List<String> result = new ArrayList<>();
for (Map<String, List<String>> entry : data.get("inputs")) {
result.add(entry.get("available_names").get(0));
}
return result;
}
private Map<String, List<Map<String, List<String>>>> getModelConverters()
throws UnsupportedEncodingException, Exception, IOException, JsonParseException, JsonMappingException {
RequestBuilder request = get("/api/convert/");
String response = mockMvc.perform(request)
......@@ -333,6 +337,13 @@ public class ConvertControllerIntegrationTest extends ControllerIntegrationTest
Map<String, List<Map<String, List<String>>>> data = objectMapper.readValue(response,
new TypeReference<Map<String, List<Map<String, List<String>>>>>() {
});
return data;
}
private List<String> getImageOutputConverters() throws Exception {
List<String> result = new ArrayList<>();
Map<String, List<Map<String, List<String>>>> data = getImageConverters();
for (Map<String, List<String>> entry : data.get("outputs")) {
result.add(entry.get("available_names").get(0));
......@@ -341,9 +352,8 @@ public class ConvertControllerIntegrationTest extends ControllerIntegrationTest
return result;
}
private List<String> getImageOutputConverters() throws Exception {
List<String> result = new ArrayList<>();
private Map<String, List<Map<String, List<String>>>> getImageConverters()
throws UnsupportedEncodingException, Exception, IOException, JsonParseException, JsonMappingException {
RequestBuilder request = get("/api/convert/image/");
String response = mockMvc.perform(request)
......@@ -353,12 +363,7 @@ public class ConvertControllerIntegrationTest extends ControllerIntegrationTest
Map<String, List<Map<String, List<String>>>> data = objectMapper.readValue(response,
new TypeReference<Map<String, List<Map<String, List<String>>>>>() {
});
for (Map<String, List<String>> entry : data.get("outputs")) {
result.add(entry.get("available_names").get(0));
}
return result;
return data;
}
@Test
......@@ -393,4 +398,22 @@ public class ConvertControllerIntegrationTest extends ControllerIntegrationTest
assertTrue(result.contains("<rect"));
}