001/**
002 * Copyright 2005-2016 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.krad.web.controller;
017
018import java.util.Collection;
019import java.util.Properties;
020import java.util.Set;
021
022import javax.servlet.http.HttpServletRequest;
023import javax.servlet.http.HttpServletResponse;
024
025import org.apache.commons.lang.StringUtils;
026import org.kuali.rice.core.api.exception.RiceRuntimeException;
027import org.kuali.rice.krad.lookup.CollectionIncomplete;
028import org.kuali.rice.krad.lookup.Lookupable;
029import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
030import org.kuali.rice.krad.service.ModuleService;
031import org.kuali.rice.krad.uif.UifConstants;
032import org.kuali.rice.krad.uif.UifParameters;
033import org.kuali.rice.krad.uif.UifPropertyPaths;
034import org.kuali.rice.krad.util.GlobalVariables;
035import org.kuali.rice.krad.util.KRADConstants;
036import org.kuali.rice.krad.util.KRADUtils;
037import org.kuali.rice.krad.web.form.LookupForm;
038import org.kuali.rice.krad.web.form.UifFormBase;
039import org.springframework.stereotype.Controller;
040import org.springframework.validation.BindingResult;
041import org.springframework.web.bind.annotation.ModelAttribute;
042import org.springframework.web.bind.annotation.RequestMapping;
043import org.springframework.web.servlet.ModelAndView;
044
045/**
046 * Controller that handles requests coming from a <code>LookupView</code>
047 *
048 * @author Kuali Rice Team (rice.collab@kuali.org)
049 */
050@Controller
051@RequestMapping(value = "/lookup")
052public class LookupController extends UifControllerBase {
053    private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(LookupController.class);
054
055    /**
056     * @see org.kuali.rice.krad.web.controller.UifControllerBase#createInitialForm(javax.servlet.http.HttpServletRequest)
057     */
058    @Override
059    protected LookupForm createInitialForm(HttpServletRequest request) {
060        return new LookupForm();
061    }
062
063    /**
064     * Invoked to request an lookup view for a data object class
065     *
066     * <p>
067     * Checks if the data object is externalizable and we need to redirect to the appropriate lookup URL, else
068     * continues with the lookup view display
069     * </p>
070     */
071    @RequestMapping(params = "methodToCall=start")
072    @Override
073    public ModelAndView start(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
074            HttpServletRequest request, HttpServletResponse response) {
075        LookupForm lookupForm = (LookupForm) form;
076
077        Lookupable lookupable = lookupForm.getLookupable();
078        if (lookupable == null) {
079            LOG.error("Lookupable is null.");
080            throw new RuntimeException("Lookupable is null.");
081        }
082        lookupable.initSuppressAction(lookupForm);
083
084        // if request is not a redirect, determine if we need to redirect for an externalizable object lookup
085        if (!lookupForm.isRedirectedLookup()) {
086            Class lookupObjectClass = null;
087            try {
088                lookupObjectClass = Class.forName(lookupForm.getDataObjectClassName());
089            } catch (ClassNotFoundException e) {
090                throw new RiceRuntimeException("Unable to get class for name: " + lookupForm.getDataObjectClassName());
091            }
092
093            ModuleService responsibleModuleService =
094                    KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService(lookupObjectClass);
095            if (responsibleModuleService != null && responsibleModuleService.isExternalizable(lookupObjectClass)) {
096                String lookupUrl = responsibleModuleService.getExternalizableDataObjectLookupUrl(lookupObjectClass,
097                        KRADUtils.convertRequestMapToProperties(request.getParameterMap()));
098
099                Properties redirectUrlProps = new Properties();
100                redirectUrlProps.put(UifParameters.REDIRECTED_LOOKUP, "true");
101
102                // clear current form from session
103                GlobalVariables.getUifFormManager().removeForm(form);
104
105                return performRedirect(form, lookupUrl, redirectUrlProps);
106            }
107        }
108
109        return super.start(lookupForm, result, request, response);
110    }
111
112    /**
113     * Just returns as if return with no value was selected
114     */
115    @Override
116    @RequestMapping(params = "methodToCall=cancel")
117    public ModelAndView cancel(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
118            HttpServletRequest request, HttpServletResponse response) {
119        LookupForm lookupForm = (LookupForm) form;
120
121        Lookupable lookupable = lookupForm.getLookupable();
122        if (lookupable == null) {
123            LOG.error("Lookupable is null.");
124            throw new RuntimeException("Lookupable is null.");
125        }
126        lookupable.initSuppressAction(lookupForm);
127
128        Properties props = new Properties();
129        props.put(UifParameters.METHOD_TO_CALL, UifConstants.MethodToCallNames.REFRESH);
130        if (StringUtils.isNotBlank(lookupForm.getReturnFormKey())) {
131            props.put(UifParameters.FORM_KEY, lookupForm.getReturnFormKey());
132        }
133        if (StringUtils.isNotBlank(lookupForm.getDocNum())) {
134            props.put(UifParameters.DOC_NUM, lookupForm.getDocNum());
135        }
136
137        // clear current form from session
138        GlobalVariables.getUifFormManager().removeForm(form);
139
140        return performRedirect(lookupForm, lookupForm.getReturnLocation(), props);
141    }
142
143    /**
144     * clearValues - clears the values of all the fields on the jsp.
145     */
146    @RequestMapping(params = "methodToCall=clearValues")
147    public ModelAndView clearValues(@ModelAttribute("KualiForm") LookupForm lookupForm, BindingResult result,
148            HttpServletRequest request, HttpServletResponse response) {
149
150        Lookupable lookupable = lookupForm.getLookupable();
151        if (lookupable == null) {
152            LOG.error("Lookupable is null.");
153            throw new RuntimeException("Lookupable is null.");
154        }
155        lookupable.initSuppressAction(lookupForm);
156        lookupForm.setCriteriaFields(lookupable.performClear(lookupForm, lookupForm.getCriteriaFields()));
157
158        return getUIFModelAndView(lookupForm);
159    }
160
161    /**
162     * search - sets the values of the data entered on the form on the jsp into a map and then searches for the
163     * results.
164     */
165    @RequestMapping(params = "methodToCall=search")
166    public ModelAndView search(@ModelAttribute("KualiForm") LookupForm lookupForm, BindingResult result,
167            HttpServletRequest request, HttpServletResponse response) {
168
169        Lookupable lookupable = lookupForm.getLookupable();
170        if (lookupable == null) {
171            LOG.error("Lookupable is null.");
172            throw new RuntimeException("Lookupable is null.");
173        }
174        lookupable.initSuppressAction(lookupForm);
175
176        // validate search parameters
177        lookupable.validateSearchParameters(lookupForm, lookupForm.getCriteriaFields());
178
179        Collection<?> displayList =
180                lookupable.performSearch(lookupForm, lookupForm.getCriteriaFields(), true);
181
182        if (displayList instanceof CollectionIncomplete<?>) {
183            request.setAttribute("reqSearchResultsActualSize",
184                    ((CollectionIncomplete<?>) displayList).getActualSizeIfTruncated());
185        } else {
186            request.setAttribute("reqSearchResultsActualSize", new Integer(displayList.size()));
187        }
188
189        lookupForm.setSearchResults(displayList);
190
191        return getUIFModelAndView(lookupForm);
192    }
193
194    /**
195     * Invoked from the UI to return the selected lookup results lines, parameters are collected to build a URL to
196     * the caller and then a redirect is performed
197     *
198     * @param lookupForm - lookup form instance containing the selected results and lookup configuration
199     */
200    @RequestMapping(params = "methodToCall=returnSelected")
201    public ModelAndView returnSelected(@ModelAttribute("KualiForm") LookupForm lookupForm, BindingResult result,
202            HttpServletRequest request, HttpServletResponse response) {
203        Properties parameters = new Properties();
204        parameters.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, KRADConstants.RETURN_METHOD_TO_CALL);
205
206        if (StringUtils.isNotBlank(lookupForm.getReturnFormKey())) {
207            parameters.put(UifParameters.FORM_KEY, lookupForm.getReturnFormKey());
208        }
209
210        parameters.put(KRADConstants.REFRESH_CALLER, lookupForm.getView().getId());
211        parameters.put(KRADConstants.REFRESH_CALLER_TYPE, UifConstants.RefreshCallerTypes.MULTI_VALUE_LOOKUP);
212        parameters.put(KRADConstants.REFRESH_DATA_OBJECT_CLASS, lookupForm.getDataObjectClassName());
213
214        if (StringUtils.isNotBlank(lookupForm.getDocNum())) {
215            parameters.put(UifParameters.DOC_NUM, lookupForm.getDocNum());
216        }
217
218        if (StringUtils.isNotBlank(lookupForm.getLookupCollectionName())) {
219            parameters.put(UifParameters.LOOKUP_COLLECTION_NAME, lookupForm.getLookupCollectionName());
220        }
221
222        if (StringUtils.isNotBlank(lookupForm.getReferencesToRefresh())) {
223            parameters.put(KRADConstants.REFERENCES_TO_REFRESH, lookupForm.getReferencesToRefresh());
224        }
225
226        // build string of select line identifiers
227        String selectedLineValues = "";
228        Set<String> selectedLines = lookupForm.getSelectedCollectionLines().get(UifPropertyPaths.SEARCH_RESULTS);
229        if (selectedLines != null) {
230            for (String selectedLine : selectedLines) {
231                selectedLineValues += selectedLine + ",";
232            }
233            selectedLineValues = StringUtils.removeEnd(selectedLineValues, ",");
234        }
235
236        parameters.put(UifParameters.SELECTED_LINE_VALUES, selectedLineValues);
237
238        // clear current form from session
239        GlobalVariables.getUifFormManager().removeForm(lookupForm);
240
241        return performRedirect(lookupForm, lookupForm.getReturnLocation(), parameters);
242    }
243}