package edu.asu.spring.quadriga.web.conceptcollection; import java.security.Principal; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.servlet.http.HttpServletRequest; import org.codehaus.jettison.json.JSONException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.ui.ModelMap; import org.springframework.validation.BindingResult; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.ModelAttribute; 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.servlet.ModelAndView; import edu.asu.spring.quadriga.aspects.IAuthorization; import edu.asu.spring.quadriga.aspects.annotations.AccessPolicies; import edu.asu.spring.quadriga.aspects.annotations.CheckedElementType; import edu.asu.spring.quadriga.aspects.annotations.ElementAccessPolicy; import edu.asu.spring.quadriga.domain.IUser; import edu.asu.spring.quadriga.domain.conceptcollection.IConcept; import edu.asu.spring.quadriga.domain.conceptcollection.IConceptCollection; import edu.asu.spring.quadriga.domain.conceptcollection.IConceptCollectionCollaborator; import edu.asu.spring.quadriga.domain.conceptcollection.IConceptCollectionConcepts; import edu.asu.spring.quadriga.domain.factory.conceptcollection.IConceptCollectionFactory; import edu.asu.spring.quadriga.domain.factory.conceptcollection.IConceptFactory; import edu.asu.spring.quadriga.domain.factory.impl.conceptcollection.ConceptCollectionFactory; import edu.asu.spring.quadriga.domain.impl.CollectionsValidator; import edu.asu.spring.quadriga.domain.impl.ConceptpowerReply; import edu.asu.spring.quadriga.domain.impl.ConceptpowerReply.ConceptEntry; import edu.asu.spring.quadriga.domain.impl.conceptcollection.ConceptCollection; import edu.asu.spring.quadriga.exceptions.QuadrigaAccessException; import edu.asu.spring.quadriga.exceptions.QuadrigaException; import edu.asu.spring.quadriga.exceptions.QuadrigaStorageException; import edu.asu.spring.quadriga.service.IUserManager; import edu.asu.spring.quadriga.service.conceptcollection.IConceptCollectionManager; import edu.asu.spring.quadriga.service.conceptcollection.mapper.IConceptCollectionDeepMapper; import edu.asu.spring.quadriga.web.login.RoleNames; /** * This class is the controller for the concept collection requests. * * @author SatyaSwaroop Boddu * */ @Controller public class ConceptcollectionController { @Autowired private IConceptCollectionManager conceptControllerManager; @Autowired private CollectionsValidator validator; @Autowired private IConceptCollectionFactory collectionFactory; @Autowired private IConceptFactory conceptFactory; @Autowired private IConceptCollectionDeepMapper conceptCollectionDeepMapper; @Autowired private IUserManager usermanager; @Autowired @Qualifier("conceptCollectionAuthorization") private IAuthorization authorization; /** * Attach the custom validator to the Spring context */ @InitBinder protected void initBinder(WebDataBinder binder) { binder.setValidator(validator); } private static final Logger logger = LoggerFactory.getLogger(ConceptcollectionController.class); /** * This is used to fetch the user related concept collections from database. * * @param model * @return Returns the list of concept collections of user to the view * @throws QuadrigaStorageException */ @RequestMapping(value = "auth/conceptcollections", method = RequestMethod.GET) public String conceptCollectionHandler(ModelMap model, Principal principal) throws QuadrigaStorageException { model.addAttribute("conceptlist", conceptControllerManager.getCollectionsOwnedbyUser(principal.getName())); model.addAttribute("collaborationlist", conceptControllerManager.getUserCollaborations(principal.getName())); return "auth/conceptcollections"; } private void fillModel(String collectionId, ModelMap model, String username) throws QuadrigaStorageException, QuadrigaAccessException, JSONException { IConceptCollection collection = conceptControllerManager.getConceptCollection(collectionId); String adminRoles[] = { RoleNames.ROLE_CC_COLLABORATOR_ADMIN, RoleNames.ROLE_COLLABORATOR_OWNER }; String readRole[] = { RoleNames.ROLE_CC_COLLABORATOR_READ }; String readWriteRole[] = { RoleNames.ROLE_CC_COLLABORATOR_READ_WRITE }; boolean isAdmin = authorization.chkAuthorization(username, collectionId, adminRoles); boolean hasRead = authorization.chkAuthorization(username, collectionId, readRole); boolean hasReadWrite = authorization.chkAuthorization(username, collectionId, readWriteRole); if (isAdmin) { model.addAttribute("isAdmin", true); } else { model.addAttribute("isAdmin", false); } if (hasRead) { model.addAttribute("hasRead", true); } else { model.addAttribute("hasRead", false); } if (hasReadWrite) { model.addAttribute("hasReadWrite", true); } else { model.addAttribute("hasReadWrite", false); } model.addAttribute("concept", collection); conceptControllerManager.getCollaborators(collection); model.addAttribute("collectionid", collectionId); model.addAttribute("owner", collection.getOwner().getUserName().equals(username)); // TODO: showCollaboratingUsers() should be changed with mapper List<IConceptCollectionCollaborator> collaboratingUsers = conceptControllerManager .showCollaboratingUsers(collectionId); model.addAttribute("collaboratingUsers", collaboratingUsers); } /** * This method is used to search the conceptpower for items and will also * give options to add it. * * @param collection_id * @param req * HttpRequest must have pos and search name as parameters to hit * the conceptpower rest service * @param model * @return * @throws QuadrigaStorageException */ @AccessPolicies({ @ElementAccessPolicy(type = CheckedElementType.CONCEPTCOLLECTION, paramIndex = 1, userRole = { RoleNames.ROLE_CC_COLLABORATOR_ADMIN, RoleNames.ROLE_CC_COLLABORATOR_READ_WRITE }) }) @RequestMapping(value = "auth/conceptcollections/{collection_id}/searchitems", method = RequestMethod.GET) public String conceptSearchHandler(@PathVariable("collection_id") String collection_id, HttpServletRequest req, ModelMap model) throws QuadrigaStorageException, QuadrigaAccessException, QuadrigaException { try { ConceptpowerReply conReply = conceptControllerManager.search(req.getParameter("name"), req.getParameter("pos")); if (conReply != null) { List<ConceptEntry> lists = conReply.getConceptEntry(); lists.sort(new Comparator<ConceptEntry>() { @Override public int compare(ConceptEntry o1, ConceptEntry o2) { return o1.getLemma().toLowerCase().compareTo(o2.getLemma().toLowerCase()); } }); model.addAttribute("result", conReply.getConceptEntry()); } } catch (HttpMessageNotReadableException hex) { throw new QuadrigaException(hex); } model.addAttribute("collectionid", collection_id); return "auth/searchitems"; } /** * This method is used to save items into a conceptcollection by searching * and choosing from the conceptpower * * @param collection_id * @param req * HttpRequest must have all the selected concept items ids. * @param model * @param principal * @return * @throws QuadrigaStorageException * @throws QuadrigaAccessException * @throws JSONException */ @AccessPolicies({ @ElementAccessPolicy(type = CheckedElementType.CONCEPTCOLLECTION, paramIndex = 1, userRole = { RoleNames.ROLE_CC_COLLABORATOR_ADMIN, RoleNames.ROLE_CC_COLLABORATOR_READ_WRITE }) }) @RequestMapping(value = "auth/conceptcollections/{collection_id}/addItems", method = RequestMethod.POST) public String saveItemsHandler(@PathVariable("collection_id") String collection_id, HttpServletRequest req, ModelMap model, Principal principal) throws QuadrigaStorageException, QuadrigaAccessException, JSONException { String[] selectedIds = req.getParameterValues("selected"); Map<String, ConceptEntry> allEntries = buildConceptEntries(req.getParameterValues("id"), req.getParameterValues("lemma"), req.getParameterValues("pos"), req.getParameterValues("description"), req.getParameterValues("type"), req.getParameterValues("conceptList")); IConceptCollection conceptCollection = conceptCollectionDeepMapper.getConceptCollectionDetails(collection_id); int addedConcepts = 0; if (conceptCollection != null) { Set<String> existingConceptIds = new HashSet<String>(); for (IConceptCollectionConcepts concept : conceptCollection.getConceptCollectionConcepts()) { existingConceptIds.add(concept.getConcept().getConceptId()); } if (selectedIds != null) { for (String id : selectedIds) { ConceptEntry entry = allEntries.get(id); if (!existingConceptIds.contains(id)) { conceptControllerManager.addItems(entry.getLemma(), id, entry.getPos(), entry.getDescription(), collection_id, principal.getName()); addedConcepts++; } } } } fillModel(collection_id, model, principal.getName()); model.addAttribute("show_success_alert", true); model.addAttribute("success_alert_msg", addedConcepts + " Concepts successfully added."); return "auth/conceptcollections/details"; } private Map<String, ConceptEntry> buildConceptEntries(String[] ids, String[] lemmas, String[] pos, String[] description, String[] types, String[] lists) { Map<String, ConceptEntry> entries = new HashMap<String, ConceptpowerReply.ConceptEntry>(); for (int i = 0; i < ids.length; i++) { ConceptEntry entry = new ConceptEntry(); entry.setId(ids[i]); entry.setConceptList(lists[i]); entry.setDescription(description[i]); entry.setLemma(lemmas[i]); entry.setPos(pos[i]); entry.setType(types[i]); entries.put(entry.getId(), entry); } return entries; } /** * This method handles the addcollections.jsp form which is used to add a * new conceptcollection to quadriga * * @return */ @RequestMapping(value = "auth/conceptcollections/addCollectionsForm", method = RequestMethod.GET) public ModelAndView addCollectionsForm() { return new ModelAndView("auth/conceptcollections/addCollectionsForm", "command", new ConceptCollectionFactory().createConceptCollectionObject()); } /** * This method is used to save the form data submitted for adding a * conceptcollection * * @param collection * @param result * @param model * @param principal * @return Returns the list of concept collections of user to the view * @throws QuadrigaStorageException * * */ @RequestMapping(value = "auth/conceptcollections/addCollectionsForm", method = RequestMethod.POST) public ModelAndView addConceptCollection(@Validated @ModelAttribute("collection") ConceptCollection collection, BindingResult result, Model model, Principal principal) throws QuadrigaStorageException { if (result.hasErrors()) { model.addAttribute("Error", "Error: " + collection.getConceptCollectionName() + "already exists."); return new ModelAndView("auth/conceptcollections/addCollectionsForm", "command", new ConceptCollectionFactory().createConceptCollectionObject()); } IUser user = usermanager.getUser(principal.getName()); collection.setOwner(user); conceptControllerManager.addConceptCollection(collection); return new ModelAndView("redirect:/auth/conceptcollections"); } /** * Returns the list of concept collections of user to the view * * @param req * HttpReqest must have selected items ids as parameters * @param model * @param principal * @return * @throws QuadrigaStorageException * @throws QuadrigaAccessException * @throws JSONException * * */ @AccessPolicies({ @ElementAccessPolicy(type = CheckedElementType.CONCEPTCOLLECTION, paramIndex = 1, userRole = { RoleNames.ROLE_CC_COLLABORATOR_ADMIN, RoleNames.ROLE_CC_COLLABORATOR_READ_WRITE }) }) @RequestMapping(value = "auth/conceptcollections/{collection_id}/deleteitems", method = RequestMethod.POST) public String deleteItems(@PathVariable("collection_id") String collectionId, HttpServletRequest req, ModelMap model, Principal principal) throws QuadrigaStorageException, QuadrigaAccessException, JSONException { String[] selectedIds = req.getParameterValues("selected"); IConceptCollection conceptCollection = conceptCollectionDeepMapper.getConceptCollectionDetails(collectionId); int deletedConceptNr = 0; if (selectedIds != null && conceptCollection != null) { for (String id : selectedIds) { conceptControllerManager.deleteItem(id, collectionId, principal.getName()); IConcept concept = conceptFactory.createConceptObject(); concept.setConceptId(id); if (conceptCollection.getConceptCollectionConcepts().contains(concept)) { conceptCollection.getConceptCollectionConcepts().remove(concept); } } deletedConceptNr = selectedIds.length; } conceptControllerManager.fillConceptCollection(conceptCollection); ; fillModel(collectionId, model, principal.getName()); if (deletedConceptNr > 0) { model.addAttribute("show_success_alert", true); model.addAttribute("success_alert_msg", deletedConceptNr + " Concepts successfully deleted."); } else { model.addAttribute("show_info_alert", true); model.addAttribute("info_alert_msg", "You didn't select any concepts to delete."); } return "auth/conceptcollections/details"; } }