wisemapping-open-source/wise-webapp/src/main/java/com/wisemapping/rest/MindmapController.java

434 lines
20 KiB
Java
Raw Normal View History

/*
* Copyright [2011] [wisemapping]
*
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
* It is basically the Apache License, Version 2.0 (the "License") plus the
* "powered by wisemapping" text requirement on every single page;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the license at
*
* http://www.wisemapping.org/license
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
2012-02-13 01:57:11 +01:00
package com.wisemapping.rest;
import com.wisemapping.exceptions.WiseMappingException;
2012-06-04 00:19:48 +02:00
import com.wisemapping.importer.ImportFormat;
import com.wisemapping.importer.Importer;
import com.wisemapping.importer.ImporterException;
import com.wisemapping.importer.ImporterFactory;
2012-06-10 03:49:54 +02:00
import com.wisemapping.model.*;
import com.wisemapping.rest.model.*;
import com.wisemapping.security.Utils;
2012-06-10 03:55:55 +02:00
import com.wisemapping.service.CollaborationException;
2012-02-13 01:57:11 +01:00
import com.wisemapping.service.MindmapService;
import com.wisemapping.validator.MapInfoValidator;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
2012-06-10 03:49:54 +02:00
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
2012-02-13 01:57:11 +01:00
import org.springframework.stereotype.Controller;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
2012-02-13 01:57:11 +01:00
import javax.servlet.http.HttpServletResponse;
2012-06-04 00:19:48 +02:00
import java.io.ByteArrayInputStream;
2012-02-13 01:57:11 +01:00
import java.io.IOException;
import java.util.*;
2012-02-13 01:57:11 +01:00
2012-02-13 01:57:11 +01:00
@Controller
public class MindmapController extends BaseController {
2012-06-10 03:49:54 +02:00
@Qualifier("mindmapService")
@Autowired
2012-02-13 01:57:11 +01:00
private MindmapService mindmapService;
@RequestMapping(method = RequestMethod.GET, value = "/maps/{id}", produces = {"application/json", "application/xml", "text/html"})
2012-02-13 01:57:11 +01:00
@ResponseBody
public ModelAndView retrieve(@PathVariable int id) throws IOException {
2012-06-10 03:49:54 +02:00
final User user = Utils.getUser();
2012-06-18 00:16:39 +02:00
final MindMap mindMap = mindmapService.findMindmapById(id);
final RestMindmap map = new RestMindmap(mindMap, user);
return new ModelAndView("mapView", "map", map);
2012-02-13 01:57:11 +01:00
}
@RequestMapping(method = RequestMethod.GET, value = "/maps/{id}", produces = {"application/wisemapping+xml"}, params = {"download=wxml"})
@ResponseBody
public ModelAndView retrieveAsWise(@PathVariable int id) throws IOException {
2012-06-18 00:16:39 +02:00
final MindMap mindMap = mindmapService.findMindmapById(id);
final Map<String, Object> values = new HashMap<String, Object>();
2012-06-10 03:49:54 +02:00
final User user = Utils.getUser();
values.put("mindmap", new RestMindmap(mindMap, user));
values.put("filename", mindMap.getTitle());
return new ModelAndView("transformViewWise", values);
}
@RequestMapping(method = RequestMethod.GET, value = "/maps/{id}", produces = {"application/freemind"}, params = {"download=mm"})
@ResponseBody
public ModelAndView retrieveDocumentAsFreemind(@PathVariable int id) throws IOException {
2012-06-18 00:16:39 +02:00
final MindMap mindMap = mindmapService.findMindmapById(id);
final Map<String, Object> values = new HashMap<String, Object>();
values.put("content", mindMap.getXmlStr());
values.put("filename", mindMap.getTitle());
return new ModelAndView("transformViewFreemind", values);
}
2012-06-04 00:19:48 +02:00
@RequestMapping(method = RequestMethod.GET, value = "/maps/", produces = {"application/json", "text/html", "application/xml"})
public ModelAndView retrieveList(@RequestParam(required = false) String q) throws IOException {
2012-06-10 03:49:54 +02:00
final User user = Utils.getUser();
2012-05-24 02:54:03 +02:00
final MindmapFilter filter = MindmapFilter.parse(q);
final List<Collaboration> collaborations = mindmapService.findCollaborations(user);
2012-05-24 02:54:03 +02:00
2012-02-20 18:42:07 +01:00
final List<MindMap> mindmaps = new ArrayList<MindMap>();
2012-06-10 03:49:54 +02:00
for (Collaboration collaboration : collaborations) {
2012-06-09 20:49:19 +02:00
final MindMap mindmap = collaboration.getMindMap();
2012-05-24 02:54:03 +02:00
if (filter.accept(mindmap, user)) {
mindmaps.add(mindmap);
}
2012-02-20 18:42:07 +01:00
}
final RestMindmapList restMindmapList = new RestMindmapList(mindmaps, user);
2012-02-20 18:42:07 +01:00
return new ModelAndView("mapsView", "list", restMindmapList);
}
@RequestMapping(method = RequestMethod.GET, value = "/maps/{id}/history", produces = {"application/json", "text/html", "application/xml"})
public ModelAndView retrieveHistory(@PathVariable int id) throws IOException {
2012-06-18 00:16:39 +02:00
final List<MindMapHistory> histories = mindmapService.findMindmapHistory(id);
2012-06-17 07:51:01 +02:00
final RestMindmapHistoryList result = new RestMindmapHistoryList();
for (MindMapHistory history : histories) {
result.addHistory(new RestMindmapHistory(history));
2012-06-10 03:49:54 +02:00
}
2012-06-17 07:51:01 +02:00
return new ModelAndView("historyView", "list", result);
}
2012-06-18 00:16:39 +02:00
@RequestMapping(value = "maps/{id}/history/{hid}", method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public void updateRevertMindmap(@PathVariable int id, @PathVariable int hid) throws IOException, WiseMappingException {
final MindMap mindmap = mindmapService.findMindmapById(id);
mindmapService.revertChange(mindmap, hid);
}
2012-05-24 01:05:16 +02:00
@RequestMapping(method = RequestMethod.PUT, value = "/maps/{id}/document", consumes = {"application/xml", "application/json"}, produces = {"application/json", "text/html", "application/xml"})
@ResponseStatus(value = HttpStatus.NO_CONTENT)
2012-05-24 01:05:16 +02:00
public void updateDocument(@RequestBody RestMindmap restMindmap, @PathVariable int id, @RequestParam(required = false) boolean minor) throws IOException, WiseMappingException {
final MindMap mindmap = mindmapService.findMindmapById(id);
final User user = Utils.getUser();
// Validate arguments ...
final String properties = restMindmap.getProperties();
if (properties == null) {
throw new IllegalArgumentException("Map properties can not be null");
}
// Update collaboration properties ...
final CollaborationProperties collaborationProperties = mindmap.getCollaborationProperties(user);
collaborationProperties.setMindmapProperties(properties);
// Validate content ...
final String xml = restMindmap.getXml();
if (xml == null) {
throw new IllegalArgumentException("Map xml can not be null");
}
mindmap.setXmlStr(xml);
// Update map ...
saveMindmap(minor, mindmap, user);
}
2012-05-24 01:05:16 +02:00
/**
* The intention of this method is the update of several properties at once ...
*/
@RequestMapping(method = RequestMethod.PUT, value = "/maps/{id}", consumes = {"application/xml", "application/json"}, produces = {"application/json", "text/html", "application/xml"})
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public void update(@RequestBody RestMindmap restMindmap, @PathVariable int id, @RequestParam(required = false) boolean minor) throws IOException, WiseMappingException {
2012-05-24 01:05:16 +02:00
final MindMap mindmap = mindmapService.findMindmapById(id);
2012-05-24 01:05:16 +02:00
final User user = Utils.getUser();
final String xml = restMindmap.getXml();
if (xml != null) {
mindmap.setXmlStr(xml);
2012-05-24 01:05:16 +02:00
}
// Update title ...
final String title = restMindmap.getTitle();
if (title != null && !title.equals(mindmap.getTitle())) {
2012-05-24 01:05:16 +02:00
if (mindmapService.getMindmapByTitle(title, user) != null) {
throw buildValidationException("title", "You already have a map with this title");
}
mindmap.setTitle(title);
2012-05-24 01:05:16 +02:00
}
// Update description ...
final String description = restMindmap.getDescription();
if (description != null) {
mindmap.setDescription(description);
2012-05-24 01:05:16 +02:00
}
final String tags = restMindmap.getTags();
if (tags != null) {
mindmap.setTags(tags);
}
// Update document properties ...
final String properties = restMindmap.getProperties();
if (properties != null) {
final CollaborationProperties collaborationProperties = mindmap.getCollaborationProperties(user);
collaborationProperties.setMindmapProperties(properties);
2012-05-24 01:05:16 +02:00
}
// Update map ...
saveMindmap(minor, mindmap, user);
2012-05-24 01:05:16 +02:00
}
@RequestMapping(method = RequestMethod.PUT, value = "/maps/{id}/title", consumes = {"text/plain"}, produces = {"application/json", "text/html", "application/xml"})
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public void updateTitle(@RequestBody String title, @PathVariable int id) throws WiseMappingException {
2012-06-18 00:16:39 +02:00
final MindMap mindMap = mindmapService.findMindmapById(id);
final User user = Utils.getUser();
// Is there a map with the same name ?
if (mindmapService.getMindmapByTitle(title, user) != null) {
2012-05-24 01:05:16 +02:00
throw buildValidationException("title", "You already have a mindmap with this title");
}
// Update map ...
2012-06-18 00:16:39 +02:00
final MindMap mindmap = mindmapService.findMindmapById(id);
mindmap.setTitle(title);
saveMindmap(true, mindMap, user);
}
2012-06-09 20:49:19 +02:00
@RequestMapping(method = RequestMethod.PUT, value = "/maps/{id}/collabs", consumes = {"application/json", "application/xml"}, produces = {"application/json", "text/html", "application/xml"})
@ResponseStatus(value = HttpStatus.NO_CONTENT)
2012-06-10 03:55:55 +02:00
public void updateCollabs(@PathVariable int id, @NotNull @RequestBody RestCollaborationList restCollabs) throws CollaborationException {
2012-06-18 00:16:39 +02:00
final MindMap mindMap = mindmapService.findMindmapById(id);
2012-06-12 16:23:47 +02:00
// Only owner can change collaborators...
2012-06-09 20:49:19 +02:00
final User user = Utils.getUser();
2012-06-12 16:23:47 +02:00
if (!mindMap.hasPermissions(user, CollaborationRole.OWNER)) {
2012-06-10 03:49:54 +02:00
throw new IllegalArgumentException("No enough permissions");
}
// Compare one by one if some of the elements has been changed ....
final Set<Collaboration> collabsToRemove = new HashSet<Collaboration>(mindMap.getCollaborations());
for (RestCollaboration restCollab : restCollabs.getCollaborations()) {
2012-06-10 03:55:55 +02:00
final Collaboration collaboration = mindMap.findCollaboration(restCollab.getEmail());
// Validate role format ...
String roleStr = restCollab.getRole();
if (roleStr == null) {
throw new IllegalArgumentException(roleStr + " is not a valid role");
}
2012-06-10 03:49:54 +02:00
2012-06-10 03:55:55 +02:00
// Is owner ?
final CollaborationRole role = CollaborationRole.valueOf(roleStr.toUpperCase());
if (role != CollaborationRole.OWNER) {
2012-06-16 16:37:40 +02:00
mindmapService.addCollaboration(mindMap, restCollab.getEmail(), role, restCollabs.getMessage());
2012-06-10 03:49:54 +02:00
}
2012-06-16 16:37:40 +02:00
// Remove from the list of pendings to remove ...
2012-06-10 03:49:54 +02:00
if (collaboration != null) {
collabsToRemove.remove(collaboration);
}
}
// Remove all collaborations that no applies anymore ..
for (final Collaboration collaboration : collabsToRemove) {
2012-06-14 04:04:29 +02:00
mindmapService.removeCollaboration(mindMap, collaboration);
2012-06-10 03:49:54 +02:00
}
2012-06-09 20:49:19 +02:00
}
2012-06-10 03:49:54 +02:00
2012-06-09 20:49:19 +02:00
@RequestMapping(method = RequestMethod.GET, value = "/maps/{id}/collabs", produces = {"application/json", "text/html", "application/xml"})
2012-06-10 03:49:54 +02:00
public ModelAndView retrieveList(@PathVariable int id) {
2012-06-18 00:16:39 +02:00
final MindMap mindMap = mindmapService.findMindmapById(id);
2012-06-09 20:49:19 +02:00
final Set<Collaboration> collaborations = mindMap.getCollaborations();
2012-06-10 03:49:54 +02:00
final List<RestCollaboration> collabs = new ArrayList<RestCollaboration>();
for (Collaboration collaboration : collaborations) {
collabs.add(new RestCollaboration(collaboration));
}
final RestCollaborationList restCollaborationList = new RestCollaborationList();
restCollaborationList.setCollaborations(collabs);
2012-06-09 20:49:19 +02:00
2012-06-10 03:49:54 +02:00
return new ModelAndView("collabsView", "list", restCollaborationList);
2012-06-09 20:49:19 +02:00
}
@RequestMapping(method = RequestMethod.PUT, value = "/maps/{id}/description", consumes = {"text/plain"}, produces = {"application/json", "text/html", "application/xml"})
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public void updateDescription(@RequestBody String description, @PathVariable int id) throws WiseMappingException {
2012-06-18 00:16:39 +02:00
final MindMap mindMap = mindmapService.findMindmapById(id);
final User user = Utils.getUser();
// Update map ...
2012-06-18 00:16:39 +02:00
final MindMap mindmap = mindmapService.findMindmapById(id);
mindmap.setDescription(description);
saveMindmap(true, mindMap, user);
}
2012-05-21 02:46:55 +02:00
@RequestMapping(method = RequestMethod.PUT, value = "/maps/{id}/publish", consumes = {"text/plain"}, produces = {"application/json", "text/html", "application/xml"})
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public void updatePublishState(@RequestBody String value, @PathVariable int id) throws WiseMappingException {
2012-05-21 02:46:55 +02:00
2012-06-18 00:16:39 +02:00
final MindMap mindMap = mindmapService.findMindmapById(id);
2012-05-21 02:46:55 +02:00
2012-06-12 16:23:47 +02:00
final User user = Utils.getUser();
if (!!mindMap.hasPermissions(user, CollaborationRole.OWNER)) {
2012-05-21 02:46:55 +02:00
throw new IllegalArgumentException("No enough to execute this operation");
}
// Update map status ...
mindMap.setPublic(Boolean.parseBoolean(value));
saveMindmap(true, mindMap, user);
2012-05-21 02:46:55 +02:00
}
2012-03-15 05:21:46 +01:00
@RequestMapping(method = RequestMethod.PUT, value = "/maps/{id}/starred", consumes = {"text/plain"}, produces = {"application/json", "text/html", "application/xml"})
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public void updateStarredState(@RequestBody String value, @PathVariable int id) throws WiseMappingException {
2012-06-18 00:16:39 +02:00
final MindMap mindMap = mindmapService.findMindmapById(id);
final User user = Utils.getUser();
// Update map status ...
mindMap.setStarred(user, Boolean.parseBoolean(value));
saveMindmap(true, mindMap, user);
}
2012-03-15 05:21:46 +01:00
@RequestMapping(method = RequestMethod.DELETE, value = "/maps/{id}")
@ResponseStatus(value = HttpStatus.NO_CONTENT)
2012-05-24 01:05:16 +02:00
public void updateMap(@PathVariable int id) throws IOException, WiseMappingException {
2012-03-15 05:21:46 +01:00
final User user = Utils.getUser();
2012-06-18 00:16:39 +02:00
final MindMap mindmap = mindmapService.findMindmapById(id);
2012-03-15 05:21:46 +01:00
mindmapService.removeMindmap(mindmap, user);
}
2012-04-06 22:05:42 +02:00
@RequestMapping(method = RequestMethod.DELETE, value = "/maps/batch")
@ResponseStatus(value = HttpStatus.NO_CONTENT)
2012-05-20 02:36:34 +02:00
public void batchDelete(@RequestParam(required = true) String ids) throws IOException, WiseMappingException {
2012-04-06 22:05:42 +02:00
final User user = Utils.getUser();
final String[] mapsIds = ids.split(",");
for (final String mapId : mapsIds) {
2012-06-18 00:16:39 +02:00
final MindMap mindmap = mindmapService.findMindmapById(Integer.parseInt(mapId));
2012-04-06 22:05:42 +02:00
mindmapService.removeMindmap(mindmap, user);
}
}
2012-06-06 05:48:46 +02:00
@RequestMapping(method = RequestMethod.POST, value = "/maps", consumes = {"application/xml", "application/json", "application/wisemapping+xml"})
@ResponseStatus(value = HttpStatus.CREATED)
2012-06-06 05:48:46 +02:00
public void createMap(@RequestBody RestMindmap restMindmap, @NotNull HttpServletResponse response, @RequestParam(required = false) String title, @RequestParam(required = false) String description) throws IOException, WiseMappingException {
// Overwrite title and description if they where specified by parameter.
if (title != null && !title.isEmpty()) {
restMindmap.setTitle(title);
}
if (description != null && !description.isEmpty()) {
restMindmap.setDescription(description);
}
// Validate ...
final BindingResult result = new BeanPropertyBindingResult(restMindmap, "");
new MapInfoValidator(mindmapService).validate(restMindmap.getDelegated(), result);
if (result.hasErrors()) {
throw new ValidationException(result);
}
// If the user has not specified the xml content, add one ...
final MindMap delegated = restMindmap.getDelegated();
String xml = restMindmap.getXml();
if (xml == null || xml.isEmpty()) {
xml = MindMap.getDefaultMindmapXml(restMindmap.getTitle());
}
2012-03-16 01:13:47 +01:00
delegated.setXmlStr(xml);
// Add new mindmap ...
2012-06-06 05:48:46 +02:00
final User user = Utils.getUser();
mindmapService.addMindmap(delegated, user);
// Return the new created map ...
response.setHeader("Location", "/service/maps/" + delegated.getId());
response.setHeader("ResourceId", Integer.toString(delegated.getId()));
}
2012-06-04 00:19:48 +02:00
@RequestMapping(method = RequestMethod.POST, value = "/maps", consumes = {"application/freemind"})
@ResponseStatus(value = HttpStatus.CREATED)
2012-06-06 06:42:24 +02:00
public void createMapFromFreemind(@RequestBody byte[] freemindXml, @RequestParam(required = true) String title, @RequestParam(required = false) String description, @NotNull HttpServletResponse response) throws IOException, WiseMappingException {
2012-06-04 00:19:48 +02:00
// Convert map ...
2012-06-06 06:42:24 +02:00
final MindMap mindMap;
try {
final Importer importer = ImporterFactory.getInstance().getImporter(ImportFormat.FREEMIND);
final ByteArrayInputStream stream = new ByteArrayInputStream(freemindXml);
mindMap = importer.importMap(title, "", stream);
} catch (ImporterException e) {
// @Todo: This should be an illegal argument exception. Review the all the other cases.
2012-06-06 06:42:24 +02:00
throw buildValidationException("xml", "The selected file does not seems to be a valid Freemind or WiseMapping file. Contact support in case the problem persists.");
}
2012-06-04 00:19:48 +02:00
// Save new map ...
final User user = Utils.getUser();
2012-06-06 05:48:46 +02:00
createMap(new RestMindmap(mindMap, user), response, title, description);
2012-06-04 00:19:48 +02:00
}
2012-03-16 01:13:47 +01:00
@RequestMapping(method = RequestMethod.POST, value = "/maps/{id}", consumes = {"application/xml", "application/json"})
@ResponseStatus(value = HttpStatus.CREATED)
public void createDuplicate(@RequestBody RestMindmapInfo restMindmap, @PathVariable int id, @NotNull HttpServletResponse response) throws IOException, WiseMappingException {
2012-05-21 02:46:55 +02:00
// Validate ...
2012-04-08 01:05:50 +02:00
final BindingResult result = new BeanPropertyBindingResult(restMindmap, "");
new MapInfoValidator(mindmapService).validate(restMindmap.getDelegated(), result);
if (result.hasErrors()) {
throw new ValidationException(result);
2012-03-16 01:13:47 +01:00
}
// Some basic validations ...
final User user = Utils.getUser();
// Create a shallowCopy of the map ...
2012-06-18 00:16:39 +02:00
final MindMap mindMap = mindmapService.findMindmapById(id);
2012-03-16 01:13:47 +01:00
final MindMap clonedMap = mindMap.shallowClone();
clonedMap.setTitle(restMindmap.getTitle());
clonedMap.setDescription(restMindmap.getDescription());
2012-06-12 16:23:47 +02:00
clonedMap.setCreator(user);
2012-03-16 01:13:47 +01:00
// Add new mindmap ...
mindmapService.addMindmap(clonedMap, user);
// Return the new created map ...
response.setHeader("Location", "/service/maps/" + clonedMap.getId());
response.setHeader("ResourceId", Integer.toString(clonedMap.getId()));
2012-03-16 01:13:47 +01:00
}
2012-06-06 05:48:46 +02:00
private void saveMindmap(boolean minor, @NotNull final MindMap mindMap, @NotNull final User user) throws WiseMappingException {
final Calendar now = Calendar.getInstance();
mindMap.setLastModificationTime(now);
mindMap.setLastModifierUser(user.getUsername());
2012-06-17 07:51:01 +02:00
mindmapService.updateMindmap(mindMap, !minor);
2012-06-06 05:48:46 +02:00
}
private ValidationException buildValidationException(@NotNull String fieldName, @NotNull String message) throws ValidationException {
final BindingResult result = new BeanPropertyBindingResult(new RestMindmap(), "");
result.rejectValue(fieldName, "error.not-specified", null, message);
return new ValidationException(result);
}
2012-02-13 01:57:11 +01:00
}