/* * Copyright (c) 2006-2010 by Public Library of Science * * http://plos.org * http://ambraproject.org * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * 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. */ package org.ambraproject.action.user; import org.ambraproject.Constants; import org.ambraproject.models.Journal; import org.ambraproject.models.SavedSearchType; import org.ambraproject.models.UserOrcid; import org.ambraproject.models.UserProfile; import org.ambraproject.service.orcid.OrcidService; import org.ambraproject.service.user.UserAlert; import org.ambraproject.views.SavedSearchView; import org.apache.http.HttpHeaders; import org.apache.struts2.interceptor.ServletRequestAware; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Set; /** * @author Joe Osowski 04/12/2013 * @author Alex Kudlick 10/23/12 */ public class EditUserAction extends UserActionSupport implements ServletRequestAware { private List<SavedSearchView> savedSearches; protected OrcidService orcidService; protected String orcid; private String clientID; private String scope; private String orcidAuth; private String redirectURL; private HttpServletRequest request; //tabID maps to tabs defined in user.js private String tabID = "profile"; @Override public String execute() throws Exception { String authId = getUserAuthId(); UserProfile userProfile = userService.getUserByAuthId(authId); setFieldsFromProfile(userProfile); monthlyAlerts = userProfile.getMonthlyAlerts(); weeklyAlerts = userProfile.getWeeklyAlerts(); showDisplayName = false; List<SavedSearchView> searches = userService.getSavedSearches(userProfile.getID()); savedSearches = new ArrayList<SavedSearchView>(); journalSubjectFilters = new HashMap<String, String[]>(); for(SavedSearchView search : searches) { if(search.getSearchType() == SavedSearchType.USER_DEFINED) { savedSearches.add(search); } else { //Only two types are supported the above and "SavedSearchType.JOURNAL_ALERT" //The second should be grouped by journal for the view String[] journals = search.getSearchParameters().getFilterJournals(); if(journals == null || journals.length != 1) { throw new RuntimeException("Journal not specified for filter or specified multiple times."); } String curJournal = journals[0]; String[] subjectFilters = search.getSearchParameters().getFilterSubjectsDisjunction(); //Assume one search alert per journal //Kludge: Deparse the journal. This will only work for journals where the only difference between the values //are case changes journalSubjectFilters.put(curJournal.toLowerCase(), subjectFilters); //Append the weekly alert for the view //Kludge: Deparse the journal. This will only work for journals where the only difference between the values //are case changes weeklyAlerts.add(curJournal.toLowerCase()); } } UserOrcid userOrcid = userService.getUserOrcid(userProfile.getID()); if(userOrcid != null) { orcid = userOrcid.getOrcid(); } clientID = orcidService.getClientID(); scope = orcidService.getScope(); orcidAuth = configuration.getString(OrcidService.ORCID_AUTHORIZATION_URL); //TODO: Better way to handle this? Config? redirectURL = "http://" + request.getHeader(HttpHeaders.HOST) + "/user/secure/profile/orcid/confirm"; return SUCCESS; } public String retrieveAlerts() throws Exception { tabID = "journalAlerts"; return execute(); } public String retrieveSearchAlerts() throws Exception { tabID = "savedSearchAlerts"; return execute(); } public String saveUser() throws Exception { boolean valid = validateProfileInput(); if (!valid) { //Fill in values for the front end execute(); return INPUT; } UserProfile profile = createProfileFromFields(); //Make sure to set the auth id so the user service can see if this account already exists String userAuthId = getUserAuthId(); profile.setAuthId(userAuthId); UserProfile savedProfile = userService.updateProfile(profile); session.put(Constants.AMBRA_USER_KEY, savedProfile); return execute(); } /** * Save the alerts. * * @return webwork status * @throws Exception Exception */ public String saveAlerts() throws Exception { final String authId = getUserAuthId(); if (authId == null) { throw new ServletException("Unable to resolve ambra user"); } if(validateAlertInput()) { UserProfile profile = userService.getUserByAuthId(authId); if(this.filterSpecified != null) { for(String journal : filterSpecified.keySet()) { String journalKey = translateJournalKey(journal); //If the journal is not checked for weekly, just remove the alert boolean weeklyChecked = false; for(String s : weeklyAlerts) { if(journal.equals(s)) { weeklyChecked = true; } } if(!weeklyChecked) { userService.removedFilteredWeeklySearchAlert(profile.getID(), journalKey); break; } if(filterSpecified.get(journal) != null && filterSpecified.get(journal).equals("subjects")) { String[] subjects = journalSubjectFilters.get(journal); userService.setFilteredWeeklySearchAlert(profile.getID(), subjects, journalKey); //The weekly alert is actually a savedSearch, remove from list weeklyAlerts.remove(journal); } else { userService.removedFilteredWeeklySearchAlert(profile.getID(), journalKey); } } } else { //If there is no filterSpecified make sure there are no filtered search alerts for(UserAlert s : this.getUserAlerts()) { userService.removedFilteredWeeklySearchAlert(profile.getID(), s.getKey()); } } profile = userService.setAlerts(authId, monthlyAlerts, weeklyAlerts); session.put(Constants.AMBRA_USER_KEY, profile); } return retrieveAlerts(); } /** * * Kind of kludge, but we seemingly have two ways of representing journalkeys in the ambra.xml * This only works as plosone is the same as "PLoSONE". Not all journal names use this same convention. * These terms need to be corrected! However, any changes made to these keys will cause user search * Alerts to be lost. A data migration will have to be performed * * @param journal * * @return */ private String translateJournalKey(String journal) { Set<Journal> journals = journalService.getAllJournals(); for(Journal j : journals) { if(j.getJournalKey().toLowerCase().equals(journal)) { return j.getJournalKey(); } } throw new RuntimeException("Can not find journal of name:" + journal); } /** * save the user search alerts * @return webwork status * @throws Exception */ public String saveSearchAlerts() throws Exception { final String authId = getUserAuthId(); if (authId == null) { throw new ServletException("Unable to resolve ambra user"); } UserProfile profile = userService.setSavedSearchAlerts(authId, monthlyAlerts, weeklyAlerts, deleteAlerts); session.put(Constants.AMBRA_USER_KEY, profile); return retrieveSearchAlerts(); } private String getUserAuthId() { return (String) session.get(Constants.AUTH_KEY); } public String getTabID() { return tabID; } public String getOrcid() { return orcid; } public String getClientID() { return clientID; } public String getScope() { return scope; } public String getOrcidAuth() { return orcidAuth; } public String getRedirectURL() { return redirectURL; } public Collection<SavedSearchView> getUserSearchAlerts() throws Exception { return savedSearches; } public void setOrcidService(OrcidService orcidService) { this.orcidService = orcidService; } public void setServletRequest(HttpServletRequest request) { this.request = request; } }