/** * ============================================================================= * * ORCID (R) Open Source * http://orcid.org * * Copyright (c) 2012-2014 ORCID, Inc. * Licensed under an MIT-Style License (MIT) * http://orcid.org/open-source-license * * This copyright and license information (including a link to the full license) * shall be included in its entirety in all copies or substantial portion of * the software. * * ============================================================================= */ package org.orcid.frontend.web.controllers; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import org.orcid.core.manager.AffiliationsManager; import org.orcid.core.manager.OrgDisambiguatedManager; import org.orcid.core.manager.ProfileEntityCacheManager; import org.orcid.core.security.visibility.OrcidVisibilityDefaults; import org.orcid.jaxb.model.record_v2.Affiliation; import org.orcid.jaxb.model.record_v2.AffiliationType; import org.orcid.jaxb.model.record_v2.Education; import org.orcid.jaxb.model.record_v2.Employment; import org.orcid.persistence.jpa.entities.CountryIsoEntity; import org.orcid.persistence.jpa.entities.ProfileEntity; import org.orcid.pojo.OrgDisambiguated; import org.orcid.pojo.ajaxForm.AffiliationForm; import org.orcid.pojo.ajaxForm.Date; import org.orcid.pojo.ajaxForm.PojoUtil; import org.orcid.pojo.ajaxForm.Text; import org.orcid.pojo.ajaxForm.Visibility; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; 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; /** * @author rcpeters */ @Controller("affiliationsController") @RequestMapping(value = { "/affiliations" }) public class AffiliationsController extends BaseWorkspaceController { private static final String AFFILIATIONS_MAP = "AFFILIATIONS_MAP"; @Resource private OrgDisambiguatedManager orgDisambiguatedManager; @Resource private AffiliationsManager affiliationsManager; @Resource private ProfileEntityCacheManager profileEntityCacheManager; /** * Removes a affiliation from a profile * */ @RequestMapping(value = "/affiliations.json", method = RequestMethod.DELETE) public @ResponseBody AffiliationForm removeAffiliationJson(HttpServletRequest request, @RequestBody AffiliationForm affiliation) { affiliationsManager.removeAffiliation(getCurrentUserOrcid(), Long.valueOf(affiliation.getPutCode().getValue())); return affiliation; } /** * List affiliations associated with a profile * */ @SuppressWarnings("unchecked") @RequestMapping(value = "/affiliations.json", method = RequestMethod.GET) public @ResponseBody List<AffiliationForm> getAffiliationJson(HttpServletRequest request, @RequestParam(value = "affiliationIds") String affiliationIdsStr) { List<AffiliationForm> affiliationList = new ArrayList<>(); AffiliationForm affiliation = null; String[] affiliationIds = affiliationIdsStr.split(","); if (affiliationIds != null) { HashMap<String, AffiliationForm> affiliationsMap = (HashMap<String, AffiliationForm>) request.getSession().getAttribute(AFFILIATIONS_MAP); // this should never happen, but just in case. if (affiliationsMap == null) { createAffiliationsIdList(request); affiliationsMap = (HashMap<String, AffiliationForm>) request.getSession().getAttribute(AFFILIATIONS_MAP); } for (String affiliationId : affiliationIds) { affiliation = affiliationsMap.get(affiliationId); if(affiliation.getStartDate() == null) { initializeStartDate(affiliation); } else { if(affiliation.getStartDate().getDay() == null) { affiliation.getStartDate().setDay(new String()); } if(affiliation.getStartDate().getMonth() == null) { affiliation.getStartDate().setMonth(new String()); } if(affiliation.getStartDate().getYear() == null) { affiliation.getStartDate().setYear(new String()); } } if(affiliation.getEndDate() == null) { initializeEndDate(affiliation); } else { if(affiliation.getEndDate().getDay() == null) { affiliation.getEndDate().setDay(new String()); } if(affiliation.getEndDate().getMonth() == null) { affiliation.getEndDate().setMonth(new String()); } if(affiliation.getEndDate().getYear() == null) { affiliation.getEndDate().setYear(new String()); } } affiliationList.add(affiliation); } } return affiliationList; } private void initializeStartDate(AffiliationForm affiliation) { if (affiliation.getStartDate() == null) { affiliation.setStartDate(getEmptyDate()); } } private void initializeEndDate(AffiliationForm affiliation) { if (affiliation.getEndDate() == null) { affiliation.setEndDate(getEmptyDate()); } } private Date getEmptyDate() { Date date = new Date(); date.setDay(new String()); date.setMonth(new String()); date.setYear(new String()); return date; } /** * Returns a blank affiliation form * */ @RequestMapping(value = "/affiliation.json", method = RequestMethod.GET) public @ResponseBody AffiliationForm getAffiliation(HttpServletRequest request) { AffiliationForm affiliationForm = new AffiliationForm(); ProfileEntity profile = profileEntityCacheManager.retrieve(getCurrentUserOrcid()); Visibility v = Visibility.valueOf(profile.getActivitiesVisibilityDefault() == null ? org.orcid.jaxb.model.common_v2.Visibility.fromValue(OrcidVisibilityDefaults.FUNDING_DEFAULT.getVisibility().value()) : profile.getActivitiesVisibilityDefault()); affiliationForm.setVisibility(v); Text affiliationName = new Text(); affiliationForm.setAffiliationName(affiliationName); affiliationName.setRequired(true); Text city = new Text(); affiliationForm.setCity(city); Text region = new Text(); affiliationForm.setRegion(region); Text country = new Text(); affiliationForm.setCountry(country); country.setValue(""); country.setRequired(true); Text department = new Text(); affiliationForm.setDepartmentName(department); Text roleTitle = new Text(); affiliationForm.setRoleTitle(roleTitle); Text affiliationType = new Text(); affiliationForm.setAffiliationType(affiliationType); affiliationType.setValue(""); Date startDate = new Date(); affiliationForm.setStartDate(startDate); startDate.setDay(""); startDate.setMonth(""); startDate.setYear(""); Date endDate = new Date(); affiliationForm.setEndDate(endDate); endDate.setDay(""); endDate.setMonth(""); endDate.setYear(""); affiliationForm.setOrgDisambiguatedId(new Text()); return affiliationForm; } @RequestMapping(value = "/affiliation.json", method = RequestMethod.POST) public @ResponseBody AffiliationForm postAffiliation(HttpServletRequest request, @RequestBody AffiliationForm affiliationForm) throws Exception { // Validate affiliationNameValidate(affiliationForm); cityValidate(affiliationForm); regionValidate(affiliationForm); countryValidate(affiliationForm); departmentValidate(affiliationForm); roleTitleValidate(affiliationForm); datesValidate(affiliationForm); copyErrors(affiliationForm.getAffiliationName(), affiliationForm); copyErrors(affiliationForm.getCity(), affiliationForm); copyErrors(affiliationForm.getRegion(), affiliationForm); copyErrors(affiliationForm.getCountry(), affiliationForm); copyErrors(affiliationForm.getDepartmentName(), affiliationForm); copyErrors(affiliationForm.getRoleTitle(), affiliationForm); if(!PojoUtil.isEmpty(affiliationForm.getStartDate())) copyErrors(affiliationForm.getStartDate(), affiliationForm); if(!PojoUtil.isEmpty(affiliationForm.getEndDate())) copyErrors(affiliationForm.getEndDate(), affiliationForm); if (affiliationForm.getErrors().isEmpty()) { if(PojoUtil.isEmpty(affiliationForm.getPutCode())) addAffiliation(affiliationForm); else editAffiliation(affiliationForm); } return affiliationForm; } /** * Adds a new affiliations * @param affiliationForm * */ private void addAffiliation(AffiliationForm affiliationForm) { Affiliation affiliation = affiliationForm.toAffiliation(); if(AffiliationType.EDUCATION.value().equals(affiliationForm.getAffiliationType().getValue())) { affiliation = affiliationsManager.createEducationAffiliation(getCurrentUserOrcid(), (Education) affiliation, false); } else { affiliation = affiliationsManager.createEmploymentAffiliation(getCurrentUserOrcid(), (Employment) affiliation, false); } affiliationForm.setPutCode(Text.valueOf(affiliation.getPutCode())); } /** * Updates an existing affiliation * @param affiliationForm * @throws Exception * */ private void editAffiliation(AffiliationForm affiliationForm) throws Exception { if (!getCurrentUserOrcid().equals(affiliationForm.getSource())) throw new Exception(getMessage("web.orcid.activity_incorrectsource.exception")); Affiliation affiliation = affiliationForm.toAffiliation(); if(AffiliationType.EDUCATION.value().equals(affiliationForm.getAffiliationType().getValue())) { affiliation = affiliationsManager.updateEducationAffiliation(getCurrentUserOrcid(), (Education) affiliation, false); } else { affiliation = affiliationsManager.updateEmploymentAffiliation(getCurrentUserOrcid(), (Employment) affiliation, false); } } /** * List affiliations associated with a profile * */ @RequestMapping(value = "/affiliationIds.json", method = RequestMethod.GET) public @ResponseBody List<String> getAffiliationsJson(HttpServletRequest request) { // Get cached profile List<String> affiliationIds = createAffiliationsIdList(request); return affiliationIds; } /** * Create an affiliation id list and sorts a map associated with the list in * in the session * */ private List<String> createAffiliationsIdList(HttpServletRequest request) { List<Affiliation> affiliationsList = affiliationsManager.getAffiliations(getCurrentUserOrcid()); HashMap<String, AffiliationForm> affiliationsMap = new HashMap<>(); List<String> affiliationIds = new ArrayList<String>(); if (affiliationsList != null) { for (Affiliation affiliation : affiliationsList) { AffiliationForm form = AffiliationForm.valueOf(affiliation); form.setCountryForDisplay(getMessage(buildInternationalizationKey(CountryIsoEntity.class, form.getCountry().getValue()))); affiliationsMap.put(form.getPutCode().getValue(), form); affiliationIds.add(form.getPutCode().getValue()); } request.getSession().setAttribute(AFFILIATIONS_MAP, affiliationsMap); } return affiliationIds; } /** * Updates an affiliation visibility * */ @RequestMapping(value = "/affiliation.json", method = RequestMethod.PUT) public @ResponseBody AffiliationForm updateAffiliationVisibility(HttpServletRequest request, @RequestBody AffiliationForm affiliation) { org.orcid.jaxb.model.common_v2.Visibility visibility = org.orcid.jaxb.model.common_v2.Visibility.fromValue(affiliation.getVisibility().getVisibility().value()); affiliationsManager.updateVisibility(getEffectiveUserOrcid(), Long.valueOf(affiliation.getPutCode().getValue()), visibility); return affiliation; } /** * Search DB for disambiguated affiliations to suggest to user */ @RequestMapping(value = "/disambiguated/name/{query}", method = RequestMethod.GET) public @ResponseBody List<Map<String, String>> searchDisambiguated(@PathVariable("query") String query, @RequestParam(value = "limit") int limit) { List<Map<String, String>> datums = new ArrayList<>(); for (OrgDisambiguated orgDisambiguated : orgDisambiguatedManager.searchOrgsFromSolr(query, 0, limit,false)) { datums.add(orgDisambiguated.toMap()); } return datums; } /** * fetch disambiguated by id */ @RequestMapping(value = "/disambiguated/id/{id}", method = RequestMethod.GET) public @ResponseBody Map<String, String> getDisambiguated(@PathVariable("id") Long id) { OrgDisambiguated orgDisambiguated = orgDisambiguatedManager.findInDB(id); return orgDisambiguated.toMap(); } @RequestMapping(value = "/affiliation/affiliationNameValidate.json", method = RequestMethod.POST) public @ResponseBody AffiliationForm affiliationNameValidate(@RequestBody AffiliationForm affiliationForm) { affiliationForm.getAffiliationName().setErrors(new ArrayList<String>()); if (affiliationForm.getAffiliationName().getValue() == null || affiliationForm.getAffiliationName().getValue().trim().length() == 0) { setError(affiliationForm.getAffiliationName(), "NotBlank.manualAffiliation.name"); } else { if (affiliationForm.getAffiliationName().getValue().trim().length() > 1000) { setError(affiliationForm.getAffiliationName(), "common.length_less_1000"); } } return affiliationForm; } @RequestMapping(value = "/affiliation/cityValidate.json", method = RequestMethod.POST) public @ResponseBody AffiliationForm cityValidate(@RequestBody AffiliationForm affiliationForm) { affiliationForm.getCity().setErrors(new ArrayList<String>()); if (affiliationForm.getCity().getValue() == null || affiliationForm.getCity().getValue().trim().length() == 0) { setError(affiliationForm.getCity(), "NotBlank.manualAffiliation.city"); } else { if (affiliationForm.getCity().getValue().trim().length() > 1000) { setError(affiliationForm.getCity(), "common.length_less_1000"); } } return affiliationForm; } @RequestMapping(value = "/affiliation/regionValidate.json", method = RequestMethod.POST) public @ResponseBody AffiliationForm regionValidate(@RequestBody AffiliationForm affiliationForm) { affiliationForm.getRegion().setErrors(new ArrayList<String>()); if (affiliationForm.getRegion().getValue() != null && affiliationForm.getRegion().getValue().trim().length() > 1000) { setError(affiliationForm.getRegion(), "common.length_less_1000"); } return affiliationForm; } @RequestMapping(value = "/affiliation/countryValidate.json", method = RequestMethod.POST) public @ResponseBody AffiliationForm countryValidate(@RequestBody AffiliationForm affiliationForm) { affiliationForm.getCountry().setErrors(new ArrayList<String>()); if (affiliationForm.getCountry().getValue() == null || affiliationForm.getCountry().getValue().trim().length() == 0) { setError(affiliationForm.getCountry(), "common.country.not_blank"); } return affiliationForm; } @RequestMapping(value = "/affiliation/departmentValidate.json", method = RequestMethod.POST) public @ResponseBody AffiliationForm departmentValidate(@RequestBody AffiliationForm affiliationForm) { affiliationForm.getDepartmentName().setErrors(new ArrayList<String>()); if (affiliationForm.getDepartmentName().getValue() != null && affiliationForm.getDepartmentName().getValue().trim().length() > 1000) { setError(affiliationForm.getDepartmentName(), "common.length_less_1000"); } return affiliationForm; } @RequestMapping(value = "/affiliation/roleTitleValidate.json", method = RequestMethod.POST) public @ResponseBody AffiliationForm roleTitleValidate(@RequestBody AffiliationForm affiliationForm) { affiliationForm.getRoleTitle().setErrors(new ArrayList<String>()); if (!PojoUtil.isEmpty(affiliationForm.getRoleTitle()) && affiliationForm.getRoleTitle().getValue().trim().length() > 1000) { setError(affiliationForm.getRoleTitle(), "common.length_less_1000"); } return affiliationForm; } @RequestMapping(value = "/affiliation/datesValidate.json", method = RequestMethod.POST) public @ResponseBody AffiliationForm datesValidate(@RequestBody AffiliationForm affiliationForm) { boolean primaryValidation = true; if(!PojoUtil.isEmpty(affiliationForm.getStartDate())) affiliationForm.getStartDate().setErrors(new ArrayList<String>()); if(!PojoUtil.isEmpty(affiliationForm.getEndDate())) affiliationForm.getEndDate().setErrors(new ArrayList<String>()); if((PojoUtil.isEmpty(affiliationForm.getStartDate().getYear()) && (!PojoUtil.isEmpty(affiliationForm.getStartDate().getMonth()) || !PojoUtil.isEmpty(affiliationForm.getStartDate().getDay()))) || (!PojoUtil.isEmpty(affiliationForm.getStartDate().getYear()) && !PojoUtil.isEmpty(affiliationForm.getStartDate().getDay()) && PojoUtil.isEmpty(affiliationForm.getStartDate().getMonth()))) { primaryValidation = false; setError(affiliationForm.getStartDate(), "common.dates.invalid"); } if((PojoUtil.isEmpty(affiliationForm.getEndDate().getYear()) && (!PojoUtil.isEmpty(affiliationForm.getEndDate().getMonth()) || !PojoUtil.isEmpty(affiliationForm.getEndDate().getDay()))) || (!PojoUtil.isEmpty(affiliationForm.getEndDate().getYear()) && !PojoUtil.isEmpty(affiliationForm.getEndDate().getDay()) && PojoUtil.isEmpty(affiliationForm.getEndDate().getMonth()))) { primaryValidation = false; setError(affiliationForm.getEndDate(), "common.dates.invalid"); } if (primaryValidation && (!PojoUtil.isEmpty(affiliationForm.getStartDate()) && !PojoUtil.isEmpty(affiliationForm.getEndDate()))) { if (affiliationForm.getStartDate().toJavaDate().after(affiliationForm.getEndDate().toJavaDate())) setError(affiliationForm.getEndDate(), "manualAffiliation.endDate.after"); } return affiliationForm; } }