diff --git a/.idea/modules.xml b/.idea/modules.xml index 6e6dd9acbdd939bf1c110062e928a9ee7c27aa96..ae3706f24995e2278ace6b3dbfc2415ef574834a 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,7 +2,28 @@ <project version="4"> <component name="ProjectModuleManager"> <modules> + <module fileurl="file://$PROJECT_DIR$/CellDesigner-plugin/CellDesigner-plugin.iml" filepath="$PROJECT_DIR$/CellDesigner-plugin/CellDesigner-plugin.iml" /> + <module fileurl="file://$PROJECT_DIR$/annotation/annotation.iml" filepath="$PROJECT_DIR$/annotation/annotation.iml" /> + <module fileurl="file://$PROJECT_DIR$/commons/commons.iml" filepath="$PROJECT_DIR$/commons/commons.iml" /> + <module fileurl="file://$PROJECT_DIR$/comparison/comparison.iml" filepath="$PROJECT_DIR$/comparison/comparison.iml" /> + <module fileurl="file://$PROJECT_DIR$/console/console.iml" filepath="$PROJECT_DIR$/console/console.iml" /> + <module fileurl="file://$PROJECT_DIR$/converter/converter.iml" filepath="$PROJECT_DIR$/converter/converter.iml" /> + <module fileurl="file://$PROJECT_DIR$/converter-CellDesigner/converter-CellDesigner.iml" filepath="$PROJECT_DIR$/converter-CellDesigner/converter-CellDesigner.iml" /> + <module fileurl="file://$PROJECT_DIR$/converter-SBGNML/converter-SBGNML.iml" filepath="$PROJECT_DIR$/converter-SBGNML/converter-SBGNML.iml" /> + <module fileurl="file://$PROJECT_DIR$/converter-graphics/converter-graphics.iml" filepath="$PROJECT_DIR$/converter-graphics/converter-graphics.iml" /> + <module fileurl="file://$PROJECT_DIR$/editor/editor.iml" filepath="$PROJECT_DIR$/editor/editor.iml" /> + <module fileurl="file://$PROJECT_DIR$/frontend-js/frontend-js.iml" filepath="$PROJECT_DIR$/frontend-js/frontend-js.iml" /> <module fileurl="file://$PROJECT_DIR$/.idea/minerva.iml" filepath="$PROJECT_DIR$/.idea/minerva.iml" /> + <module fileurl="file://$PROJECT_DIR$/model/model.iml" filepath="$PROJECT_DIR$/model/model.iml" /> + <module fileurl="file://$PROJECT_DIR$/model-command/model-command.iml" filepath="$PROJECT_DIR$/model-command/model-command.iml" /> + <module fileurl="file://$PROJECT_DIR$/parent.iml" filepath="$PROJECT_DIR$/parent.iml" /> + <module fileurl="file://$PROJECT_DIR$/pathvisio/pathvisio.iml" filepath="$PROJECT_DIR$/pathvisio/pathvisio.iml" /> + <module fileurl="file://$PROJECT_DIR$/persist/persist.iml" filepath="$PROJECT_DIR$/persist/persist.iml" /> + <module fileurl="file://$PROJECT_DIR$/quadTrees/quadTrees.iml" filepath="$PROJECT_DIR$/quadTrees/quadTrees.iml" /> + <module fileurl="file://$PROJECT_DIR$/reactome/reactome.iml" filepath="$PROJECT_DIR$/reactome/reactome.iml" /> + <module fileurl="file://$PROJECT_DIR$/rest-api/rest-api.iml" filepath="$PROJECT_DIR$/rest-api/rest-api.iml" /> + <module fileurl="file://$PROJECT_DIR$/service/service.iml" filepath="$PROJECT_DIR$/service/service.iml" /> + <module fileurl="file://$PROJECT_DIR$/web/web.iml" filepath="$PROJECT_DIR$/web/web.iml" /> </modules> </component> </project> \ No newline at end of file diff --git a/converter/src/main/java/lcsb/mapviewer/converter/OverviewParser.java b/converter/src/main/java/lcsb/mapviewer/converter/OverviewParser.java index 134f9ddb91de60742bb98ed094477bbca56fb842..b04589b96d9b7d64f661fa3fa45410365397d679 100644 --- a/converter/src/main/java/lcsb/mapviewer/converter/OverviewParser.java +++ b/converter/src/main/java/lcsb/mapviewer/converter/OverviewParser.java @@ -13,6 +13,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.zip.ZipFile; import javax.imageio.ImageIO; @@ -90,17 +91,17 @@ public class OverviewParser { private static final Integer BUFFER_SIZE = 1024; /** - * String identifing {@link OverviewModelLink} connections. + * String identifying {@link OverviewModelLink} connections. */ private static final String MODEL_LINK_TYPE = "MODEL"; /** - * String identifing {@link OverviewImageLink} connections between images. + * String identifying {@link OverviewImageLink} connections between images. */ private static final String IMAGE_LINK_TYPE = "IMAGE"; /** - * String identifing {@link OverviewSearchLink} connections. + * String identifying {@link OverviewSearchLink} connections. */ private static final String SEARCH_LINK_TYPE = "SEARCH"; @@ -125,7 +126,7 @@ public class OverviewParser { * @throws InvalidOverviewFile * thrown when the zip file contains invalid data */ - public List<OverviewImage> parseOverviewLinks(Set<Model> models, List<ImageZipEntryFile> files, String outputDirectory) throws InvalidOverviewFile { + public List<OverviewImage> parseOverviewLinks(Set<Model> models, List<ImageZipEntryFile> files, String outputDirectory, ZipFile zipFile) throws InvalidOverviewFile { if (outputDirectory != null) { File f = new File(outputDirectory); if (!f.exists()) { @@ -151,14 +152,14 @@ public class OverviewParser { // copy file to file system if (outputDirectory != null) { imageFile = new File(outputDirectory + "/" + filename); - } else { // or temp file + } else { // or temporary file imageFile = File.createTempFile("temp-file-name", ".png"); imageFile.deleteOnExit(); } FileOutputStream fos = new FileOutputStream(imageFile); byte[] bytes = new byte[BUFFER_SIZE]; int length; - InputStream is = entry.getInputStream(); + InputStream is = zipFile.getInputStream(zipFile.getEntry(entry.getFilename())); while ((length = is.read(bytes)) >= 0) { fos.write(bytes, 0, length); } @@ -175,7 +176,7 @@ public class OverviewParser { StringBuilder sb = new StringBuilder(""); byte[] buffer = new byte[BUFFER_SIZE]; int read = 0; - InputStream is = entry.getInputStream(); + InputStream is = zipFile.getInputStream(zipFile.getEntry(entry.getFilename())); while ((read = is.read(buffer)) >= 0) { sb.append(new String(buffer, 0, read)); } diff --git a/converter/src/main/java/lcsb/mapviewer/converter/ProjectFactory.java b/converter/src/main/java/lcsb/mapviewer/converter/ProjectFactory.java index 11c34bf4ef262a1ceda2b7d412082c57e99aac5c..357a3da36158df62a51e1db9fc4d6a05f5980526 100644 --- a/converter/src/main/java/lcsb/mapviewer/converter/ProjectFactory.java +++ b/converter/src/main/java/lcsb/mapviewer/converter/ProjectFactory.java @@ -58,7 +58,7 @@ public class ProjectFactory { if (imageEntries.size() > 0) { OverviewParser parser = new OverviewParser(); - project.addOverviewImages(parser.parseOverviewLinks(models, imageEntries, params.getVisualizationDir())); + project.addOverviewImages(parser.parseOverviewLinks(models, imageEntries, params.getVisualizationDir(), zipFile)); } return project; } diff --git a/converter/src/main/java/lcsb/mapviewer/converter/zip/ImageZipEntryFile.java b/converter/src/main/java/lcsb/mapviewer/converter/zip/ImageZipEntryFile.java index 5b930d5dfb2237bb2320da91643ae352f25757c1..cef2d1956bf09943b4b837f36245625cc1abc5a6 100644 --- a/converter/src/main/java/lcsb/mapviewer/converter/zip/ImageZipEntryFile.java +++ b/converter/src/main/java/lcsb/mapviewer/converter/zip/ImageZipEntryFile.java @@ -1,9 +1,6 @@ package lcsb.mapviewer.converter.zip; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.InputStream; import java.io.Serializable; /** @@ -15,67 +12,31 @@ import java.io.Serializable; */ public class ImageZipEntryFile extends ZipEntryFile implements Serializable { - /** - * - */ - private static final long serialVersionUID = 1L; + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Default constructor. + */ + public ImageZipEntryFile() { + + } + + /** + * Default constructor. + * + * @param filename + * {@link ZipEntryFile#filename} + * @param inputStream + * input stream with the data for this entry. + * @see #baos + * @throws IOException + * thrown when there is a problem with accessing input stream + */ + public ImageZipEntryFile(String filename) { + super(filename); + } - /** - * Size of the buffer used to copy input streams. - */ - private static final int BUFFER_SIZE = 1024; - - /** - * Copy of the {@link InputStream} of the file. - */ - private byte[] bytes; - - /** - * Default constructor. - */ - public ImageZipEntryFile() { - - } - - /** - * Default constructor. - * - * @param filename - * {@link ZipEntryFile#filename} - * @param inputStream - * input stream with the data for this entry. - * @see #baos - * @throws IOException - * thrown when there is a problem with accessing input stream - */ - public ImageZipEntryFile(String filename, InputStream inputStream) throws IOException { - super(filename); - setInputStream(inputStream); - } - - /** - * @return the inputStream - * @see #inputStream - */ - public InputStream getInputStream() { - return new ByteArrayInputStream(bytes); - } - - /** - * @param inputStream - * the inputStream to set - * @throws IOException - * thrown when there is aproblem with accessing inputStream - * @see #inputStream - */ - public void setInputStream(InputStream inputStream) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - byte[] buffer = new byte[BUFFER_SIZE]; - int len; - while ((len = inputStream.read(buffer)) > -1) { - baos.write(buffer, 0, len); - } - baos.flush(); - bytes = baos.toByteArray(); - } } diff --git a/converter/src/main/java/lcsb/mapviewer/converter/zip/LayoutZipEntryFile.java b/converter/src/main/java/lcsb/mapviewer/converter/zip/LayoutZipEntryFile.java index 164b0aeba75d212a4f09c981faa4954e0d4b34a4..99b30c9a5e02cc81a1d4598c8c52a31a378b1aa5 100644 --- a/converter/src/main/java/lcsb/mapviewer/converter/zip/LayoutZipEntryFile.java +++ b/converter/src/main/java/lcsb/mapviewer/converter/zip/LayoutZipEntryFile.java @@ -11,70 +11,72 @@ import java.io.Serializable; */ public class LayoutZipEntryFile extends ZipEntryFile implements Serializable { - /** - * - */ - private static final long serialVersionUID = 1L; + /** + * + */ + private static final long serialVersionUID = 1L; - /** - * Name of the layout. - */ - private String name = ""; + /** + * Name of the layout. + */ + private String name = ""; - /** - * Description of the layout. - */ - private String description = ""; + /** + * Description of the layout. + */ + private String description = ""; - /** - * Default constructor. - */ - public LayoutZipEntryFile() { + /** + * Default constructor. + */ + public LayoutZipEntryFile() { - } + } - /** - * Default constructor. - * - * @param filename - * {@link ZipEntryFile#filename} - */ - public LayoutZipEntryFile(String filename) { - super(filename); - } + /** + * Default constructor. + * + * @param filename + * {@link ZipEntryFile#filename} + */ + public LayoutZipEntryFile(String filename, String name, String description) { + super(filename); + this.name = name; + this.description = description; + } - /** - * @return the name - * @see #name - */ - public String getName() { - return name; - } + /** + * @return the name + * @see #name + */ + public String getName() { + return name; + } - /** - * @param name - * the name to set - * @see #name - */ - public void setName(String name) { - this.name = name; - } + /** + * @param name + * the name to set + * @see #name + */ + public void setName(String name) { + this.name = name; + } - /** - * @return the description - * @see #description - */ - public String getDescription() { - return description; - } + /** + * @return the description + * @see #description + */ + public String getDescription() { + return description; + } - /** - * @param description - * the description to set - * @see #description - */ - public void setDescription(String description) { - this.description = description; - } + /** + * @param description + * the description to set + * @see #description + */ + public void setDescription(String description) { + this.description = description; + } } diff --git a/converter/src/main/java/lcsb/mapviewer/converter/zip/ZipEntryFileFactory.java b/converter/src/main/java/lcsb/mapviewer/converter/zip/ZipEntryFileFactory.java index 084e575cd01cac40a83cbe5d336b070865b62328..1bcdc4b20e5ebcf96f9b4efce7de1af63a80a909 100644 --- a/converter/src/main/java/lcsb/mapviewer/converter/zip/ZipEntryFileFactory.java +++ b/converter/src/main/java/lcsb/mapviewer/converter/zip/ZipEntryFileFactory.java @@ -165,7 +165,7 @@ public class ZipEntryFileFactory { } return zesf; } else if (directory.equals(IMAGES_DIRECTORY)) { - ImageZipEntryFile result = new ImageZipEntryFile(entry.getName(), zipFile.getInputStream(entry)); + ImageZipEntryFile result = new ImageZipEntryFile(entry.getName()); return result; } else if (directory.equals(LAYOUT_DIRECTORY)) { LayoutZipEntryFile result = createLayoutZipEntryFile(entry.getName(), zipFile.getInputStream(entry)); diff --git a/converter/src/test/java/lcsb/mapviewer/converter/OverviewParserTest.java b/converter/src/test/java/lcsb/mapviewer/converter/OverviewParserTest.java index 50777ea476c2b48bf91f150162df8119b0e9cb58..feace015aecc51cdc5e9432d02f5f178aa45b73d 100644 --- a/converter/src/test/java/lcsb/mapviewer/converter/OverviewParserTest.java +++ b/converter/src/test/java/lcsb/mapviewer/converter/OverviewParserTest.java @@ -10,9 +10,12 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.Enumeration; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; import org.apache.commons.io.FileUtils; import org.apache.log4j.Logger; @@ -28,226 +31,237 @@ import lcsb.mapviewer.model.map.model.Model; import lcsb.mapviewer.model.map.model.ModelFullIndexed; public class OverviewParserTest { - Logger logger = Logger.getLogger(OverviewParserTest.class); - OverviewParser parser = new OverviewParser(); - - @Before - public void setUp() throws Exception { - } - - @After - public void tearDown() throws Exception { - } - - @Test - public void testParsingValidFile() throws Exception { - try { - Set<Model> models = createValidTestMapModel(); - List<ImageZipEntryFile> imageEntries = createImageEntries("testFiles/valid_overview"); - List<OverviewImage> result = parser.parseOverviewLinks(models, imageEntries, null); - assertNotNull(result); - assertEquals(1, result.size()); - - OverviewImage img = result.get(0); - - assertEquals("test.png", img.getFilename()); - assertEquals((Integer) 639, img.getHeight()); - assertEquals((Integer) 963, img.getWidth()); - assertEquals(2, img.getLinks().size()); - - OverviewLink link = img.getLinks().get(0); - List<Point2D> polygon = link.getPolygonCoordinates(); - assertEquals(4, polygon.size()); - - assertTrue(link instanceof OverviewModelLink); - - OverviewModelLink mLink = (OverviewModelLink) link; - Model mainModel = models.iterator().next(); - assertEquals(mainModel.getModelData(), mLink.getLinkedModel()); - assertEquals((Integer) 10, mLink.getxCoord()); - assertEquals((Integer) 10, mLink.getyCoord()); - assertEquals((Integer) 3, mLink.getZoomLevel()); - - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - private List<ImageZipEntryFile> createImageEntries(String string) throws IOException { - List<ImageZipEntryFile> result = new ArrayList<ImageZipEntryFile>(); - for (final File fileEntry : new File(string).listFiles()) { - if (!fileEntry.isDirectory()) { - result.add(new ImageZipEntryFile(fileEntry.getName(), new FileInputStream(fileEntry))); - } - } - return result; - } - - @Test - public void testParsingValidFile2() throws Exception { - try { - Set<Model> models = createValidTestMapModel(); - - String tmpDir = "tmp"; - - new File(tmpDir).mkdirs(); - List<ImageZipEntryFile> imageEntries = createImageEntries("testFiles/valid_overview"); - List<OverviewImage> result = parser.parseOverviewLinks(models, imageEntries, tmpDir); - - assertTrue(new File(tmpDir + "/test.png").exists()); - - assertNotNull(result); - assertEquals(1, result.size()); - OverviewImage img = result.get(0); - assertEquals("test.png", img.getFilename()); - - new File(tmpDir).delete(); - - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - @Test - public void testParsingInvalidFile1() throws Exception { - try { - List<ImageZipEntryFile> imageEntries = createImageEntries("testFiles/invalid_overview_1"); - Set<Model> models = createValidTestMapModel(); - - parser.parseOverviewLinks(models, imageEntries, null); - fail("Exception expected"); - } catch (InvalidOverviewFile e) { - assertTrue(e.getMessage().contains("Unknown image filename")); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - @Test - public void testParsingInvalidFile2() throws Exception { - try { - List<ImageZipEntryFile> imageEntries = createImageEntries("testFiles/invalid_overview_2"); - Set<Model> models = createValidTestMapModel(); - - parser.parseOverviewLinks(models, imageEntries, null); - fail("Exception expected"); - } catch (InvalidOverviewFile e) { - assertTrue(e.getMessage().contains("Unknown model")); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - @Test - public void testParsingInvalidFile3() throws Exception { - try { - List<ImageZipEntryFile> imageEntries = createImageEntries("testFiles/invalid_overview_3"); - Set<Model> models = createValidTestMapModel(); - - parser.parseOverviewLinks(models, imageEntries, null); - fail("Exception expected"); - } catch (InvalidOverviewFile e) { - assertTrue(e.getMessage().contains("coordinates outside image")); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - private Set<Model> createValidTestMapModel() { - Set<Model> result = new HashSet<>(); - Model model = new ModelFullIndexed(null); - model.setName("main"); - result.add(model); - return result; - } - - /** - * Test coordinates that overlap (exception is expected). - * - * @throws Exception - */ - @Test - public void testParseInvalidCoordinates() throws Exception { - try { - String invalidCoordinates = "test.png 10,10 100,10 100,100 10,10 main.xml 10,10 3\n" + // - "test.png 10,10 10,400 400,400 400,10 main.xml 10,10 4"; - Set<Model> models = createValidTestMapModel(); - - List<OverviewImage> images = new ArrayList<OverviewImage>(); - OverviewImage oi = new OverviewImage(); - oi.setFilename("test.png"); - oi.setWidth(1000); - oi.setHeight(1000); - images.add(oi); - - parser.processCoordinates(models, images, invalidCoordinates); - - fail("Exception expected"); - } catch (InvalidOverviewFile e) { - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - @Test - public void testParseValidCoordinates() throws Exception { - try { - String invalidCoordinates = "FILE POLYGON LINK_TARGET MODEL_COORDINATES MODEL_ZOOM_LEVEL LINK_TYPE\n" + // - "test.png 10,10 100,10 100,100 10,10 main.xml 10,10 3 MODEL\n" + // - "test.png 200,200 200,400 400,400 400,200 main.xml 10,10 4 MODEL"; - Set<Model> models = createValidTestMapModel(); - - List<OverviewImage> images = new ArrayList<OverviewImage>(); - OverviewImage oi = new OverviewImage(); - oi.setFilename("test.png"); - oi.setWidth(1000); - oi.setHeight(1000); - images.add(oi); - - parser.processCoordinates(models, images, invalidCoordinates); - - assertEquals(2, oi.getLinks().size()); - - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - @Test - public void testParseValidComplexCoordinates() throws Exception { - try { - String invalidCoordinates = FileUtils.readFileToString(new File("testFiles/coordinates.txt")); - Set<Model> models = createValidTestMapModel(); - - List<OverviewImage> images = new ArrayList<>(); - OverviewImage oi = new OverviewImage(); - oi.setFilename("test.png"); - oi.setWidth(1000); - oi.setHeight(1000); - images.add(oi); - - OverviewImage oi2 = new OverviewImage(); - oi2.setFilename("test2.png"); - oi2.setWidth(1000); - oi2.setHeight(1000); - images.add(oi2); - - parser.processCoordinates(models, images, invalidCoordinates); - - assertEquals(2, oi.getLinks().size()); - assertEquals(1, oi2.getLinks().size()); - - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } + private static final String TEST_FILES_VALID_OVERVIEW_ZIP = "testFiles/valid_overview.zip"; + Logger logger = Logger.getLogger(OverviewParserTest.class); + OverviewParser parser = new OverviewParser(); + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testParsingValidFile() throws Exception { + try { + Set<Model> models = createValidTestMapModel(); + List<ImageZipEntryFile> imageEntries = createImageEntries(TEST_FILES_VALID_OVERVIEW_ZIP); + List<OverviewImage> result = parser.parseOverviewLinks(models, imageEntries, null, + new ZipFile(TEST_FILES_VALID_OVERVIEW_ZIP)); + assertNotNull(result); + assertEquals(1, result.size()); + + OverviewImage img = result.get(0); + + assertEquals("test.png", img.getFilename()); + assertEquals((Integer) 639, img.getHeight()); + assertEquals((Integer) 963, img.getWidth()); + assertEquals(2, img.getLinks().size()); + + OverviewLink link = img.getLinks().get(0); + List<Point2D> polygon = link.getPolygonCoordinates(); + assertEquals(4, polygon.size()); + + assertTrue(link instanceof OverviewModelLink); + + OverviewModelLink mLink = (OverviewModelLink) link; + Model mainModel = models.iterator().next(); + assertEquals(mainModel.getModelData(), mLink.getLinkedModel()); + assertEquals((Integer) 10, mLink.getxCoord()); + assertEquals((Integer) 10, mLink.getyCoord()); + assertEquals((Integer) 3, mLink.getZoomLevel()); + + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + private List<ImageZipEntryFile> createImageEntries(String string) throws IOException { + List<ImageZipEntryFile> result = new ArrayList<>(); + + ZipFile zipFile = new ZipFile(string); + try { + Enumeration<? extends ZipEntry> entries = zipFile.entries(); + while (entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + if (!entry.isDirectory()) { + result.add(new ImageZipEntryFile(entry.getName())); + } + } + return result; + } finally { + zipFile.close(); + } + } + + @Test + public void testParsingValidFile2() throws Exception { + try { + Set<Model> models = createValidTestMapModel(); + + String tmpDir = "tmp"; + + new File(tmpDir).mkdirs(); + List<ImageZipEntryFile> imageEntries = createImageEntries(TEST_FILES_VALID_OVERVIEW_ZIP); + List<OverviewImage> result = parser.parseOverviewLinks(models, imageEntries, tmpDir, + new ZipFile(TEST_FILES_VALID_OVERVIEW_ZIP)); + + assertTrue(new File(tmpDir + "/test.png").exists()); + + assertNotNull(result); + assertEquals(1, result.size()); + OverviewImage img = result.get(0); + assertEquals("test.png", img.getFilename()); + + new File(tmpDir).delete(); + + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testParsingInvalidFile1() throws Exception { + try { + List<ImageZipEntryFile> imageEntries = createImageEntries("testFiles/invalid_overview_1.zip"); + Set<Model> models = createValidTestMapModel(); + + parser.parseOverviewLinks(models, imageEntries, null, new ZipFile("testFiles/invalid_overview_1.zip")); + fail("Exception expected"); + } catch (InvalidOverviewFile e) { + assertTrue(e.getMessage().contains("Unknown image filename")); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testParsingInvalidFile2() throws Exception { + try { + List<ImageZipEntryFile> imageEntries = createImageEntries("testFiles/invalid_overview_2.zip"); + Set<Model> models = createValidTestMapModel(); + + parser.parseOverviewLinks(models, imageEntries, null, new ZipFile("testFiles/invalid_overview_2.zip")); + fail("Exception expected"); + } catch (InvalidOverviewFile e) { + assertTrue(e.getMessage().contains("Unknown model")); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testParsingInvalidFile3() throws Exception { + try { + List<ImageZipEntryFile> imageEntries = createImageEntries("testFiles/invalid_overview_3.zip"); + Set<Model> models = createValidTestMapModel(); + + parser.parseOverviewLinks(models, imageEntries, null, new ZipFile("testFiles/invalid_overview_3.zip")); + fail("Exception expected"); + } catch (InvalidOverviewFile e) { + assertTrue(e.getMessage().contains("coordinates outside image")); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + private Set<Model> createValidTestMapModel() { + Set<Model> result = new HashSet<>(); + Model model = new ModelFullIndexed(null); + model.setName("main"); + result.add(model); + return result; + } + + /** + * Test coordinates that overlap (exception is expected). + * + * @throws Exception + */ + @Test + public void testParseInvalidCoordinates() throws Exception { + try { + String invalidCoordinates = "test.png 10,10 100,10 100,100 10,10 main.xml 10,10 3\n" + // + "test.png 10,10 10,400 400,400 400,10 main.xml 10,10 4"; + Set<Model> models = createValidTestMapModel(); + + List<OverviewImage> images = new ArrayList<OverviewImage>(); + OverviewImage oi = new OverviewImage(); + oi.setFilename("test.png"); + oi.setWidth(1000); + oi.setHeight(1000); + images.add(oi); + + parser.processCoordinates(models, images, invalidCoordinates); + + fail("Exception expected"); + } catch (InvalidOverviewFile e) { + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testParseValidCoordinates() throws Exception { + try { + String invalidCoordinates = "FILE POLYGON LINK_TARGET MODEL_COORDINATES MODEL_ZOOM_LEVEL LINK_TYPE\n" + // + "test.png 10,10 100,10 100,100 10,10 main.xml 10,10 3 MODEL\n" + // + "test.png 200,200 200,400 400,400 400,200 main.xml 10,10 4 MODEL"; + Set<Model> models = createValidTestMapModel(); + + List<OverviewImage> images = new ArrayList<OverviewImage>(); + OverviewImage oi = new OverviewImage(); + oi.setFilename("test.png"); + oi.setWidth(1000); + oi.setHeight(1000); + images.add(oi); + + parser.processCoordinates(models, images, invalidCoordinates); + + assertEquals(2, oi.getLinks().size()); + + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testParseValidComplexCoordinates() throws Exception { + try { + String invalidCoordinates = FileUtils.readFileToString(new File("testFiles/coordinates.txt")); + Set<Model> models = createValidTestMapModel(); + + List<OverviewImage> images = new ArrayList<>(); + OverviewImage oi = new OverviewImage(); + oi.setFilename("test.png"); + oi.setWidth(1000); + oi.setHeight(1000); + images.add(oi); + + OverviewImage oi2 = new OverviewImage(); + oi2.setFilename("test2.png"); + oi2.setWidth(1000); + oi2.setHeight(1000); + images.add(oi2); + + parser.processCoordinates(models, images, invalidCoordinates); + + assertEquals(2, oi.getLinks().size()); + assertEquals(1, oi2.getLinks().size()); + + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } } diff --git a/converter/src/test/resources/log4j.properties b/converter/src/test/resources/log4j.properties index ec610a35af6964418be577ea1bce3ed615e8f91e..4d46bcbdbbff98b6f0ab577993b51da5a200c6d3 100644 --- a/converter/src/test/resources/log4j.properties +++ b/converter/src/test/resources/log4j.properties @@ -1,5 +1,5 @@ #Set root logger 's level and its appender to an appender called CONSOLE which is defined below. -log4j.rootLogger=info, CONSOLE, R +log4j.rootLogger=info, CONSOLE #Set the behavior of the CONSOLE appender log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender diff --git a/converter/testFiles/invalid_overview_1.zip b/converter/testFiles/invalid_overview_1.zip new file mode 100644 index 0000000000000000000000000000000000000000..b3040204788c875114301808c2920fee4dda812b Binary files /dev/null and b/converter/testFiles/invalid_overview_1.zip differ diff --git a/converter/testFiles/invalid_overview_1/coords.txt b/converter/testFiles/invalid_overview_1/coords.txt deleted file mode 100644 index 6b604ee16c9737e8fce2be69ca0064314a1a141c..0000000000000000000000000000000000000000 --- a/converter/testFiles/invalid_overview_1/coords.txt +++ /dev/null @@ -1,4 +0,0 @@ -FILE POLYGON LINK_TARGET MODEL_COORDINATES MODEL_ZOOM_LEVEL LINK_TYPE -unknowntest.png 10,10 100,10 100,100 100,10 main.xml 10,10 3 MODEL -test.png 200,200 200,400 400,400 400,200 main.xml 1000,1000 4 MODEL - diff --git a/converter/testFiles/invalid_overview_1/test.png b/converter/testFiles/invalid_overview_1/test.png deleted file mode 100644 index adbe702689a43364dc6f0a6cebedcc9277388a9c..0000000000000000000000000000000000000000 Binary files a/converter/testFiles/invalid_overview_1/test.png and /dev/null differ diff --git a/converter/testFiles/invalid_overview_2.zip b/converter/testFiles/invalid_overview_2.zip new file mode 100644 index 0000000000000000000000000000000000000000..c2d52c9ce246a4df4b3563863c1ca122927c7958 Binary files /dev/null and b/converter/testFiles/invalid_overview_2.zip differ diff --git a/converter/testFiles/invalid_overview_2/coords.txt b/converter/testFiles/invalid_overview_2/coords.txt deleted file mode 100644 index d25072502f67096da21cace09230e9eb01e87cc5..0000000000000000000000000000000000000000 --- a/converter/testFiles/invalid_overview_2/coords.txt +++ /dev/null @@ -1,4 +0,0 @@ -FILE POLYGON LINK_TARGET MODEL_COORDINATES MODEL_ZOOM_LEVEL LINK_TYPE -test.png 10,10 100,10 100,100 100,10 unknown_main.xml 10,10 3 MODEL -test.png 200,200 200,400 400,400 400,200 main.xml 1000,1000 4 MODEL - diff --git a/converter/testFiles/invalid_overview_2/test.png b/converter/testFiles/invalid_overview_2/test.png deleted file mode 100644 index adbe702689a43364dc6f0a6cebedcc9277388a9c..0000000000000000000000000000000000000000 Binary files a/converter/testFiles/invalid_overview_2/test.png and /dev/null differ diff --git a/converter/testFiles/invalid_overview_3.zip b/converter/testFiles/invalid_overview_3.zip new file mode 100644 index 0000000000000000000000000000000000000000..9b995cf8be6b2a267e7f4f440bfce870ecbf761a Binary files /dev/null and b/converter/testFiles/invalid_overview_3.zip differ diff --git a/converter/testFiles/invalid_overview_3/coords.txt b/converter/testFiles/invalid_overview_3/coords.txt deleted file mode 100644 index 63839f6e7d91535a62b50690b3ca1d662ac65dcf..0000000000000000000000000000000000000000 --- a/converter/testFiles/invalid_overview_3/coords.txt +++ /dev/null @@ -1,4 +0,0 @@ -FILE POLYGON LINK_TARGET MODEL_COORDINATES MODEL_ZOOM_LEVEL LINK_TYPE -test.png 10,10 100,10 100,100 10000,10 main.xml 10,10 3 MODEL -test.png 200,200 200,400 400,400 400,200 main.xml 1000,1000 4 MODEL - diff --git a/converter/testFiles/invalid_overview_3/test.png b/converter/testFiles/invalid_overview_3/test.png deleted file mode 100644 index adbe702689a43364dc6f0a6cebedcc9277388a9c..0000000000000000000000000000000000000000 Binary files a/converter/testFiles/invalid_overview_3/test.png and /dev/null differ diff --git a/converter/testFiles/valid_overview.zip b/converter/testFiles/valid_overview.zip new file mode 100644 index 0000000000000000000000000000000000000000..edfff4deed85439da9ae079ad6a22be298f9a42a Binary files /dev/null and b/converter/testFiles/valid_overview.zip differ diff --git a/converter/testFiles/valid_overview/coords.txt b/converter/testFiles/valid_overview/coords.txt deleted file mode 100644 index 6cc5a4478fdef368e2c1e9e1f21e54fc9794e308..0000000000000000000000000000000000000000 --- a/converter/testFiles/valid_overview/coords.txt +++ /dev/null @@ -1,4 +0,0 @@ -FILE POLYGON LINK_TARGET MODEL_COORDINATES MODEL_ZOOM_LEVEL LINK_TYPE -test.png 10,10 100,10 100,100 100,10 main.xml 10,10 3 MODEL -test.png 200,200 200,400 400,400 400,200 main.xml 1000,1000 4 MODEL - diff --git a/converter/testFiles/valid_overview/test.png b/converter/testFiles/valid_overview/test.png deleted file mode 100644 index adbe702689a43364dc6f0a6cebedcc9277388a9c..0000000000000000000000000000000000000000 Binary files a/converter/testFiles/valid_overview/test.png and /dev/null differ diff --git a/frontend-js/.idea/frontend-js.iml b/frontend-js/.idea/frontend-js.iml index 4feb4987b6dd589318a78302c0367c39c36535a9..217608cacb6a1c303a5e7e7c1b1ad8b1338de378 100644 --- a/frontend-js/.idea/frontend-js.iml +++ b/frontend-js/.idea/frontend-js.iml @@ -4,11 +4,12 @@ <content url="file://$MODULE_DIR$"> <sourceFolder url="file://$MODULE_DIR$/src/test" isTestSource="true" /> <excludeFolder url="file://$MODULE_DIR$/.tmp" /> - <excludeFolder url="file://$MODULE_DIR$/temp" /> <excludeFolder url="file://$MODULE_DIR$/dist" /> + <excludeFolder url="file://$MODULE_DIR$/temp" /> <excludeFolder url="file://$MODULE_DIR$/tmp" /> </content> <orderEntry type="inheritedJdk" /> <orderEntry type="sourceFolder" forTests="false" /> + <orderEntry type="library" name="chai-DefinitelyTyped" level="application" /> </component> -</module> +</module> \ No newline at end of file diff --git a/frontend-js/package.json b/frontend-js/package.json index dbf87572a8bb5b7aac10a6b456fcb358ff06198e..6608366a592f90159e988c0da56c07e56cc6ad30 100644 --- a/frontend-js/package.json +++ b/frontend-js/package.json @@ -43,6 +43,7 @@ "http-status-codes": "^1.3.0", "js-cookie": "^2.1.3", "jstree": "^3.3.4", + "jszip": "^3.1.4", "log4js": "0.6.38", "pileup": "^0.6.8", "request": "^2.82.0" diff --git a/frontend-js/src/main/js/Configuration.js b/frontend-js/src/main/js/Configuration.js index f8bf26513b79f892ac70104ce220e94ed300fe0c..5dc187dd7cf1af381eddfbba546837ad98233358 100644 --- a/frontend-js/src/main/js/Configuration.js +++ b/frontend-js/src/main/js/Configuration.js @@ -49,6 +49,7 @@ function Configuration(json) { self.setElementTypes(json.elementTypes); self.setReactionTypes(json.reactionTypes); self.setMiriamTypes(json.miriamTypes); + self.setMapTypes(json.mapTypes); self.setModificationStateTypes(json.modificationStateTypes); self.setPrivilegeTypes(json.privilegeTypes); self.setAnnotators(json.annotators); @@ -98,12 +99,12 @@ Configuration.prototype.getElementTypeNames = function () { Configuration.prototype.getParentType = function (elementType) { var i; - for (var i = 0; i < this._elementTypes.length; i++) { + for (i = 0; i < this._elementTypes.length; i++) { if (this._elementTypes[i].className === elementType.parentClass) { return this._elementTypes[i]; } } - for (var i = 0; i < this._reactionTypes.length; i++) { + for (i = 0; i < this._reactionTypes.length; i++) { if (this._reactionTypes[i].className === elementType.parentClass) { return this._reactionTypes[i]; } @@ -152,6 +153,13 @@ Configuration.prototype.setMiriamTypes = function (miriamTypes) { ); }; +Configuration.prototype.setMapTypes = function (mapTypes) { + this._mapTypes = mapTypes; +}; +Configuration.prototype.getMapTypes = function () { + return this._mapTypes; +}; + Configuration.prototype.setPrivilegeTypes = function (privilegeTypes) { this._privilegeTypes = []; for (var key in privilegeTypes) { @@ -206,7 +214,7 @@ Configuration.prototype.setAnnotators = function (annotators) { for (var key in annotators) { if (annotators.hasOwnProperty(key)) { var annotator = annotators[key]; - this._annotators.push(new Annotator(annotators[key], this)); + this._annotators.push(new Annotator(annotator, this)); } } }; diff --git a/frontend-js/src/main/js/gui/AddOverlayDialog.js b/frontend-js/src/main/js/gui/AddOverlayDialog.js index b78dc728ab4ed3fc4cb752f5e0a19e7e646f5394..857b2930e528de8b0b724b91be4ce5276d0d0a70 100644 --- a/frontend-js/src/main/js/gui/AddOverlayDialog.js +++ b/frontend-js/src/main/js/gui/AddOverlayDialog.js @@ -8,6 +8,8 @@ var GuiUtils = require('./leftPanel/GuiUtils'); var LayoutData = require('../map/data/LayoutData'); var NetworkError = require('../NetworkError'); +var OverlayParser = require('../map/OverlayParser'); + var Functions = require('../Functions'); var logger = require('../logger'); var HttpStatus = require('http-status-codes'); @@ -24,7 +26,7 @@ function AddOverlayDialog(params) { AddOverlayDialog.prototype = Object.create(AbstractGuiElement.prototype); AddOverlayDialog.prototype.constructor = AddOverlayDialog; -AddOverlayDialog.prototype.createGui = function() { +AddOverlayDialog.prototype.createGui = function () { var self = this; var guiUtils = new GuiUtils(); var content = document.createElement("div"); @@ -32,9 +34,9 @@ AddOverlayDialog.prototype.createGui = function() { content.style.height = "100%"; content.appendChild(guiUtils.createLabel("Name: ")); var nameInput = Functions.createElement({ - type : "input", - inputType : "text", - name : "overlay-name", + type: "input", + inputType: "text", + name: "overlay-name", }); content.appendChild(nameInput); content.appendChild(guiUtils.createNewLine()); @@ -42,19 +44,19 @@ AddOverlayDialog.prototype.createGui = function() { content.appendChild(guiUtils.createLabel("Description: ")); content.appendChild(guiUtils.createNewLine()); var descriptionInput = Functions.createElement({ - type : "textarea", - name : "overlay-description", + type: "textarea", + name: "overlay-description", }); content.appendChild(descriptionInput); content.appendChild(guiUtils.createNewLine()); content.appendChild(guiUtils.createLabel("Upload file: ")); var fileInput = Functions.createElement({ - type : "input", - inputType : "file", - name : "overlay-file", + type: "input", + inputType: "file", + name: "overlay-file", }); - fileInput.addEventListener("change", function() { + fileInput.addEventListener("change", function () { return self.processFile(fileInput.files[0]); }, false); content.appendChild(fileInput); @@ -63,8 +65,8 @@ AddOverlayDialog.prototype.createGui = function() { content.appendChild(guiUtils.createLabel("Or provide list of elements here (one per line): ")); content.appendChild(guiUtils.createNewLine()); var contentInput = Functions.createElement({ - type : "textarea", - name : "overlay-content", + type: "textarea", + name: "overlay-content", }); content.appendChild(contentInput); content.appendChild(guiUtils.createNewLine()); @@ -72,21 +74,22 @@ AddOverlayDialog.prototype.createGui = function() { self.getElement().appendChild(content); }; -AddOverlayDialog.prototype.processFile = function(file) { +AddOverlayDialog.prototype.processFile = function (file) { var self = this; self.setFileContent(null); if (file) { - return new Promise(function(resolve, reject) { + return new Promise(function (resolve, reject) { var reader = new FileReader(); reader.readAsText(file, "UTF-8"); - reader.onload = function(evt) { + reader.onload = function (evt) { try { + var overlayParser = new OverlayParser(); self.setFileContent(evt.target.result); - var data = self.parseFile(evt.target.result); + var overlay = overlayParser.parse(evt.target.result); var nameInput = $("[name='overlay-name']", self.getElement())[0]; var descriptionInput = $("[name='overlay-description']", self.getElement())[0]; - if (data.name !== undefined) { - nameInput.value = data.name; + if (overlay.getName() !== undefined) { + nameInput.value = overlay.getName(); } else { var filename = $("[name='overlay-file']", self.getElement())[0].value; if (filename.indexOf(".") > 0) { @@ -97,15 +100,15 @@ AddOverlayDialog.prototype.processFile = function(file) { } nameInput.value = filename; } - if (data.description !== undefined) { - descriptionInput.value = data.description; + if (overlay.getDescription() !== undefined) { + descriptionInput.value = overlay.getDescription(); } resolve(self.getFileContent()); } catch (error) { reject(error); } }; - reader.onerror = function() { + reader.onerror = function () { reject(new Error("Problem reading file")); }; }); @@ -114,11 +117,11 @@ AddOverlayDialog.prototype.processFile = function(file) { } }; -AddOverlayDialog.prototype.setFileContent = function(fileContent) { +AddOverlayDialog.prototype.setFileContent = function (fileContent) { this._fileContent = fileContent; }; -AddOverlayDialog.prototype.getFileContent = function() { +AddOverlayDialog.prototype.getFileContent = function () { var self = this; var contentInput = $("[name='overlay-content']", self.getElement())[0]; @@ -135,43 +138,43 @@ AddOverlayDialog.prototype.getFileContent = function() { } }; -AddOverlayDialog.prototype.init = function() { +AddOverlayDialog.prototype.init = function () { return Promise.resolve(); }; -AddOverlayDialog.prototype.addOverlay = function() { +AddOverlayDialog.prototype.addOverlay = function () { var self = this; var nameInput = $("[name='overlay-name']", self.getElement())[0]; var descriptionInput = $("[name='overlay-description']", self.getElement())[0]; var filename = $("[name='overlay-file']", self.getElement())[0].value; var overlay = new LayoutData({ - name : nameInput.value, - description : descriptionInput.value, - content : self.getFileContent(), - filename : filename, + name: nameInput.value, + description: descriptionInput.value, + content: self.getFileContent(), + filename: filename, }); GuiConnector.showProcessing(); return ServerConnector.addOverlay({ - overlay : overlay, - projectId : self.getProject().getProjectId(), - }).then(function(result) { + overlay: overlay, + projectId: self.getProject().getProjectId(), + }).then(function (result) { overlay = result; GuiConnector.hideProcessing(); return self.callListeners("onAddOverlay", overlay); }); }; -AddOverlayDialog.prototype.destroy = function() { +AddOverlayDialog.prototype.destroy = function () { $(this.getElement()).dialog("destroy"); }; -AddOverlayDialog.prototype.open = function() { +AddOverlayDialog.prototype.open = function () { var self = this; var div = self.getElement(); if (!$(div).hasClass("ui-dialog-content")) { - var buttons = [ { - text : "UPLOAD", - click : function() { + var buttons = [{ + text: "UPLOAD", + click: function () { var dialog = this; var fileContent = self.getFileContent(); if (fileContent === null) { @@ -179,10 +182,10 @@ AddOverlayDialog.prototype.open = function() { } else if (fileContent.length > 1024 * 256) { GuiConnector.alert("File to big.<br>Please reduce file size or contact administrators."); } else { - return self.addOverlay().then(function(result) { + return self.addOverlay().then(function (result) { $(dialog).dialog("close"); return result; - }, function(error) { + }, function (error) { GuiConnector.hideProcessing(); if (error instanceof NetworkError && error.statusCode === HttpStatus.BAD_REQUEST) { var errorMessage = JSON.parse(error.content); @@ -194,46 +197,20 @@ AddOverlayDialog.prototype.open = function() { } } }, { - text : "CANCEL", - click : function() { + text: "CANCEL", + click: function () { $(this).dialog("close"); } - } ]; + }]; $(div).dialog({ - title : "Add overlay", - buttons : buttons, - modal : true, + title: "Add overlay", + buttons: buttons, + modal: true, }); } $(div).dialog("open"); }; -AddOverlayDialog.prototype.parseFile = function(fileContent) { - var result = {}; - var lines = fileContent.split("\n"); - for (var i = 0; i < lines.length; i++) { - var line = lines[i]; - if (line.startsWith("#")) { - if (line.indexOf("=") > 0) { - var name = line.substring(1, line.indexOf("=")).trim(); - var value = line.substring(line.indexOf("=") + 1).trim(); - if (name === "NAME") { - result.name = value; - } else if (name === "DESCRIPTION") { - result.description = value; - } else if (name === "TYPE") { - result.type = value; - } - } else { - logger.warn("Invalid overlay header line: " + line); - } - } else { - break; - } - } - return result; -}; - module.exports = AddOverlayDialog; diff --git a/frontend-js/src/main/js/gui/admin/AddProjectDialog.js b/frontend-js/src/main/js/gui/admin/AddProjectDialog.js index 26dea5dfd6dd9bdc3a4793fc5dead2f571d1f640..966d914461424cdbc1c4fb1672b782fa37b0c029 100644 --- a/frontend-js/src/main/js/gui/admin/AddProjectDialog.js +++ b/frontend-js/src/main/js/gui/admin/AddProjectDialog.js @@ -2,12 +2,14 @@ /* exported logger */ var Promise = require("bluebird"); +var JSZip = require("jszip"); var AbstractGuiElement = require('../AbstractGuiElement'); var ChooseAnnotatorsDialog = require('./ChooseAnnotatorsDialog'); var ChooseValidatorsDialog = require('./ChooseValidatorsDialog'); var GuiConnector = require('../../GuiConnector'); -var UserPreferences = require("../../map/data/UserPreferences"); +var OverlayParser = require('../../map/OverlayParser'); +var ZipEntry = require('./ZipEntry'); var Functions = require('../../Functions'); var logger = require('../../logger'); @@ -21,7 +23,10 @@ function AddProjectDialog(params) { AbstractGuiElement.call(this, params); var self = this; self.registerListenerType("onFileUpload"); + self.registerListenerType("onZipFileUpload"); + self.setZipEntries([]); $(self.getElement()).addClass("minerva-edit-project-dialog"); + $(self.getElement()).css({overflow: "hidden"}); self.createGui(); } @@ -36,7 +41,8 @@ AddProjectDialog.prototype.createGui = function () { var tabDiv = Functions.createElement({ type: "div", name: "tabView", - className: "tabbable boxed parentTabs" + className: "tabbable boxed parentTabs", + style: "position:absolute;top:40px;bottom:10px;left:10px;right:10px" }); element.appendChild(tabDiv); @@ -48,7 +54,8 @@ AddProjectDialog.prototype.createGui = function () { var tabContentDiv = Functions.createElement({ type: "div", - className: "tab-content" + className: "tab-content", + style: "height:100%" }); tabDiv.appendChild(tabContentDiv); @@ -83,6 +90,7 @@ AddProjectDialog.prototype.addTab = function (params) { navigationObject: navLi, navigationBar: params.tabMenuDiv }); + contentDiv.style.overflow = "auto"; if (params.content !== undefined) { contentDiv.appendChild(params.content); @@ -148,6 +156,10 @@ AddProjectDialog.prototype.createGeneralTabContent = function () { var file = e.arg; return self.processFile(file); }); + self.addListener("onFileUpload", function (e) { + var file = e.arg; + return self.setZipFileContent(file); + }); self.addListener("onFileUpload", function (e) { var file = e.arg; if (file.name.lastIndexOf('.') > 0) { @@ -308,11 +320,59 @@ AddProjectDialog.prototype.createOverlaysTabContent = function () { }; AddProjectDialog.prototype._createOverlayTable = function () { + var self = this; var result = Functions.createElement({ type: "div", style: "margin-top:10px;" }); + var overlaysTable = Functions.createElement({ + type: "table", + name: "overlaysTable", + className: "display", + style: "width:100%" + }); + result.appendChild(overlaysTable); + + $(overlaysTable).DataTable({ + columns: [{ + title: 'File name' + }, { + title: 'Name' + }, { + title: 'Description' + }] + }); + + $(overlaysTable).on("input", "[name='overlayName']", function () { + var input = this; + var filename = $(input).attr("data"); + self.getEntryByFilename(filename).getData().name = $(input).val(); + }); + + $(overlaysTable).on("input", "[name='overlayDescription']", function () { + var input = this; + var filename = $(input).attr("data"); + self.getEntryByFilename(filename).getData().description = $(input).val(); + }); + + self.addListener("onZipFileUpload", function () { + var entries = self.getZipEntries(); + var dataTable = $($("[name='overlaysTable']", self.getElement())[0]).DataTable(); + var data = []; + for (var i = 0; i < entries.length; i++) { + var entry = entries[i]; + if (entry.getType() === "OVERLAY") { + var row = []; + row[0] = entry.getFilename(); + row[1] = "<input data='" + entry.getFilename() + "' name='overlayName' value='" + entry.getData().name + "'/>"; + row[2] = "<input data='" + entry.getFilename() + "' name='overlayDescription' value='" + entry.getData().description + "'/>"; + data.push(row); + } + } + dataTable.clear().rows.add(data).draw(); + }); + return result; }; @@ -321,17 +381,142 @@ AddProjectDialog.prototype.createSubmapsTab = function (tabMenuDiv, tabContentDi self.addTab({ tabMenuDiv: tabMenuDiv, tabContentDiv: tabContentDiv, - name: "USERS", + name: "SUBMAPS", id: "project_submaps_tab", content: self.createSubmapsTabContent() }); }; AddProjectDialog.prototype.createSubmapsTabContent = function () { + var self = this; var result = Functions.createElement({ type: "div", style: "margin-top:10px;" }); + var submapsTable = Functions.createElement({ + type: "table", + name: "submapsTable", + className: "display", + style: "width:100%" + }); + result.appendChild(submapsTable); + + $(submapsTable).DataTable({ + columns: [{ + title: 'File name' + }, { + title: 'Name' + }, { + title: 'Root map' + }, { + title: 'Mapping file' + }, { + title: 'Map type' + }] + }); + + $(submapsTable).on("input", "[name='submapName']", function () { + var input = this; + var filename = $(input).attr("data"); + self.getEntryByFilename(filename).getData().name = $(input).val(); + }); + + $(submapsTable).on("change", "[name='submapRoot']", function () { + var input = this; + if (!$(input).is(":checked")) { + this.checked = true; + GuiConnector.info("One model must be marked as a root"); + return false; + } + + var filename = $(input).attr("data"); + var checkboxes = $("[name='submapRoot']", submapsTable); + for (var i = 0; i < checkboxes.length; i++) { + var checkbox = checkboxes[i]; + if ($(checkbox).attr("data") !== filename) { + $(checkbox).attr('checked', false); + self.getEntryByFilename($(checkbox).attr("data")).getData().root = false; + } + } + self.getEntryByFilename(filename).getData().root = $(input).is(":checked"); + }); + + $(submapsTable).on("change", "[name='submapMapping']", function () { + var input = this; + var filename = $(input).attr("data"); + var checkboxes = $("[name='submapMapping']", submapsTable); + for (var i = 0; i < checkboxes.length; i++) { + var checkbox = checkboxes[i]; + if ($(checkbox).attr("data") !== filename) { + $(checkbox).attr('checked', false); + self.getEntryByFilename($(checkbox).attr("data")).getData().mapping = false; + } + } + self.getEntryByFilename(filename).getData().mapping = $(input).is(":checked"); + }); + + $(submapsTable).on("change", "[name='submapType']", function () { + var input = this; + var filename = $(input).attr("data"); + return ServerConnector.getConfiguration().then(function (configuration) { + var mapTypes = configuration.getMapTypes(); + for (var j = 0; j < mapTypes.length; j++) { + var mapType = mapTypes[j]; + if (mapType.id === $(input).val()) { + self.getEntryByFilename(filename).getData().type = mapType; + } + } + }); + }); + + self.addListener("onZipFileUpload", function () { + return ServerConnector.getConfiguration().then(function (configuration) { + + var entries = self.getZipEntries(); + var dataTable = $($("[name='submapsTable']", self.getElement())[0]).DataTable(); + var data = []; + for (var i = 0; i < entries.length; i++) { + var entry = entries[i]; + if (entry.getType() === "MAP") { + var row = []; + var rootCheckbox; + if (entry.getData().root) { + rootCheckbox = "<input name='submapRoot' type='checkbox' data='" + entry.getFilename() + "' checked='checked'/>"; + } else { + rootCheckbox = "<input name='submapRoot' type='checkbox' data='" + entry.getFilename() + "'/>"; + } + var mappingCheckbox; + if (entry.getData().mapping) { + mappingCheckbox = "<input name='submapMapping' type='checkbox' data='" + entry.getFilename() + "' checked='checked'/>"; + } else { + mappingCheckbox = "<input name='submapMapping' type='checkbox' data='" + entry.getFilename() + "'/>"; + } + + var typeSelect = "<select data='" + entry.getFilename() + "' name='submapType'>"; + + typeSelect += "<option value='" + entry.getData().type.id + "' selected>" + entry.getData().type.name + "</option>"; + var mapTypes = configuration.getMapTypes(); + for (var j = 0; j < mapTypes.length; j++) { + var mapType = mapTypes[j]; + if (mapType !== entry.getData().type) { + typeSelect += "<option value='" + mapType.id + "' >" + mapType.name + "</option>"; + } + } + typeSelect += "</select>"; + + + row[0] = entry.getFilename(); + row[1] = "<input data='" + entry.getFilename() + "' name='submapName' value='" + entry.getData().name + "'/>"; + row[2] = rootCheckbox; + row[3] = mappingCheckbox; + row[4] = typeSelect; + data.push(row); + } + } + dataTable.clear().rows.add(data).draw(); + }); + }); + return result; }; @@ -340,17 +525,48 @@ AddProjectDialog.prototype.createOverviewImagesTab = function (tabMenuDiv, tabCo self.addTab({ tabMenuDiv: tabMenuDiv, tabContentDiv: tabContentDiv, - name: "USERS", + name: "IMAGES", id: "project_overview_images_tab", content: self.createOverviewImagesTabContent() }); }; AddProjectDialog.prototype.createOverviewImagesTabContent = function () { + var self = this; var result = Functions.createElement({ type: "div", style: "margin-top:10px;" }); + + var imagesTable = Functions.createElement({ + type: "table", + name: "imagesTable", + className: "display", + style: "width:100%" + }); + result.appendChild(imagesTable); + + $(imagesTable).DataTable({ + columns: [{ + title: 'File name' + }] + }); + + self.addListener("onZipFileUpload", function () { + var entries = self.getZipEntries(); + var dataTable = $($("[name='imagesTable']", self.getElement())[0]).DataTable(); + var data = []; + for (var i = 0; i < entries.length; i++) { + var entry = entries[i]; + if (entry.getType() === "IMAGE") { + var row = []; + row[0] = entry.getFilename(); + data.push(row); + } + } + dataTable.clear().rows.add(data).draw(); + }); + return result; }; @@ -412,6 +628,20 @@ AddProjectDialog.prototype.destroy = function () { if (self._validatorsDialog !== undefined) { self._validatorsDialog.destroy(); } + var overlaysTable = $("[name=overlaysTable]", self.getElement())[0]; + if ($.fn.DataTable.isDataTable(overlaysTable)) { + $(overlaysTable).DataTable().destroy(); + } + var submapsTable = $("[name=submapsTable]", self.getElement())[0]; + if ($.fn.DataTable.isDataTable(submapsTable)) { + $(submapsTable).DataTable().destroy(); + } + + var imagesTable = $("[name=imagesTable]", self.getElement())[0]; + if ($.fn.DataTable.isDataTable(imagesTable)) { + $(imagesTable).DataTable().destroy(); + } + }; AddProjectDialog.prototype.open = function () { @@ -445,7 +675,7 @@ AddProjectDialog.prototype.processFile = function (file) { if (file) { return new Promise(function (resolve, reject) { var reader = new FileReader(); - reader.readAsText(file, "UTF-8"); + reader.readAsText(file); reader.onload = function (evt) { try { self.setFileContent(evt.target.result); @@ -464,6 +694,7 @@ AddProjectDialog.prototype.processFile = function (file) { }; AddProjectDialog.prototype.setFileContent = function (fileContent) { + logger.debug(fileContent); this._fileContent = fileContent; }; AddProjectDialog.prototype.getFileContent = function () { @@ -593,7 +824,7 @@ AddProjectDialog.prototype.onSaveClicked = function () { "semantic-zoom": self.isSemanticZooming(), "annotate": self.isAnnotateAutomatically(), "verify-annotations": self.isVerifyAnnotations(), - + "zip-entries": self.getZipEntries() }; return ServerConnector.addProject(options); }); @@ -627,4 +858,124 @@ AddProjectDialog.prototype.checkValidity = function () { }); }; +AddProjectDialog.prototype.setZipFileContent = function (file) { + var self = this; + if (file.name.toLowerCase().endsWith("zip")) { + var jsZip = new JSZip(); + return jsZip.loadAsync(file).then(function (zip) { + var files = zip.files; + var promises = []; + var entries = []; + for (var key in files) { + if (files.hasOwnProperty(key)) { + promises.push(self.createZipEntry(files[key], zip)); + } + } + return Promise.all(promises).then(function (result) { + for (var i = 0; i < result.length; i++) { + if (result[i] !== null) { + entries.push(result[i]); + } + } + return self.setZipEntries(entries); + }); + }); + } else { + return self.setZipEntries([]); + } +}; + +AddProjectDialog.prototype.createZipEntry = function (jsZipEntry, zipObject) { + if (jsZipEntry.dir) { + return null; + } + var filename = jsZipEntry.name.toLowerCase(); + var type = null; + var data = {}; + var processingPromise = Promise.resolve(); + if (filename.startsWith("submaps")) { + type = "MAP"; + if (filename.endsWith("mapping.xml")) { + data.mapping = true; + } + } else if (filename.startsWith("images")) { + type = "IMAGE"; + } else if (filename.startsWith("layouts") || filename.startsWith("overlays")) { + type = "OVERLAY"; + processingPromise = zipObject.file(jsZipEntry.name).async("string").then(function (content) { + var overlayParser = new OverlayParser(); + var overlay = overlayParser.parse(content); + if (overlay.getName()) { + data.name = overlay.getName(); + } else { + data.name = ""; + } + if (overlay.getDescription()) { + data.description = overlay.getDescription(); + } else { + data.description = ""; + } + }); + } else if (filename.indexOf("\\") === -1 && filename.indexOf("/") === -1) { + type = "MAP"; + data.root = true; + } else { + throw new Error("Unrecognized file: " + filename); + } + if (type === "MAP") { + var name = jsZipEntry.name.toLowerCase(); + this.setFileParserForFilename(name); + if (name.indexOf(".") > 0) { + name = name.substr(0, name.indexOf(".")); + } + if (name.lastIndexOf("\\") >= 0) { + name = name.substr(name.lastIndexOf("\\") + 1); + } + if (name.lastIndexOf("/") >= 0) { + name = name.substr(name.lastIndexOf("/") + 1); + } + data.name = name; + + processingPromise = processingPromise.then(function () { + return ServerConnector.getConfiguration().then(function (configuration) { + var mapTypes = configuration.getMapTypes(); + for (var i = 0; i < mapTypes.length; i++) { + if (mapTypes[i].id === "UNKNOWN") { + data.type = mapTypes[i]; + } + } + if (data.type === undefined) { + data.type = mapTypes[0]; + } + }); + }); + } + + return processingPromise.then(function () { + return new ZipEntry({filename: filename, type: type, data: data}); + }); +}; + +AddProjectDialog.prototype.getZipEntries = function () { + return this._zipEntries; +}; +AddProjectDialog.prototype.setZipEntries = function (entries) { + var self = this; + self._zipEntries = entries; + return self.callListeners("onZipFileUpload", entries); + +}; + +AddProjectDialog.prototype.getEntryByFilename = function (filename) { + var self = this; + var entries = self.getZipEntries(); + for (var i = 0; i < entries.length; i++) { + var entry = entries[i]; + if (entry.getFilename() === filename) { + return entry; + } + } + return null; +}; + module.exports = AddProjectDialog; diff --git a/frontend-js/src/main/js/gui/admin/ZipEntry.js b/frontend-js/src/main/js/gui/admin/ZipEntry.js new file mode 100644 index 0000000000000000000000000000000000000000..c3891a3a013e1b131353649c320471edd8671b7c --- /dev/null +++ b/frontend-js/src/main/js/gui/admin/ZipEntry.js @@ -0,0 +1,37 @@ +"use strict"; + +var types = ["IMAGE", "OVERLAY", "MAP"]; + +function ZipEntry(params) { + var self = this; + self.setType(params.type); + self.setFilename(params.filename); + self.setData(params.data); +} + +ZipEntry.prototype.setType = function (type) { + if (types.indexOf(type) === -1) { + throw new Error("Unknown ZipEntryType: " + type + ".") + } + this._type = type; +}; +ZipEntry.prototype.getType = function () { + return this._type; +}; + +ZipEntry.prototype.setFilename = function (filename) { + this._filename = filename; +}; + +ZipEntry.prototype.getFilename = function () { + return this._filename; +}; + +ZipEntry.prototype.setData = function (data) { + this._data = data; +}; +ZipEntry.prototype.getData = function () { + return this._data; +}; + +module.exports = ZipEntry; diff --git a/frontend-js/src/main/js/map/OverlayParser.js b/frontend-js/src/main/js/map/OverlayParser.js new file mode 100644 index 0000000000000000000000000000000000000000..31fc9bc086d2884189449f5c1b9c4bacc07d1e2c --- /dev/null +++ b/frontend-js/src/main/js/map/OverlayParser.js @@ -0,0 +1,37 @@ +"use strict"; + +var logger = require('./../logger'); +var LayoutData = require('./data/LayoutData'); + +function OverlayParser() { +} + +OverlayParser.prototype.parse = function (content) { + var data = {content: content}; + var lines = content.split("\n"); + for (var i = 0; i < lines.length; i++) { + var line = lines[i]; + if (line.startsWith("#")) { + if (line.indexOf("=") > 0) { + var name = line.substring(1, line.indexOf("=")).trim(); + var value = line.substring(line.indexOf("=") + 1).trim(); + if (name === "NAME") { + data.name = value; + } else if (name === "DESCRIPTION") { + data.description = value; + } else if (name === "TYPE") { + data.type = value; + } + } else { + logger.warn("Invalid overlay header line: " + line); + } + } else { + break; + } + } + + return new LayoutData(data); +}; + + +module.exports = OverlayParser; diff --git a/frontend-js/src/main/js/map/data/LayoutData.js b/frontend-js/src/main/js/map/data/LayoutData.js index 8d8c29ba94f124cee4f4eb3394a0a187c4492e94..2e2fa6d043921a6775537c2e2c06d08dec809113 100644 --- a/frontend-js/src/main/js/map/data/LayoutData.js +++ b/frontend-js/src/main/js/map/data/LayoutData.js @@ -27,6 +27,7 @@ function LayoutData(layoutId, name) { this.setFilename(object.filename); this.setPublicOverlay(object.publicOverlay); this.setInputDataAvailable(object.inputDataAvailable); + this.setType(object.type); if (!this.getInputDataAvailable()) { this.setInitialized(true); } @@ -42,54 +43,54 @@ function LayoutData(layoutId, name) { /** * Adds alias to the {@link LayoutData} - * + * * @param layoutAlias * information about alias in a layout */ -LayoutData.prototype.addAlias = function(layoutAlias) { +LayoutData.prototype.addAlias = function (layoutAlias) { this.aliases.push(layoutAlias); this.aliasById[layoutAlias.getId()] = layoutAlias; }; /** * Adds reaction to the {@link LayoutData} - * + * * @param layoutReaction * information about reaction in a layout */ -LayoutData.prototype.addReaction = function(layoutReaction) { +LayoutData.prototype.addReaction = function (layoutReaction) { this.reactions.push(layoutReaction); }; -LayoutData.prototype.getId = function() { +LayoutData.prototype.getId = function () { return this.id; }; -LayoutData.prototype.setId = function(id) { +LayoutData.prototype.setId = function (id) { this.id = parseInt(id); }; -LayoutData.prototype.getDescription = function() { +LayoutData.prototype.getDescription = function () { return this._description; }; -LayoutData.prototype.setDescription = function(description) { +LayoutData.prototype.setDescription = function (description) { this._description = description; }; -LayoutData.prototype.getCreator = function() { +LayoutData.prototype.getCreator = function () { return this._creator; }; -LayoutData.prototype.setCreator = function(creator) { +LayoutData.prototype.setCreator = function (creator) { this._creator = creator; }; -LayoutData.prototype.getInputDataAvailable = function() { +LayoutData.prototype.getInputDataAvailable = function () { return this._inputDataAvailable; }; -LayoutData.prototype.setInputDataAvailable = function(inputDataAvailable) { +LayoutData.prototype.setInputDataAvailable = function (inputDataAvailable) { var value = inputDataAvailable; if (inputDataAvailable === undefined) { value = false; @@ -104,23 +105,23 @@ LayoutData.prototype.setInputDataAvailable = function(inputDataAvailable) { this._inputDataAvailable = value; }; -LayoutData.prototype.getName = function() { +LayoutData.prototype.getName = function () { return this.name; }; -LayoutData.prototype.setName = function(name) { +LayoutData.prototype.setName = function (name) { this.name = name; }; -LayoutData.prototype.getDirectory = function() { +LayoutData.prototype.getDirectory = function () { return this._directory; }; -LayoutData.prototype.setDirectory = function(directory) { +LayoutData.prototype.setDirectory = function (directory) { this._directory = directory; }; -LayoutData.prototype.updateAlias = function(layoutAlias) { +LayoutData.prototype.updateAlias = function (layoutAlias) { if (this.aliasById[layoutAlias.getId()] === undefined) { logger.warn("Cannot update alias, it doesn't exist. Alias: ", layoutAlias.getId()); } else { @@ -129,19 +130,19 @@ LayoutData.prototype.updateAlias = function(layoutAlias) { }; -LayoutData.prototype.getAliasById = function(id) { +LayoutData.prototype.getAliasById = function (id) { return this.aliasById[id]; }; -LayoutData.prototype.getFullAliasById = function(id) { +LayoutData.prototype.getFullAliasById = function (id) { var self = this; var alias = self.getAliasById(id); if (alias !== undefined) { if (alias.getType() === LayoutAlias.LIGTH) { return ServerConnector.getFullOverlayElement({ - element : new IdentifiedElement(alias), - overlay : self, - }).then(function(data) { + element: new IdentifiedElement(alias), + overlay: self, + }).then(function (data) { self.updateAlias(data); return alias; }); @@ -150,28 +151,28 @@ LayoutData.prototype.getFullAliasById = function(id) { return Promise.resolve(alias); }; -LayoutData.prototype.setInitialized = function(value) { +LayoutData.prototype.setInitialized = function (value) { this._initialized = value; }; -LayoutData.prototype.isInitialized = function() { +LayoutData.prototype.isInitialized = function () { return this._initialized; }; -LayoutData.prototype.getAliases = function() { +LayoutData.prototype.getAliases = function () { return this.aliases; }; -LayoutData.prototype.getReactions = function() { +LayoutData.prototype.getReactions = function () { return this.reactions; }; -LayoutData.prototype.init = function() { +LayoutData.prototype.init = function () { var self = this; if (this.isInitialized()) { return Promise.resolve(); } - return ServerConnector.getOverlayElements(self.getId()).then(function(data) { + return ServerConnector.getOverlayElements(self.getId()).then(function (data) { for (var i = 0; i < data.length; i++) { if (data[i] instanceof LayoutAlias) { self.addAlias(data[i]); @@ -187,28 +188,36 @@ LayoutData.prototype.init = function() { }; -LayoutData.prototype.getPublicOverlay = function() { +LayoutData.prototype.getPublicOverlay = function () { return this._publicOverlay; }; -LayoutData.prototype.setPublicOverlay = function(publicOverlay) { +LayoutData.prototype.setPublicOverlay = function (publicOverlay) { this._publicOverlay = publicOverlay; }; -LayoutData.prototype.getContent = function() { +LayoutData.prototype.getContent = function () { return this._content; }; -LayoutData.prototype.setContent = function(content) { +LayoutData.prototype.setContent = function (content) { this._content = content; }; -LayoutData.prototype.getFilename = function() { +LayoutData.prototype.getFilename = function () { return this._filename; }; -LayoutData.prototype.setFilename= function(filename) { +LayoutData.prototype.setFilename = function (filename) { this._filename = filename; }; +LayoutData.prototype.getType = function () { + return this._type; +}; + +LayoutData.prototype.setType = function (type) { + this._type = type; +}; + module.exports = LayoutData; diff --git a/frontend-js/src/test/js/gui/AddOverlayDialog-test.js b/frontend-js/src/test/js/gui/AddOverlayDialog-test.js index b9700d844df392ad345f93cc76c5bc4b49060e01..26b190671ff0b2a9a19e5d807e1f8ad46559dbc6 100644 --- a/frontend-js/src/test/js/gui/AddOverlayDialog-test.js +++ b/frontend-js/src/test/js/gui/AddOverlayDialog-test.js @@ -12,23 +12,6 @@ var logger = require('../logger'); describe('AddOverlayDialog', function() { - describe('processFile', function() { - it('default', function() { - return ServerConnector.getProject().then(function(project) { - var dialog = new AddOverlayDialog({ - element : testDiv, - project : project, - customMap : null - }); - - var file = new Blob([ "#DESCRIPTION=xxx\nname\tvalue\ns1\t1" ]); - return dialog.processFile(file).then(function(content) { - assert.ok(content !== null); - }); - }); - }); - }); - it('addOverlay', function() { var dialog; return ServerConnector.getProject().then(function(project) { @@ -43,22 +26,4 @@ describe('AddOverlayDialog', function() { }); }); - - it('parse overlay file', function() { - return ServerConnector.getProject().then(function(project) { - var dialog = new AddOverlayDialog({ - element : testDiv, - project : project, - customMap : null - }); - - return ServerConnector.sendGetRequest("testFiles/overlay/good.txt").then(function(fileContent) { - var obj = dialog.parseFile(fileContent); - assert.equal(obj.name, "example name"); - assert.equal(obj.description, "layout description"); - assert.equal(obj.type, "GENERIC"); - }); - }); - }); - }); diff --git a/frontend-js/src/test/js/gui/admin/AddProjectDialog-test.js b/frontend-js/src/test/js/gui/admin/AddProjectDialog-test.js index 50d53689717e43f64af90a583f190e09f7f2ba0d..219804ccf82bbf0ebbaabdd3a1e6310c06c6a63f 100644 --- a/frontend-js/src/test/js/gui/admin/AddProjectDialog-test.js +++ b/frontend-js/src/test/js/gui/admin/AddProjectDialog-test.js @@ -7,6 +7,7 @@ require("../../mocha-config"); var AddProjectDialog = require('../../../../main/js/gui/admin/AddProjectDialog'); var logger = require('../../logger'); +var fs = require("fs"); var chai = require('chai'); var assert = chai.assert; @@ -20,6 +21,7 @@ describe('AddProjectDialog', function () { return dialog.init(); }).then(function () { assert.ok(dialog.getNotifyEmail() !== ""); + return dialog.destroy(); }); }); @@ -35,6 +37,7 @@ describe('AddProjectDialog', function () { assert.notOk(dialog.isCache()); dialog.setCache(true); assert.ok(dialog.isCache()); + return dialog.destroy(); }); }); @@ -55,6 +58,41 @@ describe('AddProjectDialog', function () { return dialog.getConverter(); }).then(function (converter) { assert.equal("xml", converter.extension); + return dialog.destroy(); + }); + }); + }); + + describe('setZipFileContent', function () { + it('submaps', function () { + var dialog = new AddProjectDialog({ + element: testDiv, + customMap: null + }); + var buf = fs.readFileSync("testFiles/map/complex_model_with_submaps.zip"); + buf.name = "complex_model_with_submaps.zip"; + return dialog.init().then(function () { + return dialog.setZipFileContent(buf); + }).then(function () { + assert.equal(5, dialog.getZipEntries().length); + return dialog.destroy(); + }); + }); + it('overlays', function () { + var dialog = new AddProjectDialog({ + element: testDiv, + customMap: null + }); + var buf = fs.readFileSync("testFiles/map/complex_model_with_overlays.zip"); + buf.name = "complex_model_with_overlays.zip"; + return dialog.init().then(function () { + var dataTable = $($("[name='overlaysTable']", testDiv)[0]).DataTable(); + assert.equal(0, dataTable.data().count()); + return dialog.setZipFileContent(buf); + }).then(function () { + var dataTable = $($("[name='overlaysTable']", testDiv)[0]).DataTable(); + assert.ok(dataTable.data().count() > 0); + return dialog.destroy(); }); }); }); @@ -67,7 +105,7 @@ describe('AddProjectDialog', function () { }); return dialog.showAnnotatorsDialog().then(function () { - dialog.destroy(); + return dialog.destroy(); }); }); }); @@ -110,6 +148,7 @@ describe('AddProjectDialog', function () { assert.ok(options["organism"] !== undefined); assert.ok(options["sbgn"] !== undefined); assert.ok(options["semantic-zoom"] !== undefined); + return dialog.destroy(); }); }); }); diff --git a/frontend-js/src/test/js/map/OverlayParser-test.js b/frontend-js/src/test/js/map/OverlayParser-test.js new file mode 100644 index 0000000000000000000000000000000000000000..b3a0f0ae080204da617af2e331435a316882c07a --- /dev/null +++ b/frontend-js/src/test/js/map/OverlayParser-test.js @@ -0,0 +1,33 @@ +"use strict"; + +require("../mocha-config.js"); + +var OverlayParser = require('../../../main/js/map/OverlayParser'); +var chai = require('chai'); +var assert = chai.assert; + +describe('OverlayParser', function () { + describe('parse', function () { + it('simple', function () { + var parser = new OverlayParser(); + var fileContent = "#NAME=some Name\n#DESCRIPTION=xxx\nname\tvalue\ns1\t1"; + + var overlay = parser.parse(fileContent); + assert.ok(overlay); + assert.equal(overlay.getDescription(), "xxx"); + assert.equal(overlay.getName(), "some Name"); + assert.ok(overlay.getContent()); + }); + it('with type', function () { + + return ServerConnector.sendGetRequest("testFiles/overlay/good.txt").then(function (fileContent) { + var parser = new OverlayParser(); + var overlay = parser.parse(fileContent); + assert.equal(overlay.getName(), "example name"); + assert.equal(overlay.getDescription(), "layout description"); + assert.equal(overlay.getType(), "GENERIC"); + }); + }); + }); + +}); diff --git a/frontend-js/testFiles/apiCalls/configuration/token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/configuration/token=MOCK_TOKEN_ID& index 87bada811f18fa43905db6a71d4b83047d186854..38618b8344d16fc18518b9dfd5cda7551f015063 100644 --- a/frontend-js/testFiles/apiCalls/configuration/token=MOCK_TOKEN_ID& +++ b/frontend-js/testFiles/apiCalls/configuration/token=MOCK_TOKEN_ID& @@ -1 +1 @@ -{"modelFormats":[{"handler":"lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser","extension":"xml","name":"CellDesigner SBML"},{"handler":"lcsb.mapviewer.converter.model.sbgnml.SbgnmlXmlConverter","extension":"sbgn","name":"SBGN-ML"}],"elementTypes":[{"name":"Degraded","className":"lcsb.mapviewer.model.map.species.Degraded","parentClass":"lcsb.mapviewer.model.map.species.Species"},{"name":"Compartment","className":"lcsb.mapviewer.model.map.compartment.LeftSquareCompartment","parentClass":"lcsb.mapviewer.model.map.compartment.Compartment"},{"name":"Protein","className":"lcsb.mapviewer.model.map.species.IonChannelProtein","parentClass":"lcsb.mapviewer.model.map.species.Protein"},{"name":"Compartment","className":"lcsb.mapviewer.model.map.compartment.TopSquareCompartment","parentClass":"lcsb.mapviewer.model.map.compartment.Compartment"},{"name":"Ion","className":"lcsb.mapviewer.model.map.species.Ion","parentClass":"lcsb.mapviewer.model.map.species.Chemical"},{"name":"Species","className":"lcsb.mapviewer.model.map.species.Species","parentClass":"lcsb.mapviewer.model.map.species.Element"},{"name":"Compartment","className":"lcsb.mapviewer.model.map.compartment.RightSquareCompartment","parentClass":"lcsb.mapviewer.model.map.compartment.Compartment"},{"name":"Drug","className":"lcsb.mapviewer.model.map.species.Drug","parentClass":"lcsb.mapviewer.model.map.species.Species"},{"name":"Protein","className":"lcsb.mapviewer.model.map.species.Protein","parentClass":"lcsb.mapviewer.model.map.species.Species"},{"name":"Protein","className":"lcsb.mapviewer.model.map.species.TruncatedProtein","parentClass":"lcsb.mapviewer.model.map.species.Protein"},{"name":"Compartment","className":"lcsb.mapviewer.model.map.compartment.PathwayCompartment","parentClass":"lcsb.mapviewer.model.map.compartment.Compartment"},{"name":"Compartment","className":"lcsb.mapviewer.model.map.compartment.BottomSquareCompartment","parentClass":"lcsb.mapviewer.model.map.compartment.Compartment"},{"name":"RNA","className":"lcsb.mapviewer.model.map.species.Rna","parentClass":"lcsb.mapviewer.model.map.species.Species"},{"name":"Chemical","className":"lcsb.mapviewer.model.map.species.Chemical","parentClass":"lcsb.mapviewer.model.map.species.Species"},{"name":"Compartment","className":"lcsb.mapviewer.model.map.compartment.Compartment","parentClass":"lcsb.mapviewer.model.map.species.Element"},{"name":"Compartment","className":"lcsb.mapviewer.model.map.compartment.OvalCompartment","parentClass":"lcsb.mapviewer.model.map.compartment.Compartment"},{"name":"Compartment","className":"lcsb.mapviewer.model.map.compartment.SquareCompartment","parentClass":"lcsb.mapviewer.model.map.compartment.Compartment"},{"name":"Unknown","className":"lcsb.mapviewer.model.map.species.Unknown","parentClass":"lcsb.mapviewer.model.map.species.Species"},{"name":"Element","className":"lcsb.mapviewer.model.map.species.Element","parentClass":"lcsb.mapviewer.model.map.BioEntity"},{"name":"Phenotype","className":"lcsb.mapviewer.model.map.species.Phenotype","parentClass":"lcsb.mapviewer.model.map.species.Species"},{"name":"Complex","className":"lcsb.mapviewer.model.map.species.Complex","parentClass":"lcsb.mapviewer.model.map.species.Species"},{"name":"Antisense RNA","className":"lcsb.mapviewer.model.map.species.AntisenseRna","parentClass":"lcsb.mapviewer.model.map.species.Species"},{"name":"Protein","className":"lcsb.mapviewer.model.map.species.ReceptorProtein","parentClass":"lcsb.mapviewer.model.map.species.Protein"},{"name":"Simple molecule","className":"lcsb.mapviewer.model.map.species.SimpleMolecule","parentClass":"lcsb.mapviewer.model.map.species.Chemical"},{"name":"Protein","className":"lcsb.mapviewer.model.map.species.GenericProtein","parentClass":"lcsb.mapviewer.model.map.species.Protein"},{"name":"Gene","className":"lcsb.mapviewer.model.map.species.Gene","parentClass":"lcsb.mapviewer.model.map.species.Species"}],"modificationStateTypes":{"PHOSPHORYLATED":{"commonName":"phosphorylated","abbreviation":"P"},"METHYLATED":{"commonName":"methylated","abbreviation":"Me"},"PALMYTOYLATED":{"commonName":"palmytoylated","abbreviation":"Pa"},"ACETYLATED":{"commonName":"acetylated","abbreviation":"Ac"},"SULFATED":{"commonName":"sulfated","abbreviation":"S"},"GLYCOSYLATED":{"commonName":"glycosylated","abbreviation":"G"},"PRENYLATED":{"commonName":"prenylated","abbreviation":"Pr"},"UBIQUITINATED":{"commonName":"ubiquitinated","abbreviation":"Ub"},"PROTONATED":{"commonName":"protonated","abbreviation":"H"},"HYDROXYLATED":{"commonName":"hydroxylated","abbreviation":"OH"},"MYRISTOYLATED":{"commonName":"myristoylated","abbreviation":"My"},"UNKNOWN":{"commonName":"unknown","abbreviation":"?"},"EMPTY":{"commonName":"empty","abbreviation":""},"DONT_CARE":{"commonName":"don't care","abbreviation":"*"}},"miriamTypes":{"CHEMBL_TARGET":{"commonName":"ChEMBL target","uris":["urn:miriam:chembl.target"],"homepage":"https://www.ebi.ac.uk/chembldb/","registryIdentifier":"MIR:00000085"},"UNIPROT":{"commonName":"Uniprot","uris":["urn:miriam:uniprot"],"homepage":"http://www.uniprot.org/","registryIdentifier":"MIR:00000005"},"MI_R_BASE_MATURE_SEQUENCE":{"commonName":"miRBase Mature Sequence Database","uris":["urn:miriam:mirbase.mature"],"homepage":"http://www.mirbase.org/","registryIdentifier":"MIR:00000235"},"PFAM":{"commonName":"Protein Family Database","uris":["urn:miriam:pfam"],"homepage":"http://pfam.xfam.org//","registryIdentifier":"MIR:00000028"},"ENSEMBL_PLANTS":{"commonName":"Ensembl Plants","uris":["urn:miriam:ensembl.plant"],"homepage":"http://plants.ensembl.org/","registryIdentifier":"MIR:00000205"},"WIKIPEDIA":{"commonName":"Wikipedia (English)","uris":["urn:miriam:wikipedia.en"],"homepage":"http://en.wikipedia.org/wiki/Main_Page","registryIdentifier":"MIR:00000384"},"CHEBI":{"commonName":"Chebi","uris":["urn:miriam:obo.chebi","urn:miriam:chebi"],"homepage":"http://www.ebi.ac.uk/chebi/","registryIdentifier":"MIR:00000002"},"WIKIDATA":{"commonName":"Wikidata","uris":["urn:miriam:wikidata"],"homepage":"https://www.wikidata.org/","registryIdentifier":"MIR:00000549"},"REACTOME":{"commonName":"Reactome","uris":["urn:miriam:reactome"],"homepage":"http://www.reactome.org/","registryIdentifier":"MIR:00000018"},"EC":{"commonName":"Enzyme Nomenclature","uris":["urn:miriam:ec-code"],"homepage":"http://www.enzyme-database.org/","registryIdentifier":"MIR:00000004"},"UNIPROT_ISOFORM":{"commonName":"UniProt Isoform","uris":["urn:miriam:uniprot.isoform"],"homepage":"http://www.uniprot.org/","registryIdentifier":"MIR:00000388"},"OMIM":{"commonName":"Online Mendelian Inheritance in Man","uris":["urn:miriam:omim"],"homepage":"http://omim.org/","registryIdentifier":"MIR:00000016"},"DRUGBANK_TARGET_V4":{"commonName":"DrugBank Target v4","uris":["urn:miriam:drugbankv4.target"],"homepage":"http://www.drugbank.ca/targets","registryIdentifier":"MIR:00000528"},"MIR_TAR_BASE_MATURE_SEQUENCE":{"commonName":"miRTarBase Mature Sequence Database","uris":["urn:miriam:mirtarbase"],"homepage":"http://mirtarbase.mbc.nctu.edu.tw/","registryIdentifier":"MIR:00100739"},"CHEMBL_COMPOUND":{"commonName":"ChEMBL","uris":["urn:miriam:chembl.compound"],"homepage":"https://www.ebi.ac.uk/chembldb/","registryIdentifier":"MIR:00000084"},"KEGG_PATHWAY":{"commonName":"Kegg Pathway","uris":["urn:miriam:kegg.pathway"],"homepage":"http://www.genome.jp/kegg/pathway.html","registryIdentifier":"MIR:00000012"},"CAS":{"commonName":"Chemical Abstracts Service","uris":["urn:miriam:cas"],"homepage":"http://commonchemistry.org","registryIdentifier":"MIR:00000237"},"REFSEQ":{"commonName":"RefSeq","uris":["urn:miriam:refseq"],"homepage":"http://www.ncbi.nlm.nih.gov/projects/RefSeq/","registryIdentifier":"MIR:00000039"},"WORM_BASE":{"commonName":"WormBase","uris":["urn:miriam:wormbase"],"homepage":"http://wormbase.bio2rdf.org/fct","registryIdentifier":"MIR:00000027"},"MI_R_BASE_SEQUENCE":{"commonName":"miRBase Sequence Database","uris":["urn:miriam:mirbase"],"homepage":"http://www.mirbase.org/","registryIdentifier":"MIR:00000078"},"TAIR_LOCUS":{"commonName":"TAIR Locus","uris":["urn:miriam:tair.locus"],"homepage":"http://arabidopsis.org/index.jsp","registryIdentifier":"MIR:00000050"},"PHARM":{"commonName":"PharmGKB Pathways","uris":["urn:miriam:pharmgkb.pathways"],"homepage":"http://www.pharmgkb.org/","registryIdentifier":"MIR:00000089"},"PANTHER":{"commonName":"PANTHER Family","uris":["urn:miriam:panther.family","urn:miriam:panther"],"homepage":"http://www.pantherdb.org/","registryIdentifier":"MIR:00000060"},"TAXONOMY":{"commonName":"Taxonomy","uris":["urn:miriam:taxonomy"],"homepage":"http://www.ncbi.nlm.nih.gov/taxonomy/","registryIdentifier":"MIR:00000006"},"UNIGENE":{"commonName":"UniGene","uris":["urn:miriam:unigene"],"homepage":"http://www.ncbi.nlm.nih.gov/unigene","registryIdentifier":"MIR:00000346"},"HGNC":{"commonName":"HGNC","uris":["urn:miriam:hgnc"],"homepage":"http://www.genenames.org","registryIdentifier":"MIR:00000080"},"HGNC_SYMBOL":{"commonName":"HGNC Symbol","uris":["urn:miriam:hgnc.symbol"],"homepage":"http://www.genenames.org","registryIdentifier":"MIR:00000362"},"COG":{"commonName":"Clusters of Orthologous Groups","uris":["urn:miriam:cogs"],"homepage":"https://www.ncbi.nlm.nih.gov/COG/","registryIdentifier":"MIR:00000296"},"WIKIPATHWAYS":{"commonName":"WikiPathways","uris":["urn:miriam:wikipathways"],"homepage":"http://www.wikipathways.org/","registryIdentifier":"MIR:00000076"},"HMDB":{"commonName":"HMDB","uris":["urn:miriam:hmdb"],"homepage":"http://www.hmdb.ca/","registryIdentifier":"MIR:00000051"},"CHEMSPIDER":{"commonName":"ChemSpider","uris":["urn:miriam:chemspider"],"homepage":"http://www.chemspider.com//","registryIdentifier":"MIR:00000138"},"ENSEMBL":{"commonName":"Ensembl","uris":["urn:miriam:ensembl"],"homepage":"www.ensembl.org","registryIdentifier":"MIR:00000003"},"GO":{"commonName":"Gene Ontology","uris":["urn:miriam:obo.go","urn:miriam:go"],"homepage":"http://amigo.geneontology.org/amigo","registryIdentifier":"MIR:00000022"},"KEGG_REACTION":{"commonName":"Kegg Reaction","uris":["urn:miriam:kegg.reaction"],"homepage":"http://www.genome.jp/kegg/reaction/","registryIdentifier":"MIR:00000014"},"KEGG_ORTHOLOGY":{"commonName":"KEGG Orthology","uris":["urn:miriam:kegg.orthology"],"homepage":"http://www.genome.jp/kegg/ko.html","registryIdentifier":"MIR:00000116"},"PUBCHEM":{"commonName":"PubChem-compound","uris":["urn:miriam:pubchem.compound"],"homepage":"http://pubchem.ncbi.nlm.nih.gov/","registryIdentifier":"MIR:00000034"},"MESH_2012":{"commonName":"MeSH 2012","uris":["urn:miriam:mesh.2012","urn:miriam:mesh"],"homepage":"http://www.nlm.nih.gov/mesh/","registryIdentifier":"MIR:00000270"},"MGD":{"commonName":"Mouse Genome Database","uris":["urn:miriam:mgd"],"homepage":"http://www.informatics.jax.org/","registryIdentifier":"MIR:00000037"},"ENTREZ":{"commonName":"Entrez Gene","uris":["urn:miriam:ncbigene","urn:miriam:entrez.gene"],"homepage":"http://www.ncbi.nlm.nih.gov/gene","registryIdentifier":"MIR:00000069"},"PUBCHEM_SUBSTANCE":{"commonName":"PubChem-substance","uris":["urn:miriam:pubchem.substance"],"homepage":"http://pubchem.ncbi.nlm.nih.gov/","registryIdentifier":"MIR:00000033"},"CCDS":{"commonName":"Consensus CDS","uris":["urn:miriam:ccds"],"homepage":"http://www.ncbi.nlm.nih.gov/CCDS/","registryIdentifier":"MIR:00000375"},"KEGG_GENES":{"commonName":"Kegg Genes","uris":["urn:miriam:kegg.genes","urn:miriam:kegg.genes:hsa"],"homepage":"http://www.genome.jp/kegg/genes.html","registryIdentifier":"MIR:00000070"},"TOXICOGENOMIC_CHEMICAL":{"commonName":"Toxicogenomic Chemical","uris":["urn:miriam:ctd.chemical"],"homepage":"http://ctdbase.org/","registryIdentifier":"MIR:00000098"},"SGD":{"commonName":"Saccharomyces Genome Database","uris":["urn:miriam:sgd"],"homepage":"http://www.yeastgenome.org/","registryIdentifier":"MIR:00000023"},"KEGG_COMPOUND":{"commonName":"Kegg Compound","uris":["urn:miriam:kegg.compound"],"homepage":"http://www.genome.jp/kegg/ligand.html","registryIdentifier":"MIR:00000013"},"INTERPRO":{"commonName":"InterPro","uris":["urn:miriam:interpro"],"homepage":"http://www.ebi.ac.uk/interpro/","registryIdentifier":"MIR:00000011"},"UNKNOWN":{"commonName":"Unknown","uris":[],"homepage":null,"registryIdentifier":null},"DRUGBANK":{"commonName":"DrugBank","uris":["urn:miriam:drugbank"],"homepage":"http://www.drugbank.ca/","registryIdentifier":"MIR:00000102"},"PUBMED":{"commonName":"PubMed","uris":["urn:miriam:pubmed"],"homepage":"http://www.ncbi.nlm.nih.gov/PubMed/","registryIdentifier":"MIR:00000015"}},"imageFormats":[{"handler":"lcsb.mapviewer.converter.graphics.PngImageGenerator","extension":"png","name":"PNG image"},{"handler":"lcsb.mapviewer.converter.graphics.PdfImageGenerator","extension":"pdf","name":"PDF"},{"handler":"lcsb.mapviewer.converter.graphics.SvgImageGenerator","extension":"svg","name":"SVG image"}],"annotators":[{"name":"Biocompendium","className":"lcsb.mapviewer.annotation.services.annotators.BiocompendiumAnnotator","elementClassNames":["lcsb.mapviewer.model.map.species.Protein","lcsb.mapviewer.model.map.species.Protein","lcsb.mapviewer.model.map.species.Protein"],"url":"http://biocompendium.embl.de/"},{"name":"Chebi","className":"lcsb.mapviewer.annotation.services.annotators.ChebiAnnotator","elementClassNames":["lcsb.mapviewer.model.map.species.Chemical"],"url":"http://www.ebi.ac.uk/chebi/"},{"name":"Uniprot","className":"lcsb.mapviewer.annotation.services.annotators.UniprotAnnotator","elementClassNames":["lcsb.mapviewer.model.map.species.Protein","lcsb.mapviewer.model.map.species.Gene","lcsb.mapviewer.model.map.species.Rna"],"url":"http://www.uniprot.org/"},{"name":"Gene Ontology","className":"lcsb.mapviewer.annotation.services.annotators.GoAnnotator","elementClassNames":["lcsb.mapviewer.model.map.species.Phenotype","lcsb.mapviewer.model.map.compartment.Compartment","lcsb.mapviewer.model.map.species.Complex"],"url":"http://amigo.geneontology.org/amigo"},{"name":"HGNC","className":"lcsb.mapviewer.annotation.services.annotators.HgncAnnotator","elementClassNames":["lcsb.mapviewer.model.map.species.Protein","lcsb.mapviewer.model.map.species.Rna","lcsb.mapviewer.model.map.species.Gene"],"url":"http://www.genenames.org"},{"name":"Recon annotator","className":"lcsb.mapviewer.annotation.services.annotators.ReconAnnotator","elementClassNames":["lcsb.mapviewer.model.map.species.Chemical","lcsb.mapviewer.model.map.reaction.Reaction"],"url":"http://humanmetabolism.org/"},{"name":"Entrez Gene","className":"lcsb.mapviewer.annotation.services.annotators.EntrezAnnotator","elementClassNames":["lcsb.mapviewer.model.map.species.Protein","lcsb.mapviewer.model.map.species.Rna","lcsb.mapviewer.model.map.species.Gene"],"url":"http://www.ncbi.nlm.nih.gov/gene"},{"name":"Ensembl","className":"lcsb.mapviewer.annotation.services.annotators.EnsemblAnnotator","elementClassNames":["lcsb.mapviewer.model.map.species.Protein","lcsb.mapviewer.model.map.species.Rna","lcsb.mapviewer.model.map.species.Gene"],"url":"www.ensembl.org"}],"options":[{"idObject":9,"type":"EMAIL_ADDRESS","value":"your.account@domain.com"},{"idObject":10,"type":"EMAIL_LOGIN","value":"your@login"},{"idObject":11,"type":"EMAIL_PASSWORD","value":"email.secret.password"},{"idObject":13,"type":"EMAIL_IMAP_SERVER","value":"your.imap.domain.com"},{"idObject":12,"type":"EMAIL_SMTP_SERVER","value":"your.smtp.domain.com"},{"idObject":14,"type":"EMAIL_SMTP_PORT","value":"25"},{"idObject":6,"type":"DEFAULT_MAP","value":"sample"},{"idObject":4,"type":"LOGO_IMG","value":"udl.png"},{"idObject":3,"type":"LOGO_LINK","value":"http://wwwen.uni.lu/"},{"idObject":7,"type":"SEARCH_DISTANCE","value":"10"},{"idObject":1,"type":"REQUEST_ACCOUNT_EMAIL","value":"your.email@domain.com"},{"idObject":8,"type":"SEARCH_RESULT_NUMBER","value":"100"},{"idObject":2,"type":"GOOGLE_ANALYTICS_IDENTIFIER","value":""},{"idObject":5,"type":"LOGO_TEXT","value":"University of Luxembourg"},{"idObject":56,"type":"X_FRAME_DOMAIN","value":"http://localhost:8080/"},{"idObject":131,"type":"BIG_FILE_STORAGE_DIR","value":"minerva-big/"},{"idObject":138,"type":"LEGEND_FILE_1","value":"resources/images/legend_a.png"},{"idObject":139,"type":"LEGEND_FILE_2","value":"resources/images/legend_b.png"},{"idObject":140,"type":"LEGEND_FILE_3","value":"resources/images/legend_c.png"},{"idObject":141,"type":"LEGEND_FILE_4","value":"resources/images/legend_d.png"},{"idObject":142,"type":"USER_MANUAL_FILE","value":"resources/other/user_guide.pdf"},{"idObject":205,"type":"MIN_COLOR_VAL","value":"FF0000"},{"idObject":206,"type":"MAX_COLOR_VAL","value":"fbff00"},{"idObject":218,"type":"SIMPLE_COLOR_VAL","value":"00FF00"}],"privilegeTypes":{"VIEW_PROJECT":{"commonName":"View project","valueType":"boolean","objectType":"Project"},"LAYOUT_MANAGEMENT":{"commonName":"Manage layouts","valueType":"boolean","objectType":"Project"},"PROJECT_MANAGEMENT":{"commonName":"Map management","valueType":"boolean","objectType":null},"CUSTOM_LAYOUTS":{"commonName":"Custom layouts","valueType":"int","objectType":null},"ADD_MAP":{"commonName":"Add project","valueType":"boolean","objectType":null},"LAYOUT_VIEW":{"commonName":"View layout","valueType":"boolean","objectType":"Layout"},"MANAGE_GENOMES":{"commonName":"Manage genomes","valueType":"boolean","objectType":null},"EDIT_COMMENTS_PROJECT":{"commonName":"Manage comments","valueType":"boolean","objectType":"Project"},"CONFIGURATION_MANAGE":{"commonName":"Manage configuration","valueType":"boolean","objectType":null},"USER_MANAGEMENT":{"commonName":"User management","valueType":"boolean","objectType":null}},"overlayTypes":[{"name":"GENERIC"},{"name":"GENETIC_VARIANT"}],"buildDate":"30/08/2017 16:58","reactionTypes":[{"name":"Unknown positive influence","className":"lcsb.mapviewer.model.map.reaction.type.UnknownPositiveInfluenceReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Generic Reaction","className":"lcsb.mapviewer.model.map.reaction.Reaction","parentClass":"lcsb.mapviewer.model.map.BioEntity"},{"name":"Reduced physical stimulation","className":"lcsb.mapviewer.model.map.reaction.type.ReducedPhysicalStimulationReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Negative influence","className":"lcsb.mapviewer.model.map.reaction.type.NegativeInfluenceReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Known transition omitted","className":"lcsb.mapviewer.model.map.reaction.type.KnownTransitionOmittedReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Reduced modulation","className":"lcsb.mapviewer.model.map.reaction.type.ReducedModulationReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Translation","className":"lcsb.mapviewer.model.map.reaction.type.TranslationReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Heterodimer association","className":"lcsb.mapviewer.model.map.reaction.type.HeterodimerAssociationReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Transcription","className":"lcsb.mapviewer.model.map.reaction.type.TranscriptionReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Unknown reduced trigger","className":"lcsb.mapviewer.model.map.reaction.type.UnknownReducedTriggerReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Unknown negative influence","className":"lcsb.mapviewer.model.map.reaction.type.UnknownNegativeInfluenceReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Truncation","className":"lcsb.mapviewer.model.map.reaction.type.TruncationReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Transport","className":"lcsb.mapviewer.model.map.reaction.type.TransportReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Reduced trigger","className":"lcsb.mapviewer.model.map.reaction.type.ReducedTriggerReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"State transition","className":"lcsb.mapviewer.model.map.reaction.type.StateTransitionReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Positive influence","className":"lcsb.mapviewer.model.map.reaction.type.PositiveInfluenceReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Unknown reduced physical stimulation","className":"lcsb.mapviewer.model.map.reaction.type.UnknownReducedPhysicalStimulationReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Boolean logic gate","className":"lcsb.mapviewer.model.map.reaction.type.BooleanLogicGateReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Unknown reduced modulation","className":"lcsb.mapviewer.model.map.reaction.type.UnknownReducedModulationReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Unknown transition","className":"lcsb.mapviewer.model.map.reaction.type.UnknownTransitionReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Dissociation","className":"lcsb.mapviewer.model.map.reaction.type.DissociationReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"}],"version":"11.0.0"} \ No newline at end of file +{"modelFormats":[{"handler":"lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser","extension":"xml","name":"CellDesigner SBML"},{"handler":"lcsb.mapviewer.converter.model.sbgnml.SbgnmlXmlConverter","extension":"sbgn","name":"SBGN-ML"}],"elementTypes":[{"name":"Degraded","className":"lcsb.mapviewer.model.map.species.Degraded","parentClass":"lcsb.mapviewer.model.map.species.Species"},{"name":"Compartment","className":"lcsb.mapviewer.model.map.compartment.LeftSquareCompartment","parentClass":"lcsb.mapviewer.model.map.compartment.Compartment"},{"name":"Protein","className":"lcsb.mapviewer.model.map.species.IonChannelProtein","parentClass":"lcsb.mapviewer.model.map.species.Protein"},{"name":"Compartment","className":"lcsb.mapviewer.model.map.compartment.TopSquareCompartment","parentClass":"lcsb.mapviewer.model.map.compartment.Compartment"},{"name":"Ion","className":"lcsb.mapviewer.model.map.species.Ion","parentClass":"lcsb.mapviewer.model.map.species.Chemical"},{"name":"Species","className":"lcsb.mapviewer.model.map.species.Species","parentClass":"lcsb.mapviewer.model.map.species.Element"},{"name":"Compartment","className":"lcsb.mapviewer.model.map.compartment.RightSquareCompartment","parentClass":"lcsb.mapviewer.model.map.compartment.Compartment"},{"name":"Drug","className":"lcsb.mapviewer.model.map.species.Drug","parentClass":"lcsb.mapviewer.model.map.species.Species"},{"name":"Protein","className":"lcsb.mapviewer.model.map.species.Protein","parentClass":"lcsb.mapviewer.model.map.species.Species"},{"name":"Protein","className":"lcsb.mapviewer.model.map.species.TruncatedProtein","parentClass":"lcsb.mapviewer.model.map.species.Protein"},{"name":"Compartment","className":"lcsb.mapviewer.model.map.compartment.PathwayCompartment","parentClass":"lcsb.mapviewer.model.map.compartment.Compartment"},{"name":"Compartment","className":"lcsb.mapviewer.model.map.compartment.BottomSquareCompartment","parentClass":"lcsb.mapviewer.model.map.compartment.Compartment"},{"name":"RNA","className":"lcsb.mapviewer.model.map.species.Rna","parentClass":"lcsb.mapviewer.model.map.species.Species"},{"name":"Chemical","className":"lcsb.mapviewer.model.map.species.Chemical","parentClass":"lcsb.mapviewer.model.map.species.Species"},{"name":"Compartment","className":"lcsb.mapviewer.model.map.compartment.Compartment","parentClass":"lcsb.mapviewer.model.map.species.Element"},{"name":"Compartment","className":"lcsb.mapviewer.model.map.compartment.OvalCompartment","parentClass":"lcsb.mapviewer.model.map.compartment.Compartment"},{"name":"Compartment","className":"lcsb.mapviewer.model.map.compartment.SquareCompartment","parentClass":"lcsb.mapviewer.model.map.compartment.Compartment"},{"name":"Unknown","className":"lcsb.mapviewer.model.map.species.Unknown","parentClass":"lcsb.mapviewer.model.map.species.Species"},{"name":"Element","className":"lcsb.mapviewer.model.map.species.Element","parentClass":"lcsb.mapviewer.model.map.BioEntity"},{"name":"Phenotype","className":"lcsb.mapviewer.model.map.species.Phenotype","parentClass":"lcsb.mapviewer.model.map.species.Species"},{"name":"Complex","className":"lcsb.mapviewer.model.map.species.Complex","parentClass":"lcsb.mapviewer.model.map.species.Species"},{"name":"Antisense RNA","className":"lcsb.mapviewer.model.map.species.AntisenseRna","parentClass":"lcsb.mapviewer.model.map.species.Species"},{"name":"Protein","className":"lcsb.mapviewer.model.map.species.ReceptorProtein","parentClass":"lcsb.mapviewer.model.map.species.Protein"},{"name":"Simple molecule","className":"lcsb.mapviewer.model.map.species.SimpleMolecule","parentClass":"lcsb.mapviewer.model.map.species.Chemical"},{"name":"Protein","className":"lcsb.mapviewer.model.map.species.GenericProtein","parentClass":"lcsb.mapviewer.model.map.species.Protein"},{"name":"Gene","className":"lcsb.mapviewer.model.map.species.Gene","parentClass":"lcsb.mapviewer.model.map.species.Species"}],"modificationStateTypes":{"PHOSPHORYLATED":{"commonName":"phosphorylated","abbreviation":"P"},"METHYLATED":{"commonName":"methylated","abbreviation":"Me"},"PALMYTOYLATED":{"commonName":"palmytoylated","abbreviation":"Pa"},"ACETYLATED":{"commonName":"acetylated","abbreviation":"Ac"},"SULFATED":{"commonName":"sulfated","abbreviation":"S"},"GLYCOSYLATED":{"commonName":"glycosylated","abbreviation":"G"},"PRENYLATED":{"commonName":"prenylated","abbreviation":"Pr"},"UBIQUITINATED":{"commonName":"ubiquitinated","abbreviation":"Ub"},"PROTONATED":{"commonName":"protonated","abbreviation":"H"},"HYDROXYLATED":{"commonName":"hydroxylated","abbreviation":"OH"},"MYRISTOYLATED":{"commonName":"myristoylated","abbreviation":"My"},"UNKNOWN":{"commonName":"unknown","abbreviation":"?"},"EMPTY":{"commonName":"empty","abbreviation":""},"DONT_CARE":{"commonName":"don't care","abbreviation":"*"}},"imageFormats":[{"handler":"lcsb.mapviewer.converter.graphics.PngImageGenerator","extension":"png","name":"PNG image"},{"handler":"lcsb.mapviewer.converter.graphics.PdfImageGenerator","extension":"pdf","name":"PDF"},{"handler":"lcsb.mapviewer.converter.graphics.SvgImageGenerator","extension":"svg","name":"SVG image"}],"annotators":[{"name":"Biocompendium","className":"lcsb.mapviewer.annotation.services.annotators.BiocompendiumAnnotator","elementClassNames":["lcsb.mapviewer.model.map.species.Protein","lcsb.mapviewer.model.map.species.Gene","lcsb.mapviewer.model.map.species.Rna"],"url":"http://biocompendium.embl.de/"},{"name":"Chebi","className":"lcsb.mapviewer.annotation.services.annotators.ChebiAnnotator","elementClassNames":["lcsb.mapviewer.model.map.species.Chemical"],"url":"http://www.ebi.ac.uk/chebi/"},{"name":"Uniprot","className":"lcsb.mapviewer.annotation.services.annotators.UniprotAnnotator","elementClassNames":["lcsb.mapviewer.model.map.species.Protein","lcsb.mapviewer.model.map.species.Gene","lcsb.mapviewer.model.map.species.Rna"],"url":"http://www.uniprot.org/"},{"name":"Gene Ontology","className":"lcsb.mapviewer.annotation.services.annotators.GoAnnotator","elementClassNames":["lcsb.mapviewer.model.map.species.Phenotype","lcsb.mapviewer.model.map.compartment.Compartment","lcsb.mapviewer.model.map.species.Complex"],"url":"http://amigo.geneontology.org/amigo"},{"name":"HGNC","className":"lcsb.mapviewer.annotation.services.annotators.HgncAnnotator","elementClassNames":["lcsb.mapviewer.model.map.species.Protein","lcsb.mapviewer.model.map.species.Rna","lcsb.mapviewer.model.map.species.Gene"],"url":"http://www.genenames.org"},{"name":"Recon annotator","className":"lcsb.mapviewer.annotation.services.annotators.ReconAnnotator","elementClassNames":["lcsb.mapviewer.model.map.species.Chemical","lcsb.mapviewer.model.map.reaction.Reaction"],"url":"http://humanmetabolism.org/"},{"name":"Entrez Gene","className":"lcsb.mapviewer.annotation.services.annotators.EntrezAnnotator","elementClassNames":["lcsb.mapviewer.model.map.species.Protein","lcsb.mapviewer.model.map.species.Rna","lcsb.mapviewer.model.map.species.Gene"],"url":"http://www.ncbi.nlm.nih.gov/gene"},{"name":"Ensembl","className":"lcsb.mapviewer.annotation.services.annotators.EnsemblAnnotator","elementClassNames":["lcsb.mapviewer.model.map.species.Protein","lcsb.mapviewer.model.map.species.Rna","lcsb.mapviewer.model.map.species.Gene"],"url":"www.ensembl.org"}],"buildDate":" 28/09/2017 15:11","reactionTypes":[{"name":"Unknown positive influence","className":"lcsb.mapviewer.model.map.reaction.type.UnknownPositiveInfluenceReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Generic Reaction","className":"lcsb.mapviewer.model.map.reaction.Reaction","parentClass":"lcsb.mapviewer.model.map.BioEntity"},{"name":"Reduced physical stimulation","className":"lcsb.mapviewer.model.map.reaction.type.ReducedPhysicalStimulationReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Negative influence","className":"lcsb.mapviewer.model.map.reaction.type.NegativeInfluenceReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Known transition omitted","className":"lcsb.mapviewer.model.map.reaction.type.KnownTransitionOmittedReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Reduced modulation","className":"lcsb.mapviewer.model.map.reaction.type.ReducedModulationReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Translation","className":"lcsb.mapviewer.model.map.reaction.type.TranslationReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Heterodimer association","className":"lcsb.mapviewer.model.map.reaction.type.HeterodimerAssociationReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Transcription","className":"lcsb.mapviewer.model.map.reaction.type.TranscriptionReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Unknown reduced trigger","className":"lcsb.mapviewer.model.map.reaction.type.UnknownReducedTriggerReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Unknown negative influence","className":"lcsb.mapviewer.model.map.reaction.type.UnknownNegativeInfluenceReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Truncation","className":"lcsb.mapviewer.model.map.reaction.type.TruncationReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Transport","className":"lcsb.mapviewer.model.map.reaction.type.TransportReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Reduced trigger","className":"lcsb.mapviewer.model.map.reaction.type.ReducedTriggerReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"State transition","className":"lcsb.mapviewer.model.map.reaction.type.StateTransitionReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Positive influence","className":"lcsb.mapviewer.model.map.reaction.type.PositiveInfluenceReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Unknown reduced physical stimulation","className":"lcsb.mapviewer.model.map.reaction.type.UnknownReducedPhysicalStimulationReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Boolean logic gate","className":"lcsb.mapviewer.model.map.reaction.type.BooleanLogicGateReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Unknown reduced modulation","className":"lcsb.mapviewer.model.map.reaction.type.UnknownReducedModulationReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Unknown transition","className":"lcsb.mapviewer.model.map.reaction.type.UnknownTransitionReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"},{"name":"Dissociation","className":"lcsb.mapviewer.model.map.reaction.type.DissociationReaction","parentClass":"lcsb.mapviewer.model.map.reaction.Reaction"}],"version":"11.0.1","mapTypes":[{"name":"Downstream targets","id":"DOWNSTREAM_TARGETS"},{"name":"Pathway","id":"PATHWAY"},{"name":"Unknown","id":"UNKNOWN"}],"miriamTypes":{"CHEMBL_TARGET":{"commonName":"ChEMBL target","uris":["urn:miriam:chembl.target"],"homepage":"https://www.ebi.ac.uk/chembldb/","registryIdentifier":"MIR:00000085"},"UNIPROT":{"commonName":"Uniprot","uris":["urn:miriam:uniprot"],"homepage":"http://www.uniprot.org/","registryIdentifier":"MIR:00000005"},"MI_R_BASE_MATURE_SEQUENCE":{"commonName":"miRBase Mature Sequence Database","uris":["urn:miriam:mirbase.mature"],"homepage":"http://www.mirbase.org/","registryIdentifier":"MIR:00000235"},"PFAM":{"commonName":"Protein Family Database","uris":["urn:miriam:pfam"],"homepage":"http://pfam.xfam.org//","registryIdentifier":"MIR:00000028"},"ENSEMBL_PLANTS":{"commonName":"Ensembl Plants","uris":["urn:miriam:ensembl.plant"],"homepage":"http://plants.ensembl.org/","registryIdentifier":"MIR:00000205"},"WIKIPEDIA":{"commonName":"Wikipedia (English)","uris":["urn:miriam:wikipedia.en"],"homepage":"http://en.wikipedia.org/wiki/Main_Page","registryIdentifier":"MIR:00000384"},"CHEBI":{"commonName":"Chebi","uris":["urn:miriam:obo.chebi","urn:miriam:chebi"],"homepage":"http://www.ebi.ac.uk/chebi/","registryIdentifier":"MIR:00000002"},"WIKIDATA":{"commonName":"Wikidata","uris":["urn:miriam:wikidata"],"homepage":"https://www.wikidata.org/","registryIdentifier":"MIR:00000549"},"REACTOME":{"commonName":"Reactome","uris":["urn:miriam:reactome"],"homepage":"http://www.reactome.org/","registryIdentifier":"MIR:00000018"},"EC":{"commonName":"Enzyme Nomenclature","uris":["urn:miriam:ec-code"],"homepage":"http://www.enzyme-database.org/","registryIdentifier":"MIR:00000004"},"UNIPROT_ISOFORM":{"commonName":"UniProt Isoform","uris":["urn:miriam:uniprot.isoform"],"homepage":"http://www.uniprot.org/","registryIdentifier":"MIR:00000388"},"OMIM":{"commonName":"Online Mendelian Inheritance in Man","uris":["urn:miriam:omim"],"homepage":"http://omim.org/","registryIdentifier":"MIR:00000016"},"DRUGBANK_TARGET_V4":{"commonName":"DrugBank Target v4","uris":["urn:miriam:drugbankv4.target"],"homepage":"http://www.drugbank.ca/targets","registryIdentifier":"MIR:00000528"},"MIR_TAR_BASE_MATURE_SEQUENCE":{"commonName":"miRTarBase Mature Sequence Database","uris":["urn:miriam:mirtarbase"],"homepage":"http://mirtarbase.mbc.nctu.edu.tw/","registryIdentifier":"MIR:00100739"},"CHEMBL_COMPOUND":{"commonName":"ChEMBL","uris":["urn:miriam:chembl.compound"],"homepage":"https://www.ebi.ac.uk/chembldb/","registryIdentifier":"MIR:00000084"},"KEGG_PATHWAY":{"commonName":"Kegg Pathway","uris":["urn:miriam:kegg.pathway"],"homepage":"http://www.genome.jp/kegg/pathway.html","registryIdentifier":"MIR:00000012"},"CAS":{"commonName":"Chemical Abstracts Service","uris":["urn:miriam:cas"],"homepage":"http://commonchemistry.org","registryIdentifier":"MIR:00000237"},"REFSEQ":{"commonName":"RefSeq","uris":["urn:miriam:refseq"],"homepage":"http://www.ncbi.nlm.nih.gov/projects/RefSeq/","registryIdentifier":"MIR:00000039"},"WORM_BASE":{"commonName":"WormBase","uris":["urn:miriam:wormbase"],"homepage":"http://wormbase.bio2rdf.org/fct","registryIdentifier":"MIR:00000027"},"MI_R_BASE_SEQUENCE":{"commonName":"miRBase Sequence Database","uris":["urn:miriam:mirbase"],"homepage":"http://www.mirbase.org/","registryIdentifier":"MIR:00000078"},"TAIR_LOCUS":{"commonName":"TAIR Locus","uris":["urn:miriam:tair.locus"],"homepage":"http://arabidopsis.org/index.jsp","registryIdentifier":"MIR:00000050"},"PHARM":{"commonName":"PharmGKB Pathways","uris":["urn:miriam:pharmgkb.pathways"],"homepage":"http://www.pharmgkb.org/","registryIdentifier":"MIR:00000089"},"PANTHER":{"commonName":"PANTHER Family","uris":["urn:miriam:panther.family","urn:miriam:panther"],"homepage":"http://www.pantherdb.org/","registryIdentifier":"MIR:00000060"},"TAXONOMY":{"commonName":"Taxonomy","uris":["urn:miriam:taxonomy"],"homepage":"http://www.ncbi.nlm.nih.gov/taxonomy/","registryIdentifier":"MIR:00000006"},"UNIGENE":{"commonName":"UniGene","uris":["urn:miriam:unigene"],"homepage":"http://www.ncbi.nlm.nih.gov/unigene","registryIdentifier":"MIR:00000346"},"HGNC":{"commonName":"HGNC","uris":["urn:miriam:hgnc"],"homepage":"http://www.genenames.org","registryIdentifier":"MIR:00000080"},"HGNC_SYMBOL":{"commonName":"HGNC Symbol","uris":["urn:miriam:hgnc.symbol"],"homepage":"http://www.genenames.org","registryIdentifier":"MIR:00000362"},"COG":{"commonName":"Clusters of Orthologous Groups","uris":["urn:miriam:cogs"],"homepage":"https://www.ncbi.nlm.nih.gov/COG/","registryIdentifier":"MIR:00000296"},"WIKIPATHWAYS":{"commonName":"WikiPathways","uris":["urn:miriam:wikipathways"],"homepage":"http://www.wikipathways.org/","registryIdentifier":"MIR:00000076"},"HMDB":{"commonName":"HMDB","uris":["urn:miriam:hmdb"],"homepage":"http://www.hmdb.ca/","registryIdentifier":"MIR:00000051"},"CHEMSPIDER":{"commonName":"ChemSpider","uris":["urn:miriam:chemspider"],"homepage":"http://www.chemspider.com//","registryIdentifier":"MIR:00000138"},"ENSEMBL":{"commonName":"Ensembl","uris":["urn:miriam:ensembl"],"homepage":"www.ensembl.org","registryIdentifier":"MIR:00000003"},"GO":{"commonName":"Gene Ontology","uris":["urn:miriam:obo.go","urn:miriam:go"],"homepage":"http://amigo.geneontology.org/amigo","registryIdentifier":"MIR:00000022"},"KEGG_REACTION":{"commonName":"Kegg Reaction","uris":["urn:miriam:kegg.reaction"],"homepage":"http://www.genome.jp/kegg/reaction/","registryIdentifier":"MIR:00000014"},"KEGG_ORTHOLOGY":{"commonName":"KEGG Orthology","uris":["urn:miriam:kegg.orthology"],"homepage":"http://www.genome.jp/kegg/ko.html","registryIdentifier":"MIR:00000116"},"PUBCHEM":{"commonName":"PubChem-compound","uris":["urn:miriam:pubchem.compound"],"homepage":"http://pubchem.ncbi.nlm.nih.gov/","registryIdentifier":"MIR:00000034"},"MESH_2012":{"commonName":"MeSH 2012","uris":["urn:miriam:mesh.2012","urn:miriam:mesh"],"homepage":"http://www.nlm.nih.gov/mesh/","registryIdentifier":"MIR:00000270"},"MGD":{"commonName":"Mouse Genome Database","uris":["urn:miriam:mgd"],"homepage":"http://www.informatics.jax.org/","registryIdentifier":"MIR:00000037"},"ENTREZ":{"commonName":"Entrez Gene","uris":["urn:miriam:ncbigene","urn:miriam:entrez.gene"],"homepage":"http://www.ncbi.nlm.nih.gov/gene","registryIdentifier":"MIR:00000069"},"PUBCHEM_SUBSTANCE":{"commonName":"PubChem-substance","uris":["urn:miriam:pubchem.substance"],"homepage":"http://pubchem.ncbi.nlm.nih.gov/","registryIdentifier":"MIR:00000033"},"CCDS":{"commonName":"Consensus CDS","uris":["urn:miriam:ccds"],"homepage":"http://www.ncbi.nlm.nih.gov/CCDS/","registryIdentifier":"MIR:00000375"},"KEGG_GENES":{"commonName":"Kegg Genes","uris":["urn:miriam:kegg.genes","urn:miriam:kegg.genes:hsa"],"homepage":"http://www.genome.jp/kegg/genes.html","registryIdentifier":"MIR:00000070"},"TOXICOGENOMIC_CHEMICAL":{"commonName":"Toxicogenomic Chemical","uris":["urn:miriam:ctd.chemical"],"homepage":"http://ctdbase.org/","registryIdentifier":"MIR:00000098"},"SGD":{"commonName":"Saccharomyces Genome Database","uris":["urn:miriam:sgd"],"homepage":"http://www.yeastgenome.org/","registryIdentifier":"MIR:00000023"},"KEGG_COMPOUND":{"commonName":"Kegg Compound","uris":["urn:miriam:kegg.compound"],"homepage":"http://www.genome.jp/kegg/ligand.html","registryIdentifier":"MIR:00000013"},"INTERPRO":{"commonName":"InterPro","uris":["urn:miriam:interpro"],"homepage":"http://www.ebi.ac.uk/interpro/","registryIdentifier":"MIR:00000011"},"UNKNOWN":{"commonName":"Unknown","uris":[],"homepage":null,"registryIdentifier":null},"DRUGBANK":{"commonName":"DrugBank","uris":["urn:miriam:drugbank"],"homepage":"http://www.drugbank.ca/","registryIdentifier":"MIR:00000102"},"PUBMED":{"commonName":"PubMed","uris":["urn:miriam:pubmed"],"homepage":"http://www.ncbi.nlm.nih.gov/PubMed/","registryIdentifier":"MIR:00000015"}},"options":[{"idObject":9,"type":"EMAIL_ADDRESS","value":"your.account@domain.com"},{"idObject":10,"type":"EMAIL_LOGIN","value":"your@login"},{"idObject":11,"type":"EMAIL_PASSWORD","value":"email.secret.password"},{"idObject":13,"type":"EMAIL_IMAP_SERVER","value":"your.imap.domain.com"},{"idObject":12,"type":"EMAIL_SMTP_SERVER","value":"your.smtp.domain.com"},{"idObject":14,"type":"EMAIL_SMTP_PORT","value":"25"},{"idObject":6,"type":"DEFAULT_MAP","value":"sample"},{"idObject":4,"type":"LOGO_IMG","value":"udl.png"},{"idObject":3,"type":"LOGO_LINK","value":"http://wwwen.uni.lu/"},{"idObject":7,"type":"SEARCH_DISTANCE","value":"10"},{"idObject":1,"type":"REQUEST_ACCOUNT_EMAIL","value":"your.email@domain.com"},{"idObject":8,"type":"SEARCH_RESULT_NUMBER","value":"100"},{"idObject":2,"type":"GOOGLE_ANALYTICS_IDENTIFIER","value":""},{"idObject":5,"type":"LOGO_TEXT","value":"University of Luxembourg"},{"idObject":56,"type":"X_FRAME_DOMAIN","value":"http://localhost:8080/"},{"idObject":131,"type":"BIG_FILE_STORAGE_DIR","value":"minerva-big/"},{"idObject":138,"type":"LEGEND_FILE_1","value":"resources/images/legend_a.png"},{"idObject":139,"type":"LEGEND_FILE_2","value":"resources/images/legend_b.png"},{"idObject":140,"type":"LEGEND_FILE_3","value":"resources/images/legend_c.png"},{"idObject":141,"type":"LEGEND_FILE_4","value":"resources/images/legend_d.png"},{"idObject":142,"type":"USER_MANUAL_FILE","value":"resources/other/user_guide.pdf"},{"idObject":205,"type":"MIN_COLOR_VAL","value":"FF0000"},{"idObject":206,"type":"MAX_COLOR_VAL","value":"fbff00"},{"idObject":218,"type":"SIMPLE_COLOR_VAL","value":"00FF00"}],"privilegeTypes":{"VIEW_PROJECT":{"commonName":"View project","valueType":"boolean","objectType":"Project"},"LAYOUT_MANAGEMENT":{"commonName":"Manage layouts","valueType":"boolean","objectType":"Project"},"PROJECT_MANAGEMENT":{"commonName":"Map management","valueType":"boolean","objectType":null},"CUSTOM_LAYOUTS":{"commonName":"Custom layouts","valueType":"int","objectType":null},"ADD_MAP":{"commonName":"Add project","valueType":"boolean","objectType":null},"LAYOUT_VIEW":{"commonName":"View layout","valueType":"boolean","objectType":"Layout"},"MANAGE_GENOMES":{"commonName":"Manage genomes","valueType":"boolean","objectType":null},"EDIT_COMMENTS_PROJECT":{"commonName":"Manage comments","valueType":"boolean","objectType":"Project"},"CONFIGURATION_MANAGE":{"commonName":"Manage configuration","valueType":"boolean","objectType":null},"USER_MANAGEMENT":{"commonName":"User management","valueType":"boolean","objectType":null}},"overlayTypes":[{"name":"GENERIC"},{"name":"GENETIC_VARIANT"}]} \ No newline at end of file diff --git a/frontend-js/testFiles/map/complex_model_with_overlays.zip b/frontend-js/testFiles/map/complex_model_with_overlays.zip new file mode 100644 index 0000000000000000000000000000000000000000..0aa92bc0ab6aa5a047d64677c3520d45de75e878 Binary files /dev/null and b/frontend-js/testFiles/map/complex_model_with_overlays.zip differ diff --git a/frontend-js/testFiles/map/complex_model_with_submaps.zip b/frontend-js/testFiles/map/complex_model_with_submaps.zip new file mode 100644 index 0000000000000000000000000000000000000000..5985c849bbeff096451d99b43a430ec6c266cf5b Binary files /dev/null and b/frontend-js/testFiles/map/complex_model_with_submaps.zip differ diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationController.java b/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationController.java index e1ca1c0399715a380efb489f415821ebd4835974..52d86daa0f012301a2d1813ef17b167af9d1be65 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationController.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationController.java @@ -19,68 +19,71 @@ import lcsb.mapviewer.services.interfaces.IConfigurationService; @RestController public class ConfigurationController extends BaseController { - @Autowired - private ConfigurationRestImpl configurationController; + @Autowired + private ConfigurationRestImpl configurationController; - @Autowired - private IConfigurationService configurationService; + @Autowired + private IConfigurationService configurationService; - /** - * Context used to determine deployment path. - */ - @Autowired - private ServletContext context; + /** + * Context used to determine deployment path. + */ + @Autowired + private ServletContext context; - @RequestMapping(value = "/configuration/", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public Map<String, Object> getOverlayTypes(@CookieValue(value = Configuration.AUTH_TOKEN) String token) throws SecurityException { - Map<String, Object> result = new HashMap<>(); - result.put("options", configurationController.getAllValues(token)); - result.put("imageFormats", configurationController.getImageFormats(token)); - result.put("modelFormats", configurationController.getModelFormats(token)); - result.put("overlayTypes", configurationController.getOverlayTypes(token)); - result.put("elementTypes", configurationController.getElementTypes(token)); - result.put("reactionTypes", configurationController.getReactionTypes(token)); - result.put("miriamTypes", configurationController.getMiriamTypes(token)); - result.put("modificationStateTypes", configurationController.getModificationStateTypes(token)); - result.put("privilegeTypes", configurationController.getPrivilegeTypes(token)); - result.put("version", configurationService.getSystemSvnVersion(context.getRealPath("/"))); - result.put("buildDate", configurationService.getSystemBuild(context.getRealPath("/"))); - result.put("annotators", configurationController.getAnnotators(token)); - return result; - } + @RequestMapping(value = "/configuration/", method = { RequestMethod.GET }, produces = { + MediaType.APPLICATION_JSON_VALUE }) + public Map<String, Object> getOverlayTypes(@CookieValue(value = Configuration.AUTH_TOKEN) String token) + throws SecurityException { + Map<String, Object> result = new HashMap<>(); + result.put("options", configurationController.getAllValues(token)); + result.put("imageFormats", configurationController.getImageFormats(token)); + result.put("modelFormats", configurationController.getModelFormats(token)); + result.put("overlayTypes", configurationController.getOverlayTypes(token)); + result.put("elementTypes", configurationController.getElementTypes(token)); + result.put("reactionTypes", configurationController.getReactionTypes(token)); + result.put("miriamTypes", configurationController.getMiriamTypes(token)); + result.put("mapTypes", configurationController.getMapTypes(token)); + result.put("modificationStateTypes", configurationController.getModificationStateTypes(token)); + result.put("privilegeTypes", configurationController.getPrivilegeTypes(token)); + result.put("version", configurationService.getSystemSvnVersion(context.getRealPath("/"))); + result.put("buildDate", configurationService.getSystemBuild(context.getRealPath("/"))); + result.put("annotators", configurationController.getAnnotators(token)); + return result; + } - /** - * @return the configurationController - * @see #configurationController - */ - public ConfigurationRestImpl getConfigurationController() { - return configurationController; - } + /** + * @return the configurationController + * @see #configurationController + */ + public ConfigurationRestImpl getConfigurationController() { + return configurationController; + } - /** - * @param configurationController - * the configurationController to set - * @see #configurationController - */ - public void setConfigurationController(ConfigurationRestImpl configurationController) { - this.configurationController = configurationController; - } + /** + * @param configurationController + * the configurationController to set + * @see #configurationController + */ + public void setConfigurationController(ConfigurationRestImpl configurationController) { + this.configurationController = configurationController; + } - /** - * @return the configurationService - * @see #configurationService - */ - public IConfigurationService getConfigurationService() { - return configurationService; - } + /** + * @return the configurationService + * @see #configurationService + */ + public IConfigurationService getConfigurationService() { + return configurationService; + } - /** - * @param configurationService - * the configurationService to set - * @see #configurationService - */ - public void setConfigurationService(IConfigurationService configurationService) { - this.configurationService = configurationService; - } + /** + * @param configurationService + * the configurationService to set + * @see #configurationService + */ + public void setConfigurationService(IConfigurationService configurationService) { + this.configurationService = configurationService; + } } \ No newline at end of file diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationRestImpl.java index 6eb4066d9b08d66ee6a655414166bef47565e3bf..effd2cb87d76612dfeb95ec991946e8d0c174de3 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationRestImpl.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationRestImpl.java @@ -25,6 +25,8 @@ import lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser; import lcsb.mapviewer.converter.model.sbgnml.SbgnmlXmlConverter; import lcsb.mapviewer.model.map.BioEntity; import lcsb.mapviewer.model.map.MiriamType; +import lcsb.mapviewer.model.map.model.ModelSubmodelConnection; +import lcsb.mapviewer.model.map.model.SubmodelType; import lcsb.mapviewer.model.map.reaction.Reaction; import lcsb.mapviewer.model.map.species.Element; import lcsb.mapviewer.model.map.species.field.ModificationState; @@ -39,216 +41,228 @@ import lcsb.mapviewer.services.view.ConfigurationView; @Transactional(value = "txManager") public class ConfigurationRestImpl { - /** - * Default class logger. - */ - @SuppressWarnings("unused") - private Logger logger = Logger.getLogger(ConfigurationRestImpl.class); - - @Autowired - private IUserService userService; - - @Autowired - private IConfigurationService configurationService; - - @Autowired - private ModelAnnotator modelAnnotator; - - public List<ConfigurationView> getAllValues(String token) throws SecurityException { - userService.getToken(token); - return configurationService.getAllValues(); - } - - /** - * @return the userService - * @see #userService - */ - public IUserService getUserService() { - return userService; - } - - /** - * @param userService - * the userService to set - * @see #userService - */ - public void setUserService(IUserService userService) { - this.userService = userService; - } - - /** - * @return the configurationService - * @see #configurationService - */ - public IConfigurationService getConfigurationService() { - return configurationService; - } - - /** - * @param configurationService - * the configurationService to set - * @see #configurationService - */ - public void setConfigurationService(IConfigurationService configurationService) { - this.configurationService = configurationService; - } - - public List<Map<String, Object>> getImageFormats(String token) throws SecurityException { - userService.getToken(token); - - List<Map<String, Object>> 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 HashMap<>(); - row.put("name", element.getLeft()); - row.put("handler", element.getRight().getCanonicalName()); - row.put("extension", imageGenerators.getExtension(element.getRight())); - result.add(row); - } - return result; - } - - public List<Map<String, Object>> getModelFormats(String token) throws SecurityException { - userService.getToken(token); - List<IConverter> converters = new ArrayList<>(); - converters.add(new CellDesignerXmlParser()); - converters.add(new SbgnmlXmlConverter()); - - List<Map<String, Object>> result = new ArrayList<>(); - - for (IConverter converter : converters) { - Map<String, Object> row = new HashMap<>(); - 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(String token) throws SecurityException { - userService.getToken(token); - List<Map<String, Object>> result = new ArrayList<>(); - for (ColorSchemaType type : ColorSchemaType.values()) { - Map<String, Object> map = new HashMap<>(); - map.put("name", type.name()); - result.add(map); - } - return result; - } - - public Set<Map<String, String>> getElementTypes(String token) throws SecurityException { - userService.getToken(token); - - return getClassStringTypesList(Element.class); - } - - private Set<Map<String, String>> getClassStringTypesList(Class<?> elementClass) { - Set<Map<String, String>> result = new HashSet<>(); - ElementUtils elementUtils = new ElementUtils(); - ClassTreeNode top = elementUtils.getAnnotatedElementClassTree(); - Queue<ClassTreeNode> queue = new LinkedList<>(); - queue.add(top); - while (!queue.isEmpty()) { - ClassTreeNode clazz = queue.poll(); - for (ClassTreeNode child : clazz.getChildren()) { - queue.add(child); - } - if (elementClass.isAssignableFrom(clazz.getClazz())) { - Map<String, String> row = new HashMap<>(); - 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); - } - } - return result; - } - - public Set<Map<String, String>> getReactionTypes(String token) throws SecurityException { - userService.getToken(token); - - return getClassStringTypesList(Reaction.class); - } - - public Map<String, Object> getMiriamTypes(String id) { - Map<String, Object> result = new HashMap<>(); - for (MiriamType type : MiriamType.values()) { - result.put(type.name(), createMiriamTypeResponse(type)); - } - return result; - } - - private Map<String, Object> createMiriamTypeResponse(MiriamType type) { - Map<String, Object> result = new HashMap<>(); - 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(String token) { - Map<String, Object> result = new HashMap<>(); - for (ModificationState type : ModificationState.values()) { - result.put(type.name(), createModificationStateResponse(type)); - } - return result; - } - - private Map<String, Object> createModificationStateResponse(ModificationState type) { - Map<String, Object> result = new HashMap<>(); - result.put("commonName", type.getFullName()); - result.put("abbreviation", type.getAbbreviation()); - return result; - } - - public Map<String, Object> getPrivilegeTypes(String id) { - Map<String, Object> result = new HashMap<>(); - for (PrivilegeType type : PrivilegeType.values()) { - result.put(type.name(), createPrivilegeTypeResponse(type)); - } - return result; - } - - private Map<String, Object> createPrivilegeTypeResponse(PrivilegeType type) { - Map<String, Object> result = new HashMap<>(); - result.put("commonName", type.getCommonName()); - if (type.getPrivilegeObjectType() != null) { - result.put("objectType", type.getPrivilegeObjectType().getSimpleName()); - } else { - result.put("objectType", null); - } - if (type.isNumeric()) { - result.put("valueType", "int"); - } else { - result.put("valueType", "boolean"); - } - return result; - } - - public List<Map<String, Object>> getAnnotators(String token) { - List<Map<String, Object>> result = new ArrayList<>(); - for (ElementAnnotator annotator : modelAnnotator.getAvailableAnnotators()) { - result.add(prepareAnnotator(annotator)); - } - return result; - } - - private Map<String, Object> prepareAnnotator(ElementAnnotator annotator) { - Map<String, Object> result = new HashMap<>(); - result.put("className", annotator.getClass().getName()); - result.put("name", annotator.getCommonName()); - result.put("url", annotator.getUrl()); - result.put("elementClassNames", annotator.getValidClasses()); - return result; - } + /** + * Default class logger. + */ + @SuppressWarnings("unused") + private Logger logger = Logger.getLogger(ConfigurationRestImpl.class); + + @Autowired + private IUserService userService; + + @Autowired + private IConfigurationService configurationService; + + @Autowired + private ModelAnnotator modelAnnotator; + + public List<ConfigurationView> getAllValues(String token) throws SecurityException { + userService.getToken(token); + return configurationService.getAllValues(); + } + + /** + * @return the userService + * @see #userService + */ + public IUserService getUserService() { + return userService; + } + + /** + * @param userService + * the userService to set + * @see #userService + */ + public void setUserService(IUserService userService) { + this.userService = userService; + } + + /** + * @return the configurationService + * @see #configurationService + */ + public IConfigurationService getConfigurationService() { + return configurationService; + } + + /** + * @param configurationService + * the configurationService to set + * @see #configurationService + */ + public void setConfigurationService(IConfigurationService configurationService) { + this.configurationService = configurationService; + } + + public List<Map<String, Object>> getImageFormats(String token) throws SecurityException { + userService.getToken(token); + + List<Map<String, Object>> 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 HashMap<>(); + row.put("name", element.getLeft()); + row.put("handler", element.getRight().getCanonicalName()); + row.put("extension", imageGenerators.getExtension(element.getRight())); + result.add(row); + } + return result; + } + + public List<Map<String, Object>> getModelFormats(String token) throws SecurityException { + userService.getToken(token); + List<IConverter> converters = new ArrayList<>(); + converters.add(new CellDesignerXmlParser()); + converters.add(new SbgnmlXmlConverter()); + + List<Map<String, Object>> result = new ArrayList<>(); + + for (IConverter converter : converters) { + Map<String, Object> row = new HashMap<>(); + 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(String token) throws SecurityException { + userService.getToken(token); + List<Map<String, Object>> result = new ArrayList<>(); + for (ColorSchemaType type : ColorSchemaType.values()) { + Map<String, Object> map = new HashMap<>(); + map.put("name", type.name()); + result.add(map); + } + return result; + } + + public Set<Map<String, String>> getElementTypes(String token) throws SecurityException { + userService.getToken(token); + + return getClassStringTypesList(Element.class); + } + + private Set<Map<String, String>> getClassStringTypesList(Class<?> elementClass) { + Set<Map<String, String>> result = new HashSet<>(); + ElementUtils elementUtils = new ElementUtils(); + ClassTreeNode top = elementUtils.getAnnotatedElementClassTree(); + Queue<ClassTreeNode> queue = new LinkedList<>(); + queue.add(top); + while (!queue.isEmpty()) { + ClassTreeNode clazz = queue.poll(); + for (ClassTreeNode child : clazz.getChildren()) { + queue.add(child); + } + if (elementClass.isAssignableFrom(clazz.getClazz())) { + Map<String, String> row = new HashMap<>(); + 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); + } + } + return result; + } + + public Set<Map<String, String>> getReactionTypes(String token) throws SecurityException { + userService.getToken(token); + + return getClassStringTypesList(Reaction.class); + } + + public Map<String, Object> getMiriamTypes(String id) { + Map<String, Object> result = new HashMap<>(); + for (MiriamType type : MiriamType.values()) { + result.put(type.name(), createMiriamTypeResponse(type)); + } + return result; + } + + private Map<String, Object> createMiriamTypeResponse(MiriamType type) { + Map<String, Object> result = new HashMap<>(); + 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(String token) { + Map<String, Object> result = new HashMap<>(); + for (ModificationState type : ModificationState.values()) { + result.put(type.name(), createModificationStateResponse(type)); + } + return result; + } + + private Map<String, Object> createModificationStateResponse(ModificationState type) { + Map<String, Object> result = new HashMap<>(); + result.put("commonName", type.getFullName()); + result.put("abbreviation", type.getAbbreviation()); + return result; + } + + public Map<String, Object> getPrivilegeTypes(String id) { + Map<String, Object> result = new HashMap<>(); + for (PrivilegeType type : PrivilegeType.values()) { + result.put(type.name(), createPrivilegeTypeResponse(type)); + } + return result; + } + + private Map<String, Object> createPrivilegeTypeResponse(PrivilegeType type) { + Map<String, Object> result = new HashMap<>(); + result.put("commonName", type.getCommonName()); + if (type.getPrivilegeObjectType() != null) { + result.put("objectType", type.getPrivilegeObjectType().getSimpleName()); + } else { + result.put("objectType", null); + } + if (type.isNumeric()) { + result.put("valueType", "int"); + } else { + result.put("valueType", "boolean"); + } + return result; + } + + public List<Map<String, Object>> getAnnotators(String token) { + List<Map<String, Object>> result = new ArrayList<>(); + for (ElementAnnotator annotator : modelAnnotator.getAvailableAnnotators()) { + result.add(prepareAnnotator(annotator)); + } + return result; + } + + private Map<String, Object> prepareAnnotator(ElementAnnotator annotator) { + Map<String, Object> result = new HashMap<>(); + result.put("className", annotator.getClass().getName()); + result.put("name", annotator.getCommonName()); + result.put("url", annotator.getUrl()); + result.put("elementClassNames", annotator.getValidClasses()); + return result; + } + + public List<Map<String, Object>> getMapTypes(String token) { + List<Map<String, Object>> result = new ArrayList<>(); + for (SubmodelType type : SubmodelType.values()) { + Map<String, Object> row = new HashMap<>(); + row.put("id", type.name()); + row.put("name", type.getCommonName()); + result.add(row); + } + return result; + } } diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectController.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectController.java index 793084e98a0c168646a689fe89ae948158d3c591..3c2db6e9d4f9186d3ddc9b1c29cadf0ef368f9c3 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectController.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectController.java @@ -33,141 +33,152 @@ import lcsb.mapviewer.services.SecurityException; @RestController public class ProjectController extends BaseController { - private Logger logger = Logger.getLogger(ProjectController.class); - - @Autowired - private ServletContext context; - - @Autowired - private ProjectRestImpl projectController; - - @RequestMapping(value = "/projects/{projectId:.+}", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public ProjectMetaData getProject(// - @PathVariable(value = "projectId") String projectId, // - @CookieValue(value = Configuration.AUTH_TOKEN) String token // - ) throws SecurityException, ObjectNotFoundException { - return projectController.getProject(projectId, token); - } - - @RequestMapping(value = "/projects/{projectId:.+}", method = { RequestMethod.PATCH }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public ProjectMetaData updateProject(// - @RequestBody String body, // - @PathVariable(value = "projectId") String projectId, // - @CookieValue(value = Configuration.AUTH_TOKEN) String token // - ) throws SecurityException, IOException, QueryException { - Map<String, Object> node = parseBody(body); - Map<String, Object> data = getData(node, "project"); - return projectController.updateProject(token, projectId, data); - - } - - @RequestMapping(value = "/projects/{projectId:.+}", method = { RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public ProjectMetaData addProject(// - @RequestBody MultiValueMap<String,String> formData, // - @PathVariable(value = "projectId") String projectId, // - @CookieValue(value = Configuration.AUTH_TOKEN) String token // - ) throws SecurityException, IOException, QueryException { - return projectController.addProject(token, projectId, formData, context.getRealPath("/")); - - } - - @RequestMapping(value = "/projects/{projectId:.+}", method = { RequestMethod.DELETE }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public ProjectMetaData removeProject(// - @PathVariable(value = "projectId") String projectId, // - @CookieValue(value = Configuration.AUTH_TOKEN) String token // - ) throws SecurityException, IOException, QueryException { - return projectController.removeProject(token, projectId, context.getRealPath("/")); - - } - - @RequestMapping(value = "/projects/", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public List<ProjectMetaData> getProjects(// - @CookieValue(value = Configuration.AUTH_TOKEN) String token // - ) throws SecurityException, ObjectNotFoundException { - return projectController.getProjects(token); - } - - @RequestMapping(value = "/projects/{projectId}/statistics", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public Object getStatistics(// - @PathVariable(value = "projectId") String projectId, // - @CookieValue(value = Configuration.AUTH_TOKEN) String token // - ) throws SecurityException, ObjectNotFoundException { - return projectController.getStatistics(projectId, token); - } - - @RequestMapping(value = "/projects/{projectId}:downloadSource", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity<byte[]> getProjectSource(// - @CookieValue(value = Configuration.AUTH_TOKEN) String token, // - @PathVariable(value = "projectId") String projectId // - ) throws SecurityException, QueryException { - - FileEntry file = projectController.getSource(token, projectId); - MediaType type = MediaType.TEXT_PLAIN; - if (file.getOriginalFileName().endsWith("xml")) { - type = MediaType.APPLICATION_XML; - } else if (file.getOriginalFileName().endsWith("zip")) { - type = MediaType.APPLICATION_OCTET_STREAM; - } - return ResponseEntity - .ok().contentLength(file.getFileContent().length).contentType(type).header("Content-Disposition", "attachment; filename=" + file.getOriginalFileName()) - .body(file.getFileContent()); - } - - @RequestMapping(value = "/projects/{projectId}/models/{modelId}:downloadImage", method = { RequestMethod.GET }, - produces = { MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity<byte[]> getModelAsImage(// - @CookieValue(value = Configuration.AUTH_TOKEN) String token, // - @PathVariable(value = "projectId") String projectId, // - @PathVariable(value = "modelId") String modelId, // - @RequestParam(value = "handlerClass") String handlerClass, // - @RequestParam(value = "backgroundOverlayId", defaultValue = "") String backgroundOverlayId, // - @RequestParam(value = "overlayIds", defaultValue = "") String overlayIds, // - @RequestParam(value = "zoomLevel", defaultValue = "") String zoomLevel, // - @RequestParam(value = "polygonString", defaultValue = "") String polygonString// - ) throws SecurityException, QueryException, IOException, InvalidColorSchemaException, CommandExecutionException, DrawingException { - - FileEntry file = projectController.getModelAsImage(token, projectId, modelId, handlerClass, backgroundOverlayId, overlayIds, zoomLevel, polygonString); - MediaType type = MediaType.APPLICATION_OCTET_STREAM; - return ResponseEntity - .ok().contentLength(file.getFileContent().length).contentType(type).header("Content-Disposition", "attachment; filename=" + file.getOriginalFileName()) - .body(file.getFileContent()); - } - - @RequestMapping(value = "/projects/{projectId}/models/{modelId}:downloadModel", method = { RequestMethod.GET }, - produces = { MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity<byte[]> getModelAsModelFile(// - @CookieValue(value = Configuration.AUTH_TOKEN) String token, // - @PathVariable(value = "projectId") String projectId, // - @PathVariable(value = "modelId") String modelId, // - @RequestParam(value = "handlerClass") String handlerClass, // - @RequestParam(value = "backgroundOverlayId", defaultValue = "") String backgroundOverlayId, // - @RequestParam(value = "overlayIds", defaultValue = "") String overlayIds, // - @RequestParam(value = "zoomLevel", defaultValue = "") String zoomLevel, // - @RequestParam(value = "polygonString", defaultValue = "") String polygonString// - ) throws SecurityException, QueryException, IOException, InvalidColorSchemaException, CommandExecutionException, ConverterException, - InconsistentModelException { - - FileEntry file = projectController.getModelAsModelFile(token, projectId, modelId, handlerClass, backgroundOverlayId, overlayIds, zoomLevel, polygonString); - MediaType type = MediaType.APPLICATION_OCTET_STREAM; - return ResponseEntity - .ok().contentLength(file.getFileContent().length).contentType(type).header("Content-Disposition", "attachment; filename=" + file.getOriginalFileName()) - .body(file.getFileContent()); - } - - /** - * @return the context - * @see #context - */ - public ServletContext getContext() { - return context; - } - - /** - * @param context the context to set - * @see #context - */ - public void setContext(ServletContext context) { - this.context = context; - } + @SuppressWarnings("unused") + private Logger logger = Logger.getLogger(ProjectController.class); + + @Autowired + private ServletContext context; + + @Autowired + private ProjectRestImpl projectController; + + @RequestMapping(value = "/projects/{projectId:.+}", method = { RequestMethod.GET }, produces = { + MediaType.APPLICATION_JSON_VALUE }) + public ProjectMetaData getProject(// + @PathVariable(value = "projectId") String projectId, // + @CookieValue(value = Configuration.AUTH_TOKEN) String token // + ) throws SecurityException, ObjectNotFoundException { + return projectController.getProject(projectId, token); + } + + @RequestMapping(value = "/projects/{projectId:.+}", method = { RequestMethod.PATCH }, produces = { + MediaType.APPLICATION_JSON_VALUE }) + public ProjectMetaData updateProject(// + @RequestBody String body, // + @PathVariable(value = "projectId") String projectId, // + @CookieValue(value = Configuration.AUTH_TOKEN) String token // + ) throws SecurityException, IOException, QueryException { + Map<String, Object> node = parseBody(body); + Map<String, Object> data = getData(node, "project"); + return projectController.updateProject(token, projectId, data); + + } + + @RequestMapping(value = "/projects/{projectId:.+}", method = { RequestMethod.POST }, produces = { + MediaType.APPLICATION_JSON_VALUE }) + public ProjectMetaData addProject(// + @RequestBody MultiValueMap<String, Object> formData, // + @PathVariable(value = "projectId") String projectId, // + @CookieValue(value = Configuration.AUTH_TOKEN) String token // + ) throws SecurityException, IOException, QueryException { + return projectController.addProject(token, projectId, formData, context.getRealPath("/")); + + } + + @RequestMapping(value = "/projects/{projectId:.+}", method = { RequestMethod.DELETE }, produces = { + MediaType.APPLICATION_JSON_VALUE }) + public ProjectMetaData removeProject(// + @PathVariable(value = "projectId") String projectId, // + @CookieValue(value = Configuration.AUTH_TOKEN) String token // + ) throws SecurityException, IOException, QueryException { + return projectController.removeProject(token, projectId, context.getRealPath("/")); + + } + + @RequestMapping(value = "/projects/", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE }) + public List<ProjectMetaData> getProjects(// + @CookieValue(value = Configuration.AUTH_TOKEN) String token // + ) throws SecurityException, ObjectNotFoundException { + return projectController.getProjects(token); + } + + @RequestMapping(value = "/projects/{projectId}/statistics", method = { RequestMethod.GET }, produces = { + MediaType.APPLICATION_JSON_VALUE }) + public Object getStatistics(// + @PathVariable(value = "projectId") String projectId, // + @CookieValue(value = Configuration.AUTH_TOKEN) String token // + ) throws SecurityException, ObjectNotFoundException { + return projectController.getStatistics(projectId, token); + } + + @RequestMapping(value = "/projects/{projectId}:downloadSource", method = { RequestMethod.GET }, produces = { + MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity<byte[]> getProjectSource(// + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @PathVariable(value = "projectId") String projectId // + ) throws SecurityException, QueryException { + + FileEntry file = projectController.getSource(token, projectId); + MediaType type = MediaType.TEXT_PLAIN; + if (file.getOriginalFileName().endsWith("xml")) { + type = MediaType.APPLICATION_XML; + } else if (file.getOriginalFileName().endsWith("zip")) { + type = MediaType.APPLICATION_OCTET_STREAM; + } + return ResponseEntity.ok().contentLength(file.getFileContent().length).contentType(type) + .header("Content-Disposition", "attachment; filename=" + file.getOriginalFileName()) + .body(file.getFileContent()); + } + + @RequestMapping(value = "/projects/{projectId}/models/{modelId}:downloadImage", method = { + RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity<byte[]> getModelAsImage(// + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @PathVariable(value = "projectId") String projectId, // + @PathVariable(value = "modelId") String modelId, // + @RequestParam(value = "handlerClass") String handlerClass, // + @RequestParam(value = "backgroundOverlayId", defaultValue = "") String backgroundOverlayId, // + @RequestParam(value = "overlayIds", defaultValue = "") String overlayIds, // + @RequestParam(value = "zoomLevel", defaultValue = "") String zoomLevel, // + @RequestParam(value = "polygonString", defaultValue = "") String polygonString// + ) throws SecurityException, QueryException, IOException, InvalidColorSchemaException, CommandExecutionException, + DrawingException { + + FileEntry file = projectController.getModelAsImage(token, projectId, modelId, handlerClass, backgroundOverlayId, + overlayIds, zoomLevel, polygonString); + MediaType type = MediaType.APPLICATION_OCTET_STREAM; + return ResponseEntity.ok().contentLength(file.getFileContent().length).contentType(type) + .header("Content-Disposition", "attachment; filename=" + file.getOriginalFileName()) + .body(file.getFileContent()); + } + + @RequestMapping(value = "/projects/{projectId}/models/{modelId}:downloadModel", method = { + RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity<byte[]> getModelAsModelFile(// + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @PathVariable(value = "projectId") String projectId, // + @PathVariable(value = "modelId") String modelId, // + @RequestParam(value = "handlerClass") String handlerClass, // + @RequestParam(value = "backgroundOverlayId", defaultValue = "") String backgroundOverlayId, // + @RequestParam(value = "overlayIds", defaultValue = "") String overlayIds, // + @RequestParam(value = "zoomLevel", defaultValue = "") String zoomLevel, // + @RequestParam(value = "polygonString", defaultValue = "") String polygonString// + ) throws SecurityException, QueryException, IOException, InvalidColorSchemaException, CommandExecutionException, + ConverterException, InconsistentModelException { + + FileEntry file = projectController.getModelAsModelFile(token, projectId, modelId, handlerClass, backgroundOverlayId, + overlayIds, zoomLevel, polygonString); + MediaType type = MediaType.APPLICATION_OCTET_STREAM; + return ResponseEntity.ok().contentLength(file.getFileContent().length).contentType(type) + .header("Content-Disposition", "attachment; filename=" + file.getOriginalFileName()) + .body(file.getFileContent()); + } + + /** + * @return the context + * @see #context + */ + public ServletContext getContext() { + return context; + } + + /** + * @param context + * the context to set + * @see #context + */ + public void setContext(ServletContext context) { + this.context = context; + } } \ No newline at end of file diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectRestImpl.java index b788a8feb8c46cccf085cc3aacc6986f40341f21..6a50de4c1f70aa97abae624754c51e4b116e9f6a 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectRestImpl.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectRestImpl.java @@ -38,9 +38,14 @@ import lcsb.mapviewer.commands.SetFixedHierarchyLevelCommand; import lcsb.mapviewer.commands.SubModelCommand; import lcsb.mapviewer.common.Configuration; import lcsb.mapviewer.common.exception.InvalidArgumentException; +import lcsb.mapviewer.common.exception.NotImplementedException; import lcsb.mapviewer.converter.ConverterException; import lcsb.mapviewer.converter.IConverter; import lcsb.mapviewer.converter.graphics.AbstractImageGenerator.Params; +import lcsb.mapviewer.converter.zip.ImageZipEntryFile; +import lcsb.mapviewer.converter.zip.LayoutZipEntryFile; +import lcsb.mapviewer.converter.zip.ModelZipEntryFile; +import lcsb.mapviewer.converter.zip.ZipEntryFile; import lcsb.mapviewer.converter.graphics.DrawingException; import lcsb.mapviewer.converter.graphics.ImageGenerators; import lcsb.mapviewer.model.Project; @@ -56,6 +61,7 @@ import lcsb.mapviewer.model.map.layout.ColorSchema; import lcsb.mapviewer.model.map.layout.InvalidColorSchemaException; import lcsb.mapviewer.model.map.layout.Layout; import lcsb.mapviewer.model.map.model.Model; +import lcsb.mapviewer.model.map.model.SubmodelType; import lcsb.mapviewer.model.map.reaction.Reaction; import lcsb.mapviewer.model.map.species.Element; import lcsb.mapviewer.model.user.PrivilegeType; @@ -75,7 +81,7 @@ public class ProjectRestImpl extends BaseRestImpl { /** * Constant defining size of the array returned by - * {@link PathIterator#currentSegment(double[])} method. More nformation can be + * {@link PathIterator#currentSegment(double[])} method. More information can be * found <a href= * "http://docs.oracle.com/javase/7/docs/api/java/awt/geom/PathIterator.html#currentSegment(double[])" * >here</a> @@ -473,8 +479,9 @@ public class ProjectRestImpl extends BaseRestImpl { } } - public ProjectMetaData addProject(String token, String projectId, MultiValueMap<String, String> data, String path) + public ProjectMetaData addProject(String token, String projectId, MultiValueMap<String, Object> data, String path) throws SecurityException, QueryException, IOException { + logger.info(data); AuthenticationToken authenticationToken = getUserService().getToken(token); User user = getUserService().getUserByToken(authenticationToken); Project project = getProjectService().getProjectByProjectId(projectId, authenticationToken); @@ -493,6 +500,12 @@ public class ProjectRestImpl extends BaseRestImpl { } IConverter parser = getModelParser(parserClass); + List<ZipEntryFile> zipEntries = extractZipEntries(data); + params.complex(zipEntries.size() > 0); + for (ZipEntryFile entry : zipEntries) { + params.addZipEntry(entry); + } + params.addUser(user.getLogin(), null); params.async(true); params.parser(parser); @@ -504,7 +517,7 @@ public class ProjectRestImpl extends BaseRestImpl { params.notifyEmail(getFirstValue(data.get("notify-email"))); params.projectDir(directory); params.projectDisease(getFirstValue(data.get("disease"))); - params.projectFile(new ByteArrayInputStream(fileContent.getBytes(StandardCharsets.UTF_8))); + params.projectFile(new ByteArrayInputStream(fileContent.getBytes())); params.projectId(projectId); params.projectName(getFirstValue(data.get("name"))); params.projectOrganism(getFirstValue(data.get("organism"))); @@ -525,12 +538,57 @@ public class ProjectRestImpl extends BaseRestImpl { return getProject(projectId, token); } - private String getFirstValue(List<String> list) { + protected List<ZipEntryFile> extractZipEntries(MultiValueMap<String, Object> data) { + int fileIndex = 0; + List<ZipEntryFile> result = new ArrayList<>(); + while (data.get("zip-entries[" + fileIndex + "][_filename]") != null) { + ZipEntryFile entry = null; + String entryType = (String) data.get("zip-entries[" + fileIndex + "][_type]").get(0); + String filename = (String) data.get("zip-entries[" + fileIndex + "][_filename]").get(0); + if ("MAP".equalsIgnoreCase(entryType)) { + String submodelTypeKey = "zip-entries[" + fileIndex + "][_data][type][id]"; + String rootKey = "zip-entries[" + fileIndex + "][_data][root]"; + String mappingKey = "zip-entries[" + fileIndex + "][_data][mapping]"; + SubmodelType mapType = SubmodelType.valueOf((String) data.get(submodelTypeKey).get(0)); + String name = (String) data.get("zip-entries[" + fileIndex + "][_data][name]").get(0); + Boolean root = getBoolValue(data.get(rootKey), false); + Boolean mapping = getBoolValue(data.get(mappingKey), false); + + entry = new ModelZipEntryFile(filename, name, root, mapping, mapType); + } else if ("OVERLAY".equalsIgnoreCase(entryType)) { + String name = (String) data.get("zip-entries[" + fileIndex + "][_data][name]").get(0); + String description = (String) data.get("zip-entries[" + fileIndex + "][_data][description]").get(0); + entry = new LayoutZipEntryFile(filename, name, description); + } else if ("IMAGE".equalsIgnoreCase(entryType)) { + entry = new ImageZipEntryFile(filename); + } else { + throw new Error("Unknown entry type: " + entryType); + } + fileIndex++; + result.add(entry); + + } + return result; + } + + private Boolean getBoolValue(List<Object> list, boolean defaultValue) { + if (list == null) { + return defaultValue; + } + Object obj = list.get(0); + if (obj instanceof Boolean) { + return (Boolean) list.get(0); + } else { + return "true".equalsIgnoreCase((String) obj); + } + } + + private String getFirstValue(List<Object> list) { if (list == null) { return null; } if (list.size() > 0) { - return list.get(0); + return (String) list.get(0); } return null; } diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/projects/ProjectRestImplTest.java b/rest-api/src/test/java/lcsb/mapviewer/api/projects/ProjectRestImplTest.java index 97482c221658f95a21ec2112e04bc8b5b9f06757..f7bfb87b87c29fba1c290f12b0373a8bcb152a45 100644 --- a/rest-api/src/test/java/lcsb/mapviewer/api/projects/ProjectRestImplTest.java +++ b/rest-api/src/test/java/lcsb/mapviewer/api/projects/ProjectRestImplTest.java @@ -2,6 +2,7 @@ package lcsb.mapviewer.api.projects; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; @@ -9,6 +10,7 @@ import static org.mockito.Mockito.times; import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -19,6 +21,8 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; import com.google.gson.Gson; @@ -28,6 +32,10 @@ import lcsb.mapviewer.api.RestTestFunctions; import lcsb.mapviewer.common.exception.InvalidArgumentException; import lcsb.mapviewer.converter.graphics.PdfImageGenerator; import lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser; +import lcsb.mapviewer.converter.zip.ImageZipEntryFile; +import lcsb.mapviewer.converter.zip.LayoutZipEntryFile; +import lcsb.mapviewer.converter.zip.ModelZipEntryFile; +import lcsb.mapviewer.converter.zip.ZipEntryFile; import lcsb.mapviewer.model.Project; import lcsb.mapviewer.model.cache.FileEntry; import lcsb.mapviewer.model.map.MiriamType; @@ -36,222 +44,260 @@ import lcsb.mapviewer.services.interfaces.IModelService; import lcsb.mapviewer.services.interfaces.IProjectService; public class ProjectRestImplTest extends RestTestFunctions { - Logger logger = Logger.getLogger(ProjectRestImplTest.class); - - @Autowired - ProjectRestImpl _projectRestImpl; - - @Autowired - IModelService modelService; - - @AfterClass - public static void tearDownAfterClass() throws Exception { - } - - @Before - public void setUp() throws Exception { - } - - @After - public void tearDown() throws Exception { - } - - @Test - public void testGetModelAsImageForInvalidConverter() throws Exception { - try { - ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); - projectRest.getModelAsImage(token.getId(), "sample", "0", "", "", "", "", ""); - fail("Exception expected"); - } catch (InvalidArgumentException e) { - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - @Test - public void testGetModelAsImage() throws Exception { - try { - ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); - FileEntry result = projectRest.getModelAsImage(token.getId(), "sample", "0", PdfImageGenerator.class.getCanonicalName(), "", "", "", ""); - assertNotNull(result); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - @Test - public void testGetModelDataDependencies() throws Exception { - try { - ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); - ProjectMetaData result = projectRest.getProject("sample", token.getId()); - Gson gson = new Gson(); - assertNotNull(gson.toJson(result)); - Mockito.verify(projectRest.getModelService(), times(0)).getLastModelByProjectId(anyString(), any()); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - @Test(expected = ObjectNotFoundException.class) - public void testGetInvalidMetaData() throws Exception { - ProjectRestImpl projectRest = createMockProjectRest(null); - projectRest.getProject("unknown_model_id", token.getId()); - } - - @Test - public void testGetModelAsImage2() throws Exception { - try { - ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); - projectRest.getModelAsImage(token.getId(), "sample", "0", PdfImageGenerator.class.getCanonicalName(), "", "", "", ""); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - @Test - public void testGetModelAsFileModel() throws Exception { - try { - ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); - projectRest.getModelAsModelFile(token.getId(), "sample", "0", "", "", "", "", ""); - fail("Exception expected"); - } catch (QueryException e) { - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - @Test - public void testGetModelAsFileModel2() throws Exception { - try { - ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); - projectRest.getModelAsModelFile(token.getId(), "sample", "0", CellDesignerXmlParser.class.getCanonicalName(), "", "", "", "0,0;90,0;90,90;90,0"); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - @Test - public void testGetModelAsFileModel3() throws Exception { - try { - ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); - projectRest.getModelAsModelFile(token.getId(), "sample", "0", "", "", "", "", "0,0;90,0;90,90;90,0"); - fail("Exception expected"); - } catch (QueryException e) { - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - @Test - public void testGetProject() throws Exception { - try { - ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); - ProjectMetaData result = projectRest.getProject("sample", token.getId()); - Gson gson = new Gson(); - assertNotNull(gson.toJson(result)); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - @Test - public void testUpdateProject() throws Exception { - try { - ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); - Map<String,String> disease = new HashMap<>(); - disease.put("type",MiriamType.MESH_2012.name()); - disease.put("resource", "D010300"); - Map<String, Object> data = new HashMap<>(); - data.put("version", "1"); - data.put("name", "test"); - data.put("organism", null); - data.put("disease", disease); - data.put("projectId", "sample"); - data.put("id", "0"); - projectRest.updateProject(adminToken.getId(), "sample", data); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - @Test - public void testGetProjects() throws Exception { - try { - ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); - List<ProjectMetaData> result = projectRest.getProjects(token.getId()); - Gson gson = new Gson(); - assertNotNull(gson.toJson(result)); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - @Test - public void testGetStatistics() throws Exception { - try { - ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); - Map<String, Object> result = projectRest.getStatistics("sample", token.getId()); - Gson gson = new Gson(); - assertNotNull(gson.toJson(result)); - - Map<?, ?> elementAnnotations = (Map<?, ?>) result.get("elementAnnotations"); - assertEquals(elementAnnotations.get(MiriamType.CAS), 0); - assertEquals(elementAnnotations.get(MiriamType.ENTREZ), 1); - - Map<?, ?> reactionAnnotations = (Map<?, ?>) result.get("reactionAnnotations"); - assertEquals(reactionAnnotations.get(MiriamType.ENTREZ), 0); - assertEquals(reactionAnnotations.get(MiriamType.PUBMED), 1); - - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - @Test - public void testGetMetaDataForComplexWithImages() throws Exception { - try { - ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/complex_model_with_submaps.zip"); - ProjectMetaData result = projectRest.getProject("sample", token.getId()); - Gson gson = new Gson(); - assertNotNull(gson.toJson(result)); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - private ProjectRestImpl createMockProjectRest(String string) throws Exception { - Model model = null; - Project project = null; - if (string != null) { - project = new Project(); - model = super.getModelForFile(string, true); - project.addModel(model); - project.setProjectId(model.getName()); - } - IModelService mockModelService = Mockito.mock(IModelService.class); - Mockito.when(mockModelService.getLastModelByProjectId(anyString(), any())).thenReturn(model); - _projectRestImpl.setModelService(mockModelService); - - IProjectService projectServiceMock = Mockito.mock(IProjectService.class); - Mockito.when(projectServiceMock.getProjectByProjectId(anyString(), any())).thenReturn(project); - List<Project> projects = new ArrayList<>(); - projects.add(project); - Mockito.when(projectServiceMock.getAllProjects(any())).thenReturn(projects); - _projectRestImpl.setProjectService(projectServiceMock); - - return _projectRestImpl; - } + Logger logger = Logger.getLogger(ProjectRestImplTest.class); + + @Autowired + ProjectRestImpl _projectRestImpl; + + @Autowired + IModelService modelService; + + @AfterClass + public static void tearDownAfterClass() throws Exception { + } + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testGetModelAsImageForInvalidConverter() throws Exception { + try { + ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); + projectRest.getModelAsImage(token.getId(), "sample", "0", "", "", "", "", ""); + fail("Exception expected"); + } catch (InvalidArgumentException e) { + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testGetModelAsImage() throws Exception { + try { + ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); + FileEntry result = projectRest.getModelAsImage(token.getId(), "sample", "0", + PdfImageGenerator.class.getCanonicalName(), "", "", "", ""); + assertNotNull(result); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testGetModelDataDependencies() throws Exception { + try { + ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); + ProjectMetaData result = projectRest.getProject("sample", token.getId()); + Gson gson = new Gson(); + assertNotNull(gson.toJson(result)); + Mockito.verify(projectRest.getModelService(), times(0)).getLastModelByProjectId(anyString(), any()); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test(expected = ObjectNotFoundException.class) + public void testGetInvalidMetaData() throws Exception { + ProjectRestImpl projectRest = createMockProjectRest(null); + projectRest.getProject("unknown_model_id", token.getId()); + } + + @Test + public void testGetModelAsImage2() throws Exception { + try { + ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); + projectRest.getModelAsImage(token.getId(), "sample", "0", PdfImageGenerator.class.getCanonicalName(), "", "", "", + ""); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testGetModelAsFileModel() throws Exception { + try { + ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); + projectRest.getModelAsModelFile(token.getId(), "sample", "0", "", "", "", "", ""); + fail("Exception expected"); + } catch (QueryException e) { + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testGetModelAsFileModel2() throws Exception { + try { + ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); + projectRest.getModelAsModelFile(token.getId(), "sample", "0", CellDesignerXmlParser.class.getCanonicalName(), "", + "", "", "0,0;90,0;90,90;90,0"); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testGetModelAsFileModel3() throws Exception { + try { + ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); + projectRest.getModelAsModelFile(token.getId(), "sample", "0", "", "", "", "", "0,0;90,0;90,90;90,0"); + fail("Exception expected"); + } catch (QueryException e) { + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testGetProject() throws Exception { + try { + ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); + ProjectMetaData result = projectRest.getProject("sample", token.getId()); + Gson gson = new Gson(); + assertNotNull(gson.toJson(result)); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testUpdateProject() throws Exception { + try { + ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); + Map<String, String> disease = new HashMap<>(); + disease.put("type", MiriamType.MESH_2012.name()); + disease.put("resource", "D010300"); + Map<String, Object> data = new HashMap<>(); + data.put("version", "1"); + data.put("name", "test"); + data.put("organism", null); + data.put("disease", disease); + data.put("projectId", "sample"); + data.put("id", "0"); + projectRest.updateProject(adminToken.getId(), "sample", data); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testGetProjects() throws Exception { + try { + ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); + List<ProjectMetaData> result = projectRest.getProjects(token.getId()); + Gson gson = new Gson(); + assertNotNull(gson.toJson(result)); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testGetStatistics() throws Exception { + try { + ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); + Map<String, Object> result = projectRest.getStatistics("sample", token.getId()); + Gson gson = new Gson(); + assertNotNull(gson.toJson(result)); + + Map<?, ?> elementAnnotations = (Map<?, ?>) result.get("elementAnnotations"); + assertEquals(elementAnnotations.get(MiriamType.CAS), 0); + assertEquals(elementAnnotations.get(MiriamType.ENTREZ), 1); + + Map<?, ?> reactionAnnotations = (Map<?, ?>) result.get("reactionAnnotations"); + assertEquals(reactionAnnotations.get(MiriamType.ENTREZ), 0); + assertEquals(reactionAnnotations.get(MiriamType.PUBMED), 1); + + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testGetMetaDataForComplexWithImages() throws Exception { + try { + ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/complex_model_with_submaps.zip"); + ProjectMetaData result = projectRest.getProject("sample", token.getId()); + Gson gson = new Gson(); + assertNotNull(gson.toJson(result)); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testExtractZipEntries() throws Exception { + try { + MultiValueMap<String, Object> data = new LinkedMultiValueMap<>(); + data.put("zip-entries[0][_type]",createLinkedList("MAP")); + data.put("zip-entries[0][_filename]",createLinkedList("main.xml")); + data.put("zip-entries[0][_data][root]",createLinkedList("true")); + data.put("zip-entries[0][_data][name]",createLinkedList("main")); + data.put("zip-entries[0][_data][type][id]",createLinkedList("UNKNOWN")); + data.put("zip-entries[0][_data][type][name]",createLinkedList("Unknown")); + data.put("zip-entries[1][_type]",createLinkedList("OVERLAY")); + data.put("zip-entries[1][_filename]",createLinkedList("layouts/goodschema.txt")); + data.put("zip-entries[1][_data][name]",createLinkedList("example name")); + data.put("zip-entries[1][_data][description]",createLinkedList("layout description")); + data.put("zip-entries[2][_type]",createLinkedList("IMAGE")); + data.put("zip-entries[2][_filename]",createLinkedList("images/test.png")); + List<ZipEntryFile> result = _projectRestImpl.extractZipEntries(data); + assertNotNull(result); + assertEquals(3, result.size()); + assertTrue(result.get(0) instanceof ModelZipEntryFile); + assertTrue(result.get(1) instanceof LayoutZipEntryFile); + assertTrue(result.get(2) instanceof ImageZipEntryFile); + + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + private LinkedList<Object> createLinkedList(Object string) { + LinkedList<Object> result = new LinkedList<>(); + result.add(string); + return result; + } + + private ProjectRestImpl createMockProjectRest(String string) throws Exception { + Model model = null; + Project project = null; + if (string != null) { + project = new Project(); + model = super.getModelForFile(string, true); + project.addModel(model); + project.setProjectId(model.getName()); + } + IModelService mockModelService = Mockito.mock(IModelService.class); + Mockito.when(mockModelService.getLastModelByProjectId(anyString(), any())).thenReturn(model); + _projectRestImpl.setModelService(mockModelService); + + IProjectService projectServiceMock = Mockito.mock(IProjectService.class); + Mockito.when(projectServiceMock.getProjectByProjectId(anyString(), any())).thenReturn(project); + List<Project> projects = new ArrayList<>(); + projects.add(project); + Mockito.when(projectServiceMock.getAllProjects(any())).thenReturn(projects); + _projectRestImpl.setProjectService(projectServiceMock); + + return _projectRestImpl; + } }