diff --git a/frontend-js/src/main/js/gui/admin/AddProjectDialog.js b/frontend-js/src/main/js/gui/admin/AddProjectDialog.js index 5811bd86c8e30480f3682a6b2c5893a37006d79b..26dea5dfd6dd9bdc3a4793fc5dead2f571d1f640 100644 --- a/frontend-js/src/main/js/gui/admin/AddProjectDialog.js +++ b/frontend-js/src/main/js/gui/admin/AddProjectDialog.js @@ -590,7 +590,10 @@ AddProjectDialog.prototype.onSaveClicked = function () { "disease": self.getDisease(), "organism": self.getOrganism(), "sbgn": self.isSbgn(), - "semantic-zoom": self.isSemanticZooming() + "semantic-zoom": self.isSemanticZooming(), + "annotate": self.isAnnotateAutomatically(), + "verify-annotations": self.isVerifyAnnotations(), + }; return ServerConnector.addProject(options); }); 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 652a49ce9eec5e368d1d683c4a2fc983172d534c..b788a8feb8c46cccf085cc3aacc6986f40341f21 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 @@ -62,6 +62,7 @@ import lcsb.mapviewer.model.user.PrivilegeType; import lcsb.mapviewer.model.user.User; import lcsb.mapviewer.services.SecurityException; import lcsb.mapviewer.services.interfaces.ILayoutService; +import lcsb.mapviewer.services.interfaces.IProjectService; import lcsb.mapviewer.services.utils.ColorSchemaReader; import lcsb.mapviewer.services.utils.CreateProjectParams; import lcsb.mapviewer.services.utils.data.BuildInLayout; @@ -72,483 +73,500 @@ import lcsb.mapviewer.services.view.OverviewImageViewFactory; @Transactional(value = "txManager") public class ProjectRestImpl extends BaseRestImpl { - /** - * Constant defining size of the array returned by - * {@link PathIterator#currentSegment(double[])} method. More nformation can - * be found <a href= - * "http://docs.oracle.com/javase/7/docs/api/java/awt/geom/PathIterator.html#currentSegment(double[])" - * >here</a> - */ - private static final int PATH_ITERATOR_SEGMENT_SIZE = 6; - - /** - * Default class logger. - */ - private Logger logger = Logger.getLogger(ProjectRestImpl.class); - - @Autowired - private PublicationsRestImpl publicationsRestImpl; - - @Autowired - private ILayoutService layoutService; - - @Autowired - private OverviewImageViewFactory factory; - - public ProjectMetaData getProject(String projectId, String token) throws SecurityException, ObjectNotFoundException { - AuthenticationToken authenticationToken = getUserService().getToken(token); - Project project = getProjectService().getProjectByProjectId(projectId, authenticationToken); - if (project == null) { - throw new ObjectNotFoundException("Project with given id doesn't exist"); - } - ProjectMetaData result = createData(project); - return result; - } - - private ProjectMetaData createData(Project project) { - ProjectMetaData result = new ProjectMetaData(); - - result.setName(project.getName()); - result.setProjectId(project.getProjectId()); - result.setIdObject(project.getId()); - result.setVersion(project.getVersion()); - result.setNotifyEmail(project.getNotifyEmail()); - if (project.getStatus() != null) { - result.setStatus(project.getStatus().toString()); - } - result.setProgress(project.getProgress()); - - result.setOverviewImageViews(factory.createList(project.getOverviewImages())); - - Set<OverviewImage> set = new HashSet<>(); - set.addAll(project.getOverviewImages()); - for (OverviewImage image : project.getOverviewImages()) { - for (OverviewLink ol : image.getLinks()) { - if (ol instanceof OverviewImageLink) { - set.remove(((OverviewImageLink) ol).getLinkedOverviewImage()); - } - } - } - if (set.size() > 0) { - result.setTopOverviewImage(factory.create(set.iterator().next())); - } else if (project.getOverviewImages().size() > 0) { - logger.warn("Cannot determine top level image. Taking first one. " + project.getOverviewImages().get(0).getFilename()); - result.setTopOverviewImage(factory.create(project.getOverviewImages().get(0))); - } - - if (project.getOrganism() != null) { - result.setOrganism(createAnnotation(project.getOrganism())); - } - if (project.getDisease() != null) { - result.setDisease(createAnnotation(project.getDisease())); - } - - return result; - } - - /** - * @return the factory - * @see #factory - */ - public OverviewImageViewFactory getFactory() { - return factory; - } - - /** - * @param factory - * the factory to set - * @see #factory - */ - public void setFactory(OverviewImageViewFactory factory) { - this.factory = factory; - } - - public FileEntry getSource(String token, String projectId) throws SecurityException, QueryException { - AuthenticationToken authenticationToken = getUserService().getToken(token); - Project project = getProjectService().getProjectByProjectId(projectId, authenticationToken); - if (project == null) { - throw new ObjectNotFoundException("Project with given id doesn't exist"); - } - return project.getInputData(); - } - - public FileEntry getModelAsImage(String token, String projectId, String modelId, String handlerClass, String backgroundOverlayId, String overlayIds, - String zoomLevel, String polygonString) - throws SecurityException, QueryException, IOException, InvalidColorSchemaException, CommandExecutionException, DrawingException { - AuthenticationToken authenticationToken = getUserService().getToken(token); - User user = getUserService().getUserByToken(authenticationToken); - - Model topModel = getModelService().getLastModelByProjectId(projectId, authenticationToken); - if (topModel == null) { - throw new ObjectNotFoundException("Project with given id doesn't exist"); - } - - Model originalModel = topModel.getSubmodelById(modelId); - - if (originalModel == null) { - throw new ObjectNotFoundException("Model with given id doesn't exist"); - } - - Layout overlay = null; - if (!backgroundOverlayId.equals("")) { - overlay = topModel.getLayoutByIdentifier(Integer.valueOf(backgroundOverlayId)); - - if (overlay == null) { - throw new ObjectNotFoundException("Unknown overlay in model. Layout.id=" + backgroundOverlayId); - } - } else { - if (topModel.getLayouts().size() > 0) { - overlay = topModel.getLayouts().get(0); - } - } - - Model colorModel = new CopyCommand(originalModel).execute(); - if (overlay != null) { - if (overlay.getInputData() != null) { - ColorSchemaReader reader = new ColorSchemaReader(); - Collection<ColorSchema> schemas = reader.readColorSchema(overlay.getInputData().getFileContent()); - - new ColorModelCommand(colorModel, schemas, getUserService().getColorExtractorForUser(user)).execute(); - } else if (overlay.getTitle().equals(BuildInLayout.CLEAN.getTitle())) { - // this might not return true if we change CLEAN.title in future... - - // if it's clean then remove coloring - new ClearColorModelCommand(colorModel).execute(); - } else if (overlay.isHierarchicalView()) { - new SetFixedHierarchyLevelCommand(colorModel, overlay.getHierarchyViewLevel()).execute(); - } - } - - Integer level = Configuration.MIN_ZOOM_LEVEL; - if (!zoomLevel.equals("")) { - level = Integer.valueOf(zoomLevel); - } - - // transform polygon - CoordinationConverter cc = new CoordinationConverter(colorModel); - Double minX = originalModel.getWidth(); - Double minY = originalModel.getHeight(); - Double maxX = 0.0; - Double maxY = 0.0; - Path2D polygon = cc.latLngToPolygon(polygonString); - - PathIterator pathIter = polygon.getPathIterator(null); - while (!pathIter.isDone()) { - final double[] segment = new double[PATH_ITERATOR_SEGMENT_SIZE]; - if (pathIter.currentSegment(segment) != PathIterator.SEG_CLOSE) { - minX = Math.min(minX, segment[0]); - maxX = Math.max(maxX, segment[0]); - minY = Math.min(minY, segment[1]); - maxY = Math.max(maxY, segment[1]); - } - pathIter.next(); - } - - maxX = Math.min(originalModel.getWidth(), maxX); - maxY = Math.min(originalModel.getHeight(), maxY); - minX = Math.max(0.0, minX); - minY = Math.max(0.0, minY); - - Double scale = Math.max(originalModel.getHeight(), originalModel.getWidth()) / (originalModel.getTileSize()); - - for (int i = level; i > Configuration.MIN_ZOOM_LEVEL; i--) { - scale /= 2; - } - - ColorExtractor colorExtractor = getUserService().getColorExtractorForUser(user); - - Params params = new Params().// - x(minX).// - y(minY).// - height((maxY - minY) / scale).// - width((maxX - minX) / scale).// - level(level - Configuration.MIN_ZOOM_LEVEL).// - nested(false).// automatically set nested view as invalid - scale(scale).// - colorExtractor(colorExtractor).// - sbgn(topModel.getProject().isSbgnFormat()).// - model(colorModel); - if (overlay != null) { - params.nested(overlay.isHierarchicalView()); - } - List<Integer> visibleLayoutIds = deserializeIdList(overlayIds); - for (Integer integer : visibleLayoutIds) { - Map<Object, ColorSchema> map = layoutService.getElementsForLayout(colorModel, integer, authenticationToken); - params.addVisibleLayout(map); - } - - ImageGenerators imageGenerator = new ImageGenerators(); - String extension = imageGenerator.getExtension(handlerClass); - File file = File.createTempFile("map", "." + extension); - - imageGenerator.generate(handlerClass, params, file.getAbsolutePath()); - - FileEntry entry = new UploadedFileEntry(); - entry.setOriginalFileName("map." + extension); - entry.setFileContent(IOUtils.toByteArray(new FileInputStream(file))); - file.delete(); - return entry; - - } - - private List<Integer> deserializeIdList(String overlayIds) { - List<Integer> result = new ArrayList<>(); - String[] tmp = overlayIds.split(","); - for (String string : tmp) { - if (!string.equals("")) { - result.add(Integer.valueOf(string)); - } - } - return result; - } - - public FileEntry getModelAsModelFile(String token, String projectId, String modelId, String handlerClass, String backgroundOverlayId, String overlayIds, - String zoomLevel, String polygonString) throws SecurityException, QueryException, IOException, InvalidColorSchemaException, CommandExecutionException, - ConverterException, InconsistentModelException { - AuthenticationToken authenticationToken = getUserService().getToken(token); - - Model topModel = getModelService().getLastModelByProjectId(projectId, authenticationToken); - if (topModel == null) { - throw new ObjectNotFoundException("Project with given id doesn't exist"); - } - - Model originalModel = topModel.getSubmodelById(modelId); - - if (originalModel == null) { - throw new ObjectNotFoundException("Model with given id doesn't exist"); - } - - CoordinationConverter cc = new CoordinationConverter(originalModel); - Path2D polygon = cc.latLngToPolygon(polygonString); - - // create model bounded by the polygon - SubModelCommand subModelCommand = new SubModelCommand(originalModel, polygon); - Model part = subModelCommand.execute(); - - IConverter parser = getModelParser(handlerClass); - InputStream is = parser.exportModelToInputStream(part); - - String fileExtension = parser.getFileExtension(); - - FileEntry entry = new UploadedFileEntry(); - entry.setOriginalFileName("model." + fileExtension); - entry.setFileContent(IOUtils.toByteArray(is)); - return entry; - - } - - public Map<String, Object> getStatistics(String projectId, String token) throws SecurityException, ObjectNotFoundException { - Map<String, Object> result = new HashMap<String, Object>(); - AuthenticationToken authenticationToken = getUserService().getToken(token); - - Model model = getModelService().getLastModelByProjectId(projectId, authenticationToken); - if (model == null) { - throw new ObjectNotFoundException("Project with given id doesn't exist"); - } - - Map<MiriamType, Integer> elementAnnotations = new HashMap<>(); - for (MiriamType mt : MiriamType.values()) { - elementAnnotations.put(mt, 0); - } - Set<Model> models = new HashSet<>(); - models.add(model); - models.addAll(model.getSubmodels()); - - for (Model model2 : models) { - for (Element alias : model2.getElements()) { - for (MiriamData md : alias.getMiriamData()) { - Integer amount = elementAnnotations.get(md.getDataType()); - amount += 1; - elementAnnotations.put(md.getDataType(), amount); - } - } - } - result.put("elementAnnotations", elementAnnotations); - - Map<MiriamType, Integer> reactionAnnotations = new HashMap<>(); - for (MiriamType mt : MiriamType.values()) { - reactionAnnotations.put(mt, 0); - } - for (Model model2 : models) { - for (Reaction reaction : model2.getReactions()) { - for (MiriamData md : reaction.getMiriamData()) { - Integer amount = reactionAnnotations.get(md.getDataType()); - amount += 1; - reactionAnnotations.put(md.getDataType(), amount); - } - } - } - - result.put("reactionAnnotations", reactionAnnotations); - - result.put("publications", publicationsRestImpl.getPublications(models).size()); - - return result; - } - - public List<ProjectMetaData> getProjects(String token) throws SecurityException { - AuthenticationToken authenticationToken = getUserService().getToken(token); - List<Project> projects = getProjectService().getAllProjects(authenticationToken); - List<ProjectMetaData> result = new ArrayList<>(); - for (Project project : projects) { - result.add(createData(project)); - } - return result; - } - - public ProjectMetaData updateProject(String token, String projectId, Map<String, Object> data) throws SecurityException, QueryException { - AuthenticationToken authenticationToken = getUserService().getToken(token); - Project project = getProjectService().getProjectByProjectId(projectId, authenticationToken); - if (project == null) { - throw new ObjectNotFoundException("Project with given id doesn't exist"); - } - boolean canModify = getUserService().userHasPrivilege(authenticationToken, PrivilegeType.ADD_MAP); - if (!canModify) { - throw new SecurityException("You cannot update projects"); - } - Set<String> fields = data.keySet(); - for (String fieldName : fields) { - Object value = data.get(fieldName); - String stringValue = null; - if (value instanceof String) { - stringValue = (String) value; - } - if (fieldName.equalsIgnoreCase("version")) { - project.setVersion((String) value); - } else if (fieldName.equalsIgnoreCase("id")) { - try { - int id = Integer.parseInt(stringValue); - if (id != project.getId()) { - throw new QueryException("Invalid id: " + stringValue); - } - } catch (NumberFormatException e) { - throw new QueryException("Invalid id: " + stringValue); - } - } else if (fieldName.equalsIgnoreCase("projectId")) { - if (!project.getProjectId().equalsIgnoreCase(stringValue)) { - throw new QueryException("You cannot modify projectId"); - } - } else if (fieldName.equalsIgnoreCase("name")) { - project.setName((String) value); - } else if (fieldName.equalsIgnoreCase("notifyEmail")) { - project.setNotifyEmail(stringValue); - } else if (fieldName.equalsIgnoreCase("organism")) { - MiriamData organism = updateMiriamData(project.getOrganism(), value); - project.setOrganism(organism); - } else if (fieldName.equalsIgnoreCase("disease")) { - MiriamData disease = updateMiriamData(project.getDisease(), value); - project.setDisease(disease); - } else { - throw new QueryException("Unknown field: " + fieldName); - } - } - getProjectService().updateProject(project); - return getProject(projectId, token); - } - - private MiriamData updateMiriamData(MiriamData organism, Object res) { - if (res == null) { - return null; - } - if (organism == null) { - organism = new MiriamData(); - } - - if (res instanceof Map) { - @SuppressWarnings("unchecked") - Map<String, Object> map = (Map<String, Object>) res; - organism.setDataType(MiriamType.valueOf((String) map.get("type"))); - organism.setResource((String) map.get("resource")); - return organism; - } else { - throw new InvalidArgumentException("invalid miriamdData: " + res); - } - } - - public ProjectMetaData addProject(String token, String projectId, MultiValueMap<String, String> data, String path) - throws SecurityException, QueryException, IOException { - AuthenticationToken authenticationToken = getUserService().getToken(token); - User user = getUserService().getUserByToken(authenticationToken); - Project project = getProjectService().getProjectByProjectId(projectId, authenticationToken); - if (project != null) { - throw new ObjectExistsException("Project with given id already exists"); - } - CreateProjectParams params = new CreateProjectParams(); - String directory = path + "/../map_images/" + md5(projectId) + "/"; - String fileContent = getFirstValue(data.get("file-content")); - if (fileContent == null) { - throw new QueryException("file-content is obligatory"); - } - String parserClass = getFirstValue(data.get("parser")); - if (parserClass == null) { - throw new QueryException("parser is obligatory"); - } - IConverter parser = getModelParser(parserClass); - - params.addUser(user.getLogin(), null); - params.async(true); - params.parser(parser); - params.authenticationToken(authenticationToken); - params.autoResize(getFirstValue(data.get("auto-resize"))); - params.cacheModel(getFirstValue(data.get("cache"))); - params.description(getFirstValue(data.get("description"))); - params.images(true); - 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.projectId(projectId); - params.projectName(getFirstValue(data.get("name"))); - params.projectOrganism(getFirstValue(data.get("organism"))); - params.sbgnFormat(getFirstValue(data.get("sbgn"))); - params.semanticZoom(getFirstValue(data.get("semantic-zoom"))); - params.version(getFirstValue(data.get("version"))); - - getProjectService().createProject(params); - return getProject(projectId, token); - } - - private String getFirstValue(List<String> list) { - if (list == null) { - return null; - } - if (list.size() > 0) { - return list.get(0); - } - return null; - } - - /** - * Method that computes md5 hash for a given {@link String}. - * - * @param data - * input string - * @return md5 hash for input string - */ - private String md5(String data) { - try { - MessageDigest md = MessageDigest.getInstance("MD5"); - byte[] mdbytes = md.digest(data.getBytes()); - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < mdbytes.length; i++) { - // CHECKSTYLE:OFF - // this magic formula transforms int into hex value - sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1)); - // CHECKSTYLE:ON - } - return sb.toString(); - } catch (NoSuchAlgorithmException e) { - logger.fatal("Problem with instance of MD5 encoder", e); - } - - return null; - } - - public ProjectMetaData removeProject(String token, String projectId, String path) throws ObjectNotFoundException, SecurityException { - AuthenticationToken authenticationToken = getUserService().getToken(token); - Project project = getProjectService().getProjectByProjectId(projectId, authenticationToken); - getProjectService().removeProject(project, path, true, authenticationToken); - return getProject(projectId, token); - } + /** + * Constant defining size of the array returned by + * {@link PathIterator#currentSegment(double[])} method. More nformation can be + * found <a href= + * "http://docs.oracle.com/javase/7/docs/api/java/awt/geom/PathIterator.html#currentSegment(double[])" + * >here</a> + */ + private static final int PATH_ITERATOR_SEGMENT_SIZE = 6; + + /** + * Default class logger. + */ + private Logger logger = Logger.getLogger(ProjectRestImpl.class); + + @Autowired + private PublicationsRestImpl publicationsRestImpl; + + @Autowired + private ILayoutService layoutService; + + @Autowired + private IProjectService projectService; + + @Autowired + private OverviewImageViewFactory factory; + + public ProjectMetaData getProject(String projectId, String token) throws SecurityException, ObjectNotFoundException { + AuthenticationToken authenticationToken = getUserService().getToken(token); + Project project = getProjectService().getProjectByProjectId(projectId, authenticationToken); + if (project == null) { + throw new ObjectNotFoundException("Project with given id doesn't exist"); + } + ProjectMetaData result = createData(project); + return result; + } + + private ProjectMetaData createData(Project project) { + ProjectMetaData result = new ProjectMetaData(); + + result.setName(project.getName()); + result.setProjectId(project.getProjectId()); + result.setIdObject(project.getId()); + result.setVersion(project.getVersion()); + result.setNotifyEmail(project.getNotifyEmail()); + if (project.getStatus() != null) { + result.setStatus(project.getStatus().toString()); + } + result.setProgress(project.getProgress()); + + result.setOverviewImageViews(factory.createList(project.getOverviewImages())); + + Set<OverviewImage> set = new HashSet<>(); + set.addAll(project.getOverviewImages()); + for (OverviewImage image : project.getOverviewImages()) { + for (OverviewLink ol : image.getLinks()) { + if (ol instanceof OverviewImageLink) { + set.remove(((OverviewImageLink) ol).getLinkedOverviewImage()); + } + } + } + if (set.size() > 0) { + result.setTopOverviewImage(factory.create(set.iterator().next())); + } else if (project.getOverviewImages().size() > 0) { + logger.warn( + "Cannot determine top level image. Taking first one. " + project.getOverviewImages().get(0).getFilename()); + result.setTopOverviewImage(factory.create(project.getOverviewImages().get(0))); + } + + if (project.getOrganism() != null) { + result.setOrganism(createAnnotation(project.getOrganism())); + } + if (project.getDisease() != null) { + result.setDisease(createAnnotation(project.getDisease())); + } + + return result; + } + + /** + * @return the factory + * @see #factory + */ + public OverviewImageViewFactory getFactory() { + return factory; + } + + /** + * @param factory + * the factory to set + * @see #factory + */ + public void setFactory(OverviewImageViewFactory factory) { + this.factory = factory; + } + + public FileEntry getSource(String token, String projectId) throws SecurityException, QueryException { + AuthenticationToken authenticationToken = getUserService().getToken(token); + Project project = getProjectService().getProjectByProjectId(projectId, authenticationToken); + if (project == null) { + throw new ObjectNotFoundException("Project with given id doesn't exist"); + } + return project.getInputData(); + } + + public FileEntry getModelAsImage(String token, String projectId, String modelId, String handlerClass, + String backgroundOverlayId, String overlayIds, String zoomLevel, String polygonString) throws SecurityException, + QueryException, IOException, InvalidColorSchemaException, CommandExecutionException, DrawingException { + AuthenticationToken authenticationToken = getUserService().getToken(token); + User user = getUserService().getUserByToken(authenticationToken); + + Model topModel = getModelService().getLastModelByProjectId(projectId, authenticationToken); + if (topModel == null) { + throw new ObjectNotFoundException("Project with given id doesn't exist"); + } + + Model originalModel = topModel.getSubmodelById(modelId); + + if (originalModel == null) { + throw new ObjectNotFoundException("Model with given id doesn't exist"); + } + + Layout overlay = null; + if (!backgroundOverlayId.equals("")) { + overlay = topModel.getLayoutByIdentifier(Integer.valueOf(backgroundOverlayId)); + + if (overlay == null) { + throw new ObjectNotFoundException("Unknown overlay in model. Layout.id=" + backgroundOverlayId); + } + } else { + if (topModel.getLayouts().size() > 0) { + overlay = topModel.getLayouts().get(0); + } + } + + Model colorModel = new CopyCommand(originalModel).execute(); + if (overlay != null) { + if (overlay.getInputData() != null) { + ColorSchemaReader reader = new ColorSchemaReader(); + Collection<ColorSchema> schemas = reader.readColorSchema(overlay.getInputData().getFileContent()); + + new ColorModelCommand(colorModel, schemas, getUserService().getColorExtractorForUser(user)).execute(); + } else if (overlay.getTitle().equals(BuildInLayout.CLEAN.getTitle())) { + // this might not return true if we change CLEAN.title in future... + + // if it's clean then remove coloring + new ClearColorModelCommand(colorModel).execute(); + } else if (overlay.isHierarchicalView()) { + new SetFixedHierarchyLevelCommand(colorModel, overlay.getHierarchyViewLevel()).execute(); + } + } + + Integer level = Configuration.MIN_ZOOM_LEVEL; + if (!zoomLevel.equals("")) { + level = Integer.valueOf(zoomLevel); + } + + // transform polygon + CoordinationConverter cc = new CoordinationConverter(colorModel); + Double minX = originalModel.getWidth(); + Double minY = originalModel.getHeight(); + Double maxX = 0.0; + Double maxY = 0.0; + Path2D polygon = cc.latLngToPolygon(polygonString); + + PathIterator pathIter = polygon.getPathIterator(null); + while (!pathIter.isDone()) { + final double[] segment = new double[PATH_ITERATOR_SEGMENT_SIZE]; + if (pathIter.currentSegment(segment) != PathIterator.SEG_CLOSE) { + minX = Math.min(minX, segment[0]); + maxX = Math.max(maxX, segment[0]); + minY = Math.min(minY, segment[1]); + maxY = Math.max(maxY, segment[1]); + } + pathIter.next(); + } + + maxX = Math.min(originalModel.getWidth(), maxX); + maxY = Math.min(originalModel.getHeight(), maxY); + minX = Math.max(0.0, minX); + minY = Math.max(0.0, minY); + + Double scale = Math.max(originalModel.getHeight(), originalModel.getWidth()) / (originalModel.getTileSize()); + + for (int i = level; i > Configuration.MIN_ZOOM_LEVEL; i--) { + scale /= 2; + } + + ColorExtractor colorExtractor = getUserService().getColorExtractorForUser(user); + + Params params = new Params().// + x(minX).// + y(minY).// + height((maxY - minY) / scale).// + width((maxX - minX) / scale).// + level(level - Configuration.MIN_ZOOM_LEVEL).// + nested(false).// automatically set nested view as invalid + scale(scale).// + colorExtractor(colorExtractor).// + sbgn(topModel.getProject().isSbgnFormat()).// + model(colorModel); + if (overlay != null) { + params.nested(overlay.isHierarchicalView()); + } + List<Integer> visibleLayoutIds = deserializeIdList(overlayIds); + for (Integer integer : visibleLayoutIds) { + Map<Object, ColorSchema> map = layoutService.getElementsForLayout(colorModel, integer, authenticationToken); + params.addVisibleLayout(map); + } + + ImageGenerators imageGenerator = new ImageGenerators(); + String extension = imageGenerator.getExtension(handlerClass); + File file = File.createTempFile("map", "." + extension); + + imageGenerator.generate(handlerClass, params, file.getAbsolutePath()); + + FileEntry entry = new UploadedFileEntry(); + entry.setOriginalFileName("map." + extension); + entry.setFileContent(IOUtils.toByteArray(new FileInputStream(file))); + file.delete(); + return entry; + + } + + private List<Integer> deserializeIdList(String overlayIds) { + List<Integer> result = new ArrayList<>(); + String[] tmp = overlayIds.split(","); + for (String string : tmp) { + if (!string.equals("")) { + result.add(Integer.valueOf(string)); + } + } + return result; + } + + public FileEntry getModelAsModelFile(String token, String projectId, String modelId, String handlerClass, + String backgroundOverlayId, String overlayIds, String zoomLevel, String polygonString) + throws SecurityException, QueryException, IOException, InvalidColorSchemaException, CommandExecutionException, + ConverterException, InconsistentModelException { + AuthenticationToken authenticationToken = getUserService().getToken(token); + + Model topModel = getModelService().getLastModelByProjectId(projectId, authenticationToken); + if (topModel == null) { + throw new ObjectNotFoundException("Project with given id doesn't exist"); + } + + Model originalModel = topModel.getSubmodelById(modelId); + + if (originalModel == null) { + throw new ObjectNotFoundException("Model with given id doesn't exist"); + } + + CoordinationConverter cc = new CoordinationConverter(originalModel); + Path2D polygon = cc.latLngToPolygon(polygonString); + + // create model bounded by the polygon + SubModelCommand subModelCommand = new SubModelCommand(originalModel, polygon); + Model part = subModelCommand.execute(); + + IConverter parser = getModelParser(handlerClass); + InputStream is = parser.exportModelToInputStream(part); + + String fileExtension = parser.getFileExtension(); + + FileEntry entry = new UploadedFileEntry(); + entry.setOriginalFileName("model." + fileExtension); + entry.setFileContent(IOUtils.toByteArray(is)); + return entry; + + } + + public Map<String, Object> getStatistics(String projectId, String token) + throws SecurityException, ObjectNotFoundException { + Map<String, Object> result = new HashMap<String, Object>(); + AuthenticationToken authenticationToken = getUserService().getToken(token); + + Model model = getModelService().getLastModelByProjectId(projectId, authenticationToken); + if (model == null) { + throw new ObjectNotFoundException("Project with given id doesn't exist"); + } + + Map<MiriamType, Integer> elementAnnotations = new HashMap<>(); + for (MiriamType mt : MiriamType.values()) { + elementAnnotations.put(mt, 0); + } + Set<Model> models = new HashSet<>(); + models.add(model); + models.addAll(model.getSubmodels()); + + for (Model model2 : models) { + for (Element alias : model2.getElements()) { + for (MiriamData md : alias.getMiriamData()) { + Integer amount = elementAnnotations.get(md.getDataType()); + amount += 1; + elementAnnotations.put(md.getDataType(), amount); + } + } + } + result.put("elementAnnotations", elementAnnotations); + + Map<MiriamType, Integer> reactionAnnotations = new HashMap<>(); + for (MiriamType mt : MiriamType.values()) { + reactionAnnotations.put(mt, 0); + } + for (Model model2 : models) { + for (Reaction reaction : model2.getReactions()) { + for (MiriamData md : reaction.getMiriamData()) { + Integer amount = reactionAnnotations.get(md.getDataType()); + amount += 1; + reactionAnnotations.put(md.getDataType(), amount); + } + } + } + + result.put("reactionAnnotations", reactionAnnotations); + + result.put("publications", publicationsRestImpl.getPublications(models).size()); + + return result; + } + + public List<ProjectMetaData> getProjects(String token) throws SecurityException { + AuthenticationToken authenticationToken = getUserService().getToken(token); + List<Project> projects = getProjectService().getAllProjects(authenticationToken); + List<ProjectMetaData> result = new ArrayList<>(); + for (Project project : projects) { + result.add(createData(project)); + } + return result; + } + + public ProjectMetaData updateProject(String token, String projectId, Map<String, Object> data) + throws SecurityException, QueryException { + AuthenticationToken authenticationToken = getUserService().getToken(token); + Project project = getProjectService().getProjectByProjectId(projectId, authenticationToken); + if (project == null) { + throw new ObjectNotFoundException("Project with given id doesn't exist"); + } + boolean canModify = getUserService().userHasPrivilege(authenticationToken, PrivilegeType.ADD_MAP); + if (!canModify) { + throw new SecurityException("You cannot update projects"); + } + Set<String> fields = data.keySet(); + for (String fieldName : fields) { + Object value = data.get(fieldName); + String stringValue = null; + if (value instanceof String) { + stringValue = (String) value; + } + if (fieldName.equalsIgnoreCase("version")) { + project.setVersion((String) value); + } else if (fieldName.equalsIgnoreCase("id")) { + try { + int id = Integer.parseInt(stringValue); + if (id != project.getId()) { + throw new QueryException("Invalid id: " + stringValue); + } + } catch (NumberFormatException e) { + throw new QueryException("Invalid id: " + stringValue); + } + } else if (fieldName.equalsIgnoreCase("projectId")) { + if (!project.getProjectId().equalsIgnoreCase(stringValue)) { + throw new QueryException("You cannot modify projectId"); + } + } else if (fieldName.equalsIgnoreCase("name")) { + project.setName((String) value); + } else if (fieldName.equalsIgnoreCase("notifyEmail")) { + project.setNotifyEmail(stringValue); + } else if (fieldName.equalsIgnoreCase("organism")) { + MiriamData organism = updateMiriamData(project.getOrganism(), value); + project.setOrganism(organism); + } else if (fieldName.equalsIgnoreCase("disease")) { + MiriamData disease = updateMiriamData(project.getDisease(), value); + project.setDisease(disease); + } else { + throw new QueryException("Unknown field: " + fieldName); + } + } + getProjectService().updateProject(project); + return getProject(projectId, token); + } + + private MiriamData updateMiriamData(MiriamData organism, Object res) { + if (res == null) { + return null; + } + if (organism == null) { + organism = new MiriamData(); + } + + if (res instanceof Map) { + @SuppressWarnings("unchecked") + Map<String, Object> map = (Map<String, Object>) res; + organism.setDataType(MiriamType.valueOf((String) map.get("type"))); + organism.setResource((String) map.get("resource")); + return organism; + } else { + throw new InvalidArgumentException("invalid miriamdData: " + res); + } + } + + public ProjectMetaData addProject(String token, String projectId, MultiValueMap<String, String> data, String path) + throws SecurityException, QueryException, IOException { + AuthenticationToken authenticationToken = getUserService().getToken(token); + User user = getUserService().getUserByToken(authenticationToken); + Project project = getProjectService().getProjectByProjectId(projectId, authenticationToken); + if (project != null) { + throw new ObjectExistsException("Project with given id already exists"); + } + CreateProjectParams params = new CreateProjectParams(); + String directory = path + "/../map_images/" + md5(projectId) + "/"; + String fileContent = getFirstValue(data.get("file-content")); + if (fileContent == null) { + throw new QueryException("file-content is obligatory"); + } + String parserClass = getFirstValue(data.get("parser")); + if (parserClass == null) { + throw new QueryException("parser is obligatory"); + } + IConverter parser = getModelParser(parserClass); + + params.addUser(user.getLogin(), null); + params.async(true); + params.parser(parser); + params.authenticationToken(authenticationToken); + params.autoResize(getFirstValue(data.get("auto-resize"))); + params.cacheModel(getFirstValue(data.get("cache"))); + params.description(getFirstValue(data.get("description"))); + params.images(true); + 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.projectId(projectId); + params.projectName(getFirstValue(data.get("name"))); + params.projectOrganism(getFirstValue(data.get("organism"))); + params.sbgnFormat(getFirstValue(data.get("sbgn"))); + params.semanticZoom(getFirstValue(data.get("semantic-zoom"))); + params.version(getFirstValue(data.get("version"))); + params.annotations(getFirstValue(data.get("annotate"))); + if (params.isUpdateAnnotations()) { + params.annotatorsMap(projectService.createClassAnnotatorTree(user)); + } + params.analyzeAnnotations(getFirstValue(data.get("verify-annotations"))); + if (params.isAnalyzeAnnotations()) { + params.requiredAnnotations(projectService.createClassAnnotatorTree(user)); + params.validAnnotations(projectService.createClassAnnotatorTree(user)); + } + + getProjectService().createProject(params); + return getProject(projectId, token); + } + + private String getFirstValue(List<String> list) { + if (list == null) { + return null; + } + if (list.size() > 0) { + return list.get(0); + } + return null; + } + + /** + * Method that computes md5 hash for a given {@link String}. + * + * @param data + * input string + * @return md5 hash for input string + */ + private String md5(String data) { + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] mdbytes = md.digest(data.getBytes()); + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < mdbytes.length; i++) { + // CHECKSTYLE:OFF + // this magic formula transforms int into hex value + sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1)); + // CHECKSTYLE:ON + } + return sb.toString(); + } catch (NoSuchAlgorithmException e) { + logger.fatal("Problem with instance of MD5 encoder", e); + } + + return null; + } + + public ProjectMetaData removeProject(String token, String projectId, String path) + throws ObjectNotFoundException, SecurityException { + AuthenticationToken authenticationToken = getUserService().getToken(token); + Project project = getProjectService().getProjectByProjectId(projectId, authenticationToken); + getProjectService().removeProject(project, path, true, authenticationToken); + return getProject(projectId, token); + } } diff --git a/service/src/main/java/lcsb/mapviewer/services/utils/CreateProjectParams.java b/service/src/main/java/lcsb/mapviewer/services/utils/CreateProjectParams.java index 69b792a9bb8d1ed9d4a8e1641c76927df4afb7a6..a1f3ab33bcb611c39b4a409d0dbcec2429ec1a0e 100644 --- a/service/src/main/java/lcsb/mapviewer/services/utils/CreateProjectParams.java +++ b/service/src/main/java/lcsb/mapviewer/services/utils/CreateProjectParams.java @@ -31,737 +31,740 @@ import lcsb.mapviewer.services.view.AuthenticationToken; */ public class CreateProjectParams { - /** - * User defined project identifier. - */ - private String projectId; - - /** - * Name of the project. - */ - private String projectName; - - /** - * Disease associated to the project. - */ - private String disease; - - /** - * Organism associated to the project. - */ - private String organism; - - /** - * Path to a file used as a model. - */ - private String projectFile; - - private IConverter parser; - - /** - * Is the project a complex multi-file project. - */ - private boolean complex; - private boolean semanticZoom; - - /** - * List of zip entries in the complex model definition. - */ - private List<ZipEntryFile> zipEntries = new ArrayList<ZipEntryFile>(); - - /** - * Should the elements be annotated by the external resources. - */ - private boolean updateAnnotations = false; - - /** - * Do we want to generate images for all available layers. - */ - private boolean images = false; - - /** - * Should the map be autoresized after processing (to trim unnecessary - * margins). - */ - private boolean autoResize = true; - - /** - * Should the data from external resources but linked to model be cached. - */ - private boolean cacheModel = true; - - /** - * Should the process of creation of the project be asynchronous (in separate - * thread). - */ - private boolean async = false; - - /** - * Should the map be displayed in SBGN format. - */ - private boolean sbgnFormat = false; - - /** - * Is the {@link lcsb.mapviewer.services.utils.data.BuildInLayout#NORMAL} - * default {@link lcsb.mapviewer.model.map.layout.Layout Layout} when - * generating new project. - */ - private boolean networkLayoutAsDefault = false; - - /** - * Do we want to analyze annotations after processing of the map. If yes then - * in the email with summary of the generation process information about - * improper annotations will be sent. - */ - private boolean analyzeAnnotations = false; - - /** - * Email address that should be notified after everything is done. - */ - private String notifyEmail = null; - - /** - * Description of the project. - */ - private String description = ""; - - /** - * Version of the map. - */ - private String version = "0"; - - /** - * Users that should have access to the map. - */ - private List<String[]> users = new ArrayList<String[]>(); - - /** - * Directory with the static images that will be stored on server. This - * directory is relative and it's a simple uniqe name within folder with - * images. - */ - private String projectDir; - - private AuthenticationToken authenticationToken; - - /** - * Map that contains informnation what kind of annotators should be used for - * specific class. - */ - private Map<Class<?>, List<String>> annotatorsMap = null; - - /** - * Map that contains information which {@link MiriamType miriam types} are - * valid for which class. - */ - private Map<Class<? extends BioEntity>, Set<MiriamType>> validAnnotations = null; - - /** - * Map that contains information which {@link MiriamType miriam types} are - * obigatory for which class. - */ - private Map<Class<? extends BioEntity>, Set<MiriamType>> requiredAnnotations = null; - - /** - * @param projectId - * the projectId to set - * @return object with all parameters - * @see #projectId - */ - public CreateProjectParams projectId(String projectId) { - this.projectId = projectId; - return this; - } - - public CreateProjectParams parser(IConverter parser) { - this.parser = parser; - return this; - } - - - - - /** - * @param notifyEmail - * the notifyEmail to set - * @return object with all parameters - * @see #notifyEmail - */ - public CreateProjectParams notifyEmail(String notifyEmail) { - this.notifyEmail = notifyEmail; - return this; - } - - /** - * @param projectFile - * the projectFile to set - * @return object with all parameters - * @see #projectFile - */ - public CreateProjectParams projectFile(String projectFile) { - this.projectFile = projectFile; - return this; - } - - /** - * @param autoResize - * the autoResize to set - * @return object with all parameters - * @see #autoResize - */ - public CreateProjectParams autoResize(boolean autoResize) { - this.autoResize = autoResize; - return this; - } - - public CreateProjectParams autoResize(String value) { - return this.autoResize("true".equalsIgnoreCase(value)); - } - - /** - * Sets input stream from which projects should be generated. - * - * @param is - * inputstream with the data of the project to be generated - * @return object with all parameters - * @throws IOException - * thrown if there are some problem with the stream - */ - public CreateProjectParams projectFile(InputStream is) throws IOException { - File temp = File.createTempFile("model", ".xml"); - IOUtils.copy(is, new FileOutputStream(temp)); - this.projectFile = temp.getAbsolutePath(); - return this; - } - - /** - * Sets file from which projects should be generated. - * - * @param file - * file with the data of the project to be generated - * @return object with all parameters - */ - public CreateProjectParams projectFile(File file) { - this.projectFile = file.getAbsolutePath(); - return this; - } - - /** - * @param async - * the async to set - * @return object with all parameters - * @see #async - */ - public CreateProjectParams async(boolean async) { - this.async = async; - return this; - } - - /** - * @param analyzeAnnotations - * the analyzeAnnotations to set - * @return object with all parameters - * @see #analyzeAnnotations - */ - public CreateProjectParams analyzeAnnotations(boolean analyzeAnnotations) { - this.analyzeAnnotations = analyzeAnnotations; - return this; - } - - /** - * @param updateAnnotations - * the updateAnnotations to set - * @return object with all parameters - * @see #updateAnnotations - */ - public CreateProjectParams annotations(boolean updateAnnotations) { - this.updateAnnotations = updateAnnotations; - return this; - } - - /** - * @param images - * the images to set - * @return object with all parameters - * @see #images - */ - public CreateProjectParams images(boolean images) { - this.images = images; - return this; - } - - /** - * @param description - * the description to set - * @return object with all parameters - * @see #description - */ - public CreateProjectParams description(String description) { - this.description = description; - return this; - } - - /** - * @param version - * the version to set - * @return object with all parameters - * @see #version - */ - public CreateProjectParams version(String version) { - this.version = version; - return this; - } - - /** - * Adds a user to the list of users that should have access to the project - * from the beginning. - * - * @param login - * login of the user - * @param password - * password (in case user doesn't exist yet) - * @return object with all parameters - * @return - */ - public CreateProjectParams addUser(String login, String password) { - this.users.add(new String[] { login, password }); - return this; - } - - /** - * @return the users - * @see #users - */ - public List<String[]> getUsers() { - return users; - } - - /** - * @return the version - * @see #version - */ - public String getVersion() { - return version; - } - - /** - * @return the description - * @see #description - */ - public String getDescription() { - return description; - } - - /** - * @return the notifyEmail - * @see #notifyEmail - */ - public String getNotifyEmail() { - return notifyEmail; - } - - /** - * @return the analyzeAnnotations - * @see #analyzeAnnotations - */ - public boolean isAnalyzeAnnotations() { - return analyzeAnnotations; - } - - /** - * @return the async - * @see #async - */ - public boolean isAsync() { - return async; - } - - /** - * @return the autoResize - * @see #autoResize - */ - public boolean isAutoResize() { - return autoResize; - } - - /** - * @return the images - * @see #images - */ - public boolean isImages() { - return images; - } - - /** - * @return the updateAnnotations - * @see #updateAnnotations - */ - public boolean isUpdateAnnotations() { - return updateAnnotations; - } - - /** - * @return the projectFile - * @see #projectFile - */ - public String getProjectFile() { - return projectFile; - } - - /** - * @return the projectId - * @see #projectId - */ - public String getProjectId() { - return projectId; - } - - /** - * @return the cacheModel - * @see #cacheModel - */ - public boolean isCacheModel() { - return cacheModel; - } - - /** - * @param cacheModel - * the cacheModel to set - * @see #cacheModel - * @return object with all parameters - */ - public CreateProjectParams cacheModel(boolean cacheModel) { - this.cacheModel = cacheModel; - return this; - } - - public CreateProjectParams cacheModel(String value) { - return this.cacheModel("true".equalsIgnoreCase(value)); - } - - /** - * @return the submodels - * @see #zipEntries - */ - public List<ZipEntryFile> getZipEntries() { - return zipEntries; - } - - /** - * @param entry - * the submodel to add - * @see #zipEntries - * @return object with all parameters - */ - public CreateProjectParams addZipEntry(ZipEntryFile entry) { - if (entry != null) { - this.zipEntries.add(entry); - } - return this; - } - - /** - * @return the complex - * @see #complex - */ - public boolean isComplex() { - return complex; - } - - /** - * @return the sbgnFormat - * @see #sbgnFormat - */ - public boolean isSbgnFormat() { - return sbgnFormat; - } - - /** - * @param sbgnFormat - * the sbgnFormat to set - * @see #sbgnFormat - */ - public CreateProjectParams sbgnFormat(boolean sbgnFormat) { - this.sbgnFormat = sbgnFormat; - return this; - } - - public CreateProjectParams sbgnFormat(String value) { - return this.sbgnFormat("true".equalsIgnoreCase(value)); - } - - /** - * @param complex - * the complex to set - * @see #complex - * @return object with all parameters - */ - public CreateProjectParams complex(boolean complex) { - this.complex = complex; - return this; - } - - /** - * Creates {@link #annotatorsMap}. - * - * @param annotatorsTree - * tree containing information about annotators for given classes - */ - public void annotatorsMap(TreeNode annotatorsTree) { - Map<Class<?>, List<String>> map = new HashMap<Class<?>, List<String>>(); - Queue<TreeNode> queue = new LinkedList<TreeNode>(); - queue.add(annotatorsTree); - while (!queue.isEmpty()) { - TreeNode node = queue.poll(); - - Set<String> set = new HashSet<String>(); - - TreeNode parent = node; - while (parent != null) { - set.addAll(((AnnotatedObjectTreeRow) parent.getData()).getUsedAnnotators()); - parent = parent.getParent(); - } - List<String> list = new ArrayList<String>(); - list.addAll(set); - map.put(((AnnotatedObjectTreeRow) node.getData()).getClazz(), list); - - for (TreeNode node2 : node.getChildren()) { - queue.add(node2); - } - } - annotatorsMap = map; - } - - /** - * @return the annotatorsMap - * @see #annotatorsMap - */ - public Map<Class<?>, List<String>> getAnnotatorsMap() { - return annotatorsMap; - } - - /** - * @param annotatorsMap - * the annotatorsMap to set - * @see #annotatorsMap - */ - public void setAnnotatorsMap(Map<Class<?>, List<String>> annotatorsMap) { - this.annotatorsMap = annotatorsMap; - } - - /** - * Creates {@link #validAnnotations}. - * - * @param annotatorsTree - * tree containing information about valid {@link MiriamType miriam - * types} - */ - @SuppressWarnings("unchecked") - public void validAnnotations(TreeNode annotatorsTree) { - Map<Class<? extends BioEntity>, Set<MiriamType>> map = new HashMap<Class<? extends BioEntity>, Set<MiriamType>>(); - Queue<TreeNode> queue = new LinkedList<TreeNode>(); - queue.add(annotatorsTree); - while (!queue.isEmpty()) { - TreeNode node = queue.poll(); - Set<MiriamType> set = new HashSet<MiriamType>(); - - TreeNode parent = node; - while (parent != null) { - set.addAll(((AnnotatedObjectTreeRow) parent.getData()).getValidAnnotations()); - parent = parent.getParent(); - } - map.put((Class<? extends BioEntity>) ((AnnotatedObjectTreeRow) node.getData()).getClazz(), set); - - for (TreeNode node2 : node.getChildren()) { - queue.add(node2); - } - } - validAnnotations = map; - } - - /** - * Creates {@link #requiredAnnotations}. - * - * @param annotatorsTree - * tree containing information about required {@link MiriamType - * miriam types} - */ - @SuppressWarnings("unchecked") - public void requiredAnnotations(TreeNode annotatorsTree) { - Map<Class<? extends BioEntity>, Set<MiriamType>> map = new HashMap<Class<? extends BioEntity>, Set<MiriamType>>(); - Queue<TreeNode> queue = new LinkedList<TreeNode>(); - queue.add(annotatorsTree); - while (!queue.isEmpty()) { - TreeNode node = queue.poll(); - boolean valid = ((AnnotatedObjectTreeRow) node.getData()).getRequire(); - Set<MiriamType> set = new HashSet<MiriamType>(); - - TreeNode parent = node; - while (parent != null) { - set.addAll(((AnnotatedObjectTreeRow) parent.getData()).getRequiredAnnotations()); - if (((AnnotatedObjectTreeRow) parent.getData()).getRequire()) { - valid = true; - } - parent = parent.getParent(); - } - if (!valid) { - set = null; - } - map.put((Class<? extends BioEntity>) ((AnnotatedObjectTreeRow) node.getData()).getClazz(), set); - - for (TreeNode node2 : node.getChildren()) { - queue.add(node2); - } - } - requiredAnnotations = map; - } - - /** - * Returns {@link #validAnnotations}. - * - * @return {@link #validAnnotations}. - */ - public Map<Class<? extends BioEntity>, Set<MiriamType>> getValidAnnotations() { - return validAnnotations; - } - - /** - * Returns {@link #requiredAnnotations}. - * - * @return {@link #requiredAnnotations}. - */ - public Map<Class<? extends BioEntity>, Set<MiriamType>> getRequiredAnnotations() { - return requiredAnnotations; - } - - /** - * Sets {@link #projectDir}. - * - * @param directory - * new {@link #projectDir} value - * @return instance of this class with new value set - */ - public CreateProjectParams projectDir(String directory) { - this.projectDir = directory; - return this; - } - - /** - * @return the projectDir - * @see #projectDir - */ - public String getProjectDir() { - return projectDir; - } - - /** - * - * @param projectName - * new {@link #projectName} - * @return instance of this class with new value set - */ - public CreateProjectParams projectName(String projectName) { - this.projectName = projectName; - return this; - } - - /** - * @return the projectName - * @see #projectName - */ - public String getProjectName() { - return projectName; - } - - /** - * @param value - * the networkLayoutAsDefault to set - * @see #networkLayoutAsDefault - * @return instance of this class with new value set - */ - public CreateProjectParams networkLayoutAsDefault(boolean value) { - this.networkLayoutAsDefault = value; - return this; - - } - - /** - * @return the networkLayoutAsDefault - * @see #networkLayoutAsDefault - */ - public boolean isNetworkLayoutAsDefault() { - return networkLayoutAsDefault; - } - - /** - * @return disease MESH code. - */ - public String getDisease() { - return disease; - } - - /** - * @param disease - * the code of the disease. - * @return updated params object. - */ - public CreateProjectParams projectDisease(String disease) { - this.disease = disease; - return this; - } - - /** - * @return the organism - * @see #organism - */ - public String getOrganism() { - return organism; - } - - /** - * @param organism - * the organism to set - * @return updated params object. - */ - public CreateProjectParams projectOrganism(String organism) { - this.organism = organism; - return this; - } - - /** - * @return the authenticationToken - * @see #authenticationToken - */ - public AuthenticationToken getAuthenticationToken() { - return authenticationToken; - } - - /** - * @param authenticationToken - * the authenticationToken to set - * @see #authenticationToken - */ - public CreateProjectParams authenticationToken(AuthenticationToken authenticationToken) { - this.authenticationToken = authenticationToken; - - return this; - } - - public CreateProjectParams semanticZoom(boolean semanticZoom) { - this.semanticZoom = semanticZoom; - return this; - } - - public CreateProjectParams semanticZoom(String value) { - return this.semanticZoom("true".equals(value)); - } - - public boolean isSemanticZoom() { - return this.semanticZoom; - } - - public IConverter getParser() { - return this.parser ; - } + /** + * User defined project identifier. + */ + private String projectId; + + /** + * Name of the project. + */ + private String projectName; + + /** + * Disease associated to the project. + */ + private String disease; + + /** + * Organism associated to the project. + */ + private String organism; + + /** + * Path to a file used as a model. + */ + private String projectFile; + + private IConverter parser; + + /** + * Is the project a complex multi-file project. + */ + private boolean complex; + private boolean semanticZoom; + + /** + * List of zip entries in the complex model definition. + */ + private List<ZipEntryFile> zipEntries = new ArrayList<ZipEntryFile>(); + + /** + * Should the elements be annotated by the external resources. + */ + private boolean updateAnnotations = false; + + /** + * Do we want to generate images for all available layers. + */ + private boolean images = false; + + /** + * Should the map be autoresized after processing (to trim unnecessary margins). + */ + private boolean autoResize = true; + + /** + * Should the data from external resources but linked to model be cached. + */ + private boolean cacheModel = true; + + /** + * Should the process of creation of the project be asynchronous (in separate + * thread). + */ + private boolean async = false; + + /** + * Should the map be displayed in SBGN format. + */ + private boolean sbgnFormat = false; + + /** + * Is the {@link lcsb.mapviewer.services.utils.data.BuildInLayout#NORMAL} + * default {@link lcsb.mapviewer.model.map.layout.Layout Layout} when generating + * new project. + */ + private boolean networkLayoutAsDefault = false; + + /** + * Do we want to analyze annotations after processing of the map. If yes then in + * the email with summary of the generation process information about improper + * annotations will be sent. + */ + private boolean analyzeAnnotations = false; + + /** + * Email address that should be notified after everything is done. + */ + private String notifyEmail = null; + + /** + * Description of the project. + */ + private String description = ""; + + /** + * Version of the map. + */ + private String version = "0"; + + /** + * Users that should have access to the map. + */ + private List<String[]> users = new ArrayList<String[]>(); + + /** + * Directory with the static images that will be stored on server. This + * directory is relative and it's a simple uniqe name within folder with images. + */ + private String projectDir; + + private AuthenticationToken authenticationToken; + + /** + * Map that contains informnation what kind of annotators should be used for + * specific class. + */ + private Map<Class<?>, List<String>> annotatorsMap = null; + + /** + * Map that contains information which {@link MiriamType miriam types} are valid + * for which class. + */ + private Map<Class<? extends BioEntity>, Set<MiriamType>> validAnnotations = null; + + /** + * Map that contains information which {@link MiriamType miriam types} are + * obigatory for which class. + */ + private Map<Class<? extends BioEntity>, Set<MiriamType>> requiredAnnotations = null; + + /** + * @param projectId + * the projectId to set + * @return object with all parameters + * @see #projectId + */ + public CreateProjectParams projectId(String projectId) { + this.projectId = projectId; + return this; + } + + public CreateProjectParams parser(IConverter parser) { + this.parser = parser; + return this; + } + + /** + * @param notifyEmail + * the notifyEmail to set + * @return object with all parameters + * @see #notifyEmail + */ + public CreateProjectParams notifyEmail(String notifyEmail) { + this.notifyEmail = notifyEmail; + return this; + } + + /** + * @param projectFile + * the projectFile to set + * @return object with all parameters + * @see #projectFile + */ + public CreateProjectParams projectFile(String projectFile) { + this.projectFile = projectFile; + return this; + } + + /** + * @param autoResize + * the autoResize to set + * @return object with all parameters + * @see #autoResize + */ + public CreateProjectParams autoResize(boolean autoResize) { + this.autoResize = autoResize; + return this; + } + + public CreateProjectParams autoResize(String value) { + return this.autoResize("true".equalsIgnoreCase(value)); + } + + /** + * Sets input stream from which projects should be generated. + * + * @param is + * inputstream with the data of the project to be generated + * @return object with all parameters + * @throws IOException + * thrown if there are some problem with the stream + */ + public CreateProjectParams projectFile(InputStream is) throws IOException { + File temp = File.createTempFile("model", ".xml"); + IOUtils.copy(is, new FileOutputStream(temp)); + this.projectFile = temp.getAbsolutePath(); + return this; + } + + /** + * Sets file from which projects should be generated. + * + * @param file + * file with the data of the project to be generated + * @return object with all parameters + */ + public CreateProjectParams projectFile(File file) { + this.projectFile = file.getAbsolutePath(); + return this; + } + + /** + * @param async + * the async to set + * @return object with all parameters + * @see #async + */ + public CreateProjectParams async(boolean async) { + this.async = async; + return this; + } + + /** + * @param analyzeAnnotations + * the analyzeAnnotations to set + * @return object with all parameters + * @see #analyzeAnnotations + */ + public CreateProjectParams analyzeAnnotations(boolean analyzeAnnotations) { + this.analyzeAnnotations = analyzeAnnotations; + return this; + } + + /** + * @param updateAnnotations + * the updateAnnotations to set + * @return object with all parameters + * @see #updateAnnotations + */ + public CreateProjectParams annotations(boolean updateAnnotations) { + this.updateAnnotations = updateAnnotations; + return this; + } + + /** + * @param images + * the images to set + * @return object with all parameters + * @see #images + */ + public CreateProjectParams images(boolean images) { + this.images = images; + return this; + } + + /** + * @param description + * the description to set + * @return object with all parameters + * @see #description + */ + public CreateProjectParams description(String description) { + this.description = description; + return this; + } + + /** + * @param version + * the version to set + * @return object with all parameters + * @see #version + */ + public CreateProjectParams version(String version) { + this.version = version; + return this; + } + + /** + * Adds a user to the list of users that should have access to the project from + * the beginning. + * + * @param login + * login of the user + * @param password + * password (in case user doesn't exist yet) + * @return object with all parameters + * @return + */ + public CreateProjectParams addUser(String login, String password) { + this.users.add(new String[] { login, password }); + return this; + } + + /** + * @return the users + * @see #users + */ + public List<String[]> getUsers() { + return users; + } + + /** + * @return the version + * @see #version + */ + public String getVersion() { + return version; + } + + /** + * @return the description + * @see #description + */ + public String getDescription() { + return description; + } + + /** + * @return the notifyEmail + * @see #notifyEmail + */ + public String getNotifyEmail() { + return notifyEmail; + } + + /** + * @return the analyzeAnnotations + * @see #analyzeAnnotations + */ + public boolean isAnalyzeAnnotations() { + return analyzeAnnotations; + } + + /** + * @return the async + * @see #async + */ + public boolean isAsync() { + return async; + } + + /** + * @return the autoResize + * @see #autoResize + */ + public boolean isAutoResize() { + return autoResize; + } + + /** + * @return the images + * @see #images + */ + public boolean isImages() { + return images; + } + + /** + * @return the updateAnnotations + * @see #updateAnnotations + */ + public boolean isUpdateAnnotations() { + return updateAnnotations; + } + + /** + * @return the projectFile + * @see #projectFile + */ + public String getProjectFile() { + return projectFile; + } + + /** + * @return the projectId + * @see #projectId + */ + public String getProjectId() { + return projectId; + } + + /** + * @return the cacheModel + * @see #cacheModel + */ + public boolean isCacheModel() { + return cacheModel; + } + + /** + * @param cacheModel + * the cacheModel to set + * @see #cacheModel + * @return object with all parameters + */ + public CreateProjectParams cacheModel(boolean cacheModel) { + this.cacheModel = cacheModel; + return this; + } + + public CreateProjectParams cacheModel(String value) { + return this.cacheModel("true".equalsIgnoreCase(value)); + } + + /** + * @return the submodels + * @see #zipEntries + */ + public List<ZipEntryFile> getZipEntries() { + return zipEntries; + } + + /** + * @param entry + * the submodel to add + * @see #zipEntries + * @return object with all parameters + */ + public CreateProjectParams addZipEntry(ZipEntryFile entry) { + if (entry != null) { + this.zipEntries.add(entry); + } + return this; + } + + /** + * @return the complex + * @see #complex + */ + public boolean isComplex() { + return complex; + } + + /** + * @return the sbgnFormat + * @see #sbgnFormat + */ + public boolean isSbgnFormat() { + return sbgnFormat; + } + + /** + * @param sbgnFormat + * the sbgnFormat to set + * @see #sbgnFormat + */ + public CreateProjectParams sbgnFormat(boolean sbgnFormat) { + this.sbgnFormat = sbgnFormat; + return this; + } + + public CreateProjectParams sbgnFormat(String value) { + return this.sbgnFormat("true".equalsIgnoreCase(value)); + } + + /** + * @param complex + * the complex to set + * @see #complex + * @return object with all parameters + */ + public CreateProjectParams complex(boolean complex) { + this.complex = complex; + return this; + } + + /** + * Creates {@link #annotatorsMap}. + * + * @param annotatorsTree + * tree containing information about annotators for given classes + */ + public void annotatorsMap(TreeNode annotatorsTree) { + Map<Class<?>, List<String>> map = new HashMap<Class<?>, List<String>>(); + Queue<TreeNode> queue = new LinkedList<TreeNode>(); + queue.add(annotatorsTree); + while (!queue.isEmpty()) { + TreeNode node = queue.poll(); + + Set<String> set = new HashSet<String>(); + + TreeNode parent = node; + while (parent != null) { + set.addAll(((AnnotatedObjectTreeRow) parent.getData()).getUsedAnnotators()); + parent = parent.getParent(); + } + List<String> list = new ArrayList<String>(); + list.addAll(set); + map.put(((AnnotatedObjectTreeRow) node.getData()).getClazz(), list); + + for (TreeNode node2 : node.getChildren()) { + queue.add(node2); + } + } + annotatorsMap = map; + } + + /** + * @return the annotatorsMap + * @see #annotatorsMap + */ + public Map<Class<?>, List<String>> getAnnotatorsMap() { + return annotatorsMap; + } + + /** + * @param annotatorsMap + * the annotatorsMap to set + * @see #annotatorsMap + */ + public void setAnnotatorsMap(Map<Class<?>, List<String>> annotatorsMap) { + this.annotatorsMap = annotatorsMap; + } + + /** + * Creates {@link #validAnnotations}. + * + * @param annotatorsTree + * tree containing information about valid {@link MiriamType miriam + * types} + */ + @SuppressWarnings("unchecked") + public void validAnnotations(TreeNode annotatorsTree) { + Map<Class<? extends BioEntity>, Set<MiriamType>> map = new HashMap<Class<? extends BioEntity>, Set<MiriamType>>(); + Queue<TreeNode> queue = new LinkedList<TreeNode>(); + queue.add(annotatorsTree); + while (!queue.isEmpty()) { + TreeNode node = queue.poll(); + Set<MiriamType> set = new HashSet<MiriamType>(); + + TreeNode parent = node; + while (parent != null) { + set.addAll(((AnnotatedObjectTreeRow) parent.getData()).getValidAnnotations()); + parent = parent.getParent(); + } + map.put((Class<? extends BioEntity>) ((AnnotatedObjectTreeRow) node.getData()).getClazz(), set); + + for (TreeNode node2 : node.getChildren()) { + queue.add(node2); + } + } + validAnnotations = map; + } + + /** + * Creates {@link #requiredAnnotations}. + * + * @param annotatorsTree + * tree containing information about required {@link MiriamType miriam + * types} + */ + @SuppressWarnings("unchecked") + public void requiredAnnotations(TreeNode annotatorsTree) { + Map<Class<? extends BioEntity>, Set<MiriamType>> map = new HashMap<Class<? extends BioEntity>, Set<MiriamType>>(); + Queue<TreeNode> queue = new LinkedList<TreeNode>(); + queue.add(annotatorsTree); + while (!queue.isEmpty()) { + TreeNode node = queue.poll(); + boolean valid = ((AnnotatedObjectTreeRow) node.getData()).getRequire(); + Set<MiriamType> set = new HashSet<MiriamType>(); + + TreeNode parent = node; + while (parent != null) { + set.addAll(((AnnotatedObjectTreeRow) parent.getData()).getRequiredAnnotations()); + if (((AnnotatedObjectTreeRow) parent.getData()).getRequire()) { + valid = true; + } + parent = parent.getParent(); + } + if (!valid) { + set = null; + } + map.put((Class<? extends BioEntity>) ((AnnotatedObjectTreeRow) node.getData()).getClazz(), set); + + for (TreeNode node2 : node.getChildren()) { + queue.add(node2); + } + } + requiredAnnotations = map; + } + + /** + * Returns {@link #validAnnotations}. + * + * @return {@link #validAnnotations}. + */ + public Map<Class<? extends BioEntity>, Set<MiriamType>> getValidAnnotations() { + return validAnnotations; + } + + /** + * Returns {@link #requiredAnnotations}. + * + * @return {@link #requiredAnnotations}. + */ + public Map<Class<? extends BioEntity>, Set<MiriamType>> getRequiredAnnotations() { + return requiredAnnotations; + } + + /** + * Sets {@link #projectDir}. + * + * @param directory + * new {@link #projectDir} value + * @return instance of this class with new value set + */ + public CreateProjectParams projectDir(String directory) { + this.projectDir = directory; + return this; + } + + /** + * @return the projectDir + * @see #projectDir + */ + public String getProjectDir() { + return projectDir; + } + + /** + * + * @param projectName + * new {@link #projectName} + * @return instance of this class with new value set + */ + public CreateProjectParams projectName(String projectName) { + this.projectName = projectName; + return this; + } + + /** + * @return the projectName + * @see #projectName + */ + public String getProjectName() { + return projectName; + } + + /** + * @param value + * the networkLayoutAsDefault to set + * @see #networkLayoutAsDefault + * @return instance of this class with new value set + */ + public CreateProjectParams networkLayoutAsDefault(boolean value) { + this.networkLayoutAsDefault = value; + return this; + + } + + /** + * @return the networkLayoutAsDefault + * @see #networkLayoutAsDefault + */ + public boolean isNetworkLayoutAsDefault() { + return networkLayoutAsDefault; + } + + /** + * @return disease MESH code. + */ + public String getDisease() { + return disease; + } + + /** + * @param disease + * the code of the disease. + * @return updated params object. + */ + public CreateProjectParams projectDisease(String disease) { + this.disease = disease; + return this; + } + + /** + * @return the organism + * @see #organism + */ + public String getOrganism() { + return organism; + } + + /** + * @param organism + * the organism to set + * @return updated params object. + */ + public CreateProjectParams projectOrganism(String organism) { + this.organism = organism; + return this; + } + + /** + * @return the authenticationToken + * @see #authenticationToken + */ + public AuthenticationToken getAuthenticationToken() { + return authenticationToken; + } + + /** + * @param authenticationToken + * the authenticationToken to set + * @see #authenticationToken + */ + public CreateProjectParams authenticationToken(AuthenticationToken authenticationToken) { + this.authenticationToken = authenticationToken; + + return this; + } + + public CreateProjectParams semanticZoom(boolean semanticZoom) { + this.semanticZoom = semanticZoom; + return this; + } + + public CreateProjectParams semanticZoom(String value) { + return this.semanticZoom("true".equals(value)); + } + + public boolean isSemanticZoom() { + return this.semanticZoom; + } + + public IConverter getParser() { + return this.parser; + } + + public CreateProjectParams annotations(String value) { + return this.annotations("true".equalsIgnoreCase(value)); + } + + public CreateProjectParams analyzeAnnotations(String value) { + return this.analyzeAnnotations("true".equalsIgnoreCase(value)); + } }