/* * This is eMonocot, a global online biodiversity information resource. * * Copyright © 2011–2015 The Board of Trustees of the Royal Botanic Gardens, Kew and The University of Oxford * * eMonocot is free software: you can redistribute it and/or modify it under the terms of the * GNU Affero General Public License as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * eMonocot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * The complete text of the GNU Affero General Public License is in the source repository as the file * ‘COPYING’. It is also available from <http://www.gnu.org/licenses/>. */ package org.emonocot.portal.controller; import java.security.Principal; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import javax.validation.Valid; import org.apache.solr.client.solrj.SolrServerException; import org.emonocot.api.CommentService; import org.emonocot.api.ConceptService; import org.emonocot.api.DescriptionService; import org.emonocot.api.DistributionService; import org.emonocot.api.IdentifierService; import org.emonocot.api.MeasurementOrFactService; import org.emonocot.api.ReferenceService; import org.emonocot.api.SearchableObjectService; import org.emonocot.api.Service; import org.emonocot.api.UserService; import org.emonocot.api.VernacularNameService; import org.emonocot.model.Base; import org.emonocot.model.BaseData; import org.emonocot.model.Comment; import org.emonocot.model.Concept; import org.emonocot.model.Description; import org.emonocot.model.Distribution; import org.emonocot.model.IdentificationKey; import org.emonocot.model.Identifier; import org.emonocot.model.Image; import org.emonocot.model.MeasurementOrFact; import org.emonocot.model.PhylogeneticTree; import org.emonocot.model.Reference; import org.emonocot.model.Taxon; import org.emonocot.model.TypeAndSpecimen; import org.emonocot.model.VernacularName; import org.emonocot.model.auth.User; import org.emonocot.pager.Page; import org.emonocot.portal.controller.form.CommentForm; import org.emonocot.portal.format.annotation.FacetRequestFormat; import org.joda.time.DateTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.support.DefaultMessageSourceResolvable; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.mvc.support.RedirectAttributes; /** * @author jk00kg * */ @Controller @RequestMapping("/comment") public class CommentController extends GenericController<Comment, CommentService> { private Logger logger = LoggerFactory.getLogger(CommentController.class); private SearchableObjectService searchableObjectService; private DescriptionService descriptionService; private DistributionService distributionService; private VernacularNameService vernacularNameService; private ReferenceService referenceService; private MeasurementOrFactService measurementOrFactService; private IdentifierService identifierService; private ConceptService conceptService; private UserService userService; @Autowired public void setDistributionService(DistributionService distributionService) { this.distributionService = distributionService; } @Autowired public void setVernacularNameService(VernacularNameService vernacularNameService) { this.vernacularNameService = vernacularNameService; } @Autowired public void setReferenceService(ReferenceService referenceService) { this.referenceService = referenceService; } @Autowired public void setMeasurementOrFactService(MeasurementOrFactService measurementOrFactService) { this.measurementOrFactService = measurementOrFactService; } @Autowired public void setIdentifierService(IdentifierService identifierService) { this.identifierService = identifierService; } @Autowired public void setUserService(UserService userService) { this.userService = userService; } @Autowired public void setConceptService(ConceptService conceptService) { this.conceptService = conceptService; } private List<Service<? extends BaseData>> getServices() { return Arrays.asList(searchableObjectService, distributionService, descriptionService, vernacularNameService, measurementOrFactService, identifierService, referenceService, conceptService); } public CommentController() { super("comment", Comment.class); } /** * @param commentService */ @Autowired public void setCommentService(CommentService commentService) { super.setService(commentService); } /** * @param searchableObjectService the searchableObjectService to set */ @Autowired public void setSearchableObjectService(SearchableObjectService searchableObjectService) { this.searchableObjectService = searchableObjectService; } /** * @param descriptionService the descriptionService to set */ @Autowired public void setDescriptionService(DescriptionService descriptionService) { this.descriptionService = descriptionService; } @RequestMapping(value = "/{identifier}", method = RequestMethod.GET, params="_method=DELETE", produces = "text/html") public String delete(@PathVariable String identifier, RedirectAttributes attributes) { getService().delete(identifier); attributes.addFlashAttribute("info", new DefaultMessageSourceResolvable("comment.deleted")); return "redirect:/comment"; } /** * @param comment * @param result */ @RequestMapping(method = RequestMethod.POST, produces = "text/html") public String create(Principal principal, @Valid CommentForm form, BindingResult formResult, RedirectAttributes attributes) { logger.debug("Got the comment \"" + form.getComment() + "\" about " + form.getAboutData() + " from " + principal.getName()); User user = userService.load(principal.getName()); //Create comment Comment comment = new Comment(); comment.setIdentifier(UUID.randomUUID().toString()); comment.setComment(form.getComment()); comment.setCreated(new DateTime()); comment.setStatus(Comment.Status.PENDING); comment.setUser(user); BaseData commentPage = searchableObjectService.find(form.getCommentPageIdentifier()); Base about = null; switch(form.getAboutData()) { case "descriptions": case "distribution": case "childNameUsages": case "synonymNameUsages": case "vernacularNames": case "higherClassification": case "measurementsOrFacts": case "typesAndSpecimens": case "references": case "identifiers": case "other": comment.setSubject(form.getAboutData()); about = commentPage; break; default: for(Service<? extends BaseData> service : getServices()) { about = service.find(form.getAboutData()); if(about != null) { break; } } if(about != null && commentPage instanceof Taxon) { Taxon t = (Taxon)commentPage; BaseData aboutData = (BaseData) about; if(aboutData instanceof Taxon) { if(about.equals(t.getParentNameUsage())) { comment.setSubject("parentNameUsage"); } if(about.equals(t.getAcceptedNameUsage())) { comment.setSubject("acceptedNameUsage"); } if(t.getChildNameUsages().contains(about)) { comment.setSubject("childNameUsages"); } if(t.getSynonymNameUsages().contains(about)) { comment.setSubject("synonymNameUsages"); } } else if(aboutData instanceof Description) { comment.setSubject("descriptions"); } else if(aboutData instanceof Distribution) { comment.setSubject("distribution"); } else if(aboutData instanceof Identifier) { comment.setSubject("identifiers"); } else if(aboutData instanceof MeasurementOrFact) { comment.setSubject("measurementsOrFacts"); } else if(aboutData instanceof VernacularName) { comment.setSubject("vernacularNames"); } else if(aboutData instanceof TypeAndSpecimen) { comment.setSubject("typesAndSpecimens"); } else if(aboutData instanceof Reference) { comment.setSubject("references"); } else { logger.warn("Unable to find an object with the identifier" + form.getAboutData()); attributes.addFlashAttribute("error", new DefaultMessageSourceResolvable("feedback.error.about")); } } break; } if(commentPage == null) { logger.warn("Unable to find an object with the identifier" + form.getCommentPageIdentifier()); attributes.addFlashAttribute("error", new DefaultMessageSourceResolvable("feedback.error.commentPage")); } else if(!formResult.hasErrors()) { comment.setAboutData(about); comment.setCommentPage(commentPage); super.getService().save(comment); attributes.addFlashAttribute("info", new DefaultMessageSourceResolvable("feedback.saved")); } else { attributes.addFlashAttribute("error", new DefaultMessageSourceResolvable("feedback.error.input")); } //Set object and redirect if(commentPage instanceof Taxon) { return "redirect:taxon/" + commentPage.getIdentifier(); } else if (commentPage instanceof Image) { return "redirect:image/" + commentPage.getId(); } else if (commentPage instanceof PhylogeneticTree) { return "redirect:phylo/" + commentPage.getId(); } else if (commentPage instanceof IdentificationKey) { return "redirect:key/" + commentPage.getId(); } else if (commentPage instanceof Concept) { return "redirect:term/" + commentPage.getId(); } else { return "user/show"; } } @RequestMapping(method = RequestMethod.GET, produces = "text/html") public String list( Model model, @RequestParam(value = "query", required = false) String query, @RequestParam(value = "limit", required = false, defaultValue = "10") Integer limit, @RequestParam(value = "start", required = false, defaultValue = "0") Integer start, @RequestParam(value = "facet", required = false) @FacetRequestFormat List<FacetRequest> facets, @RequestParam(value = "sort", required = false, defaultValue = "comment.created_dt_desc") String sort, @RequestParam(value = "view", required = false) String view) throws SolrServerException { Map<String, String> selectedFacets = new HashMap<String, String>(); if (facets != null && !facets.isEmpty()) { for (FacetRequest facetRequest : facets) { selectedFacets.put(facetRequest.getFacet(), facetRequest.getSelected()); } } selectedFacets.put("base.class_s", "org.emonocot.model.Comment"); selectedFacets.put("comment.status_t", "SENT"); Page<Comment> result = getService().search(query, null, limit, start, new String[] {"taxon.family_ss", "comment.subject_s","comment.comment_page_class_s" }, null, selectedFacets, sort, "aboutData"); model.addAttribute("result", result); result.putParam("query", query); return "comment/list"; } }