001/**
002 * Copyright 2005-2018 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.kns.web.struts.form;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.rice.kns.lookup.HtmlData;
020import org.kuali.rice.kns.lookup.LookupUtils;
021import org.kuali.rice.kns.util.PagingBannerUtils;
022import org.kuali.rice.krad.util.KRADConstants;
023
024import javax.servlet.http.HttpServletRequest;
025import java.util.Enumeration;
026import java.util.HashSet;
027import java.util.Map;
028import java.util.Set;
029
030/**
031 * Form to handle multiple value lookups 
032 * 
033 * @author Kuali Rice Team (rice.collab@kuali.org)
034 *
035 * @deprecated KNS Struts deprecated, use KRAD and the Spring MVC framework.
036 */
037@Deprecated
038public class MultipleValueLookupForm extends LookupForm {
039    private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(MultipleValueLookupForm.class);
040    
041    private KualiTableRenderFormMetadata tableMetadata;
042    
043    private String lookupResultsSequenceNumber;
044    
045    /**
046     * @see LookupForm#addRequiredNonEditableProperties()
047     */
048    @Override
049    public void addRequiredNonEditableProperties(){
050        super.addRequiredNonEditableProperties();
051        registerRequiredNonEditableProperty(KRADConstants.LOOKUP_RESULTS_SEQUENCE_NUMBER);
052        registerRequiredNonEditableProperty(KRADConstants.LOOKED_UP_COLLECTION_NAME);
053    }
054    
055    /**
056     * The number of rows that match the query criteria
057     */
058    private int resultsActualSize;
059    
060    /**
061     * The number of rows that match the query criteria or
062     *  the max results limit size (if applicable), whichever is less
063     */
064    private int resultsLimitedSize;
065    
066    /**
067     * when the looked results screen was rendered, the index of the column that the results were sorted on.  -1 for unknown, index numbers
068     * starting at 0
069     */
070    private String previouslySortedColumnIndex;
071    
072    /**
073     * Comment for <code>columnToSortIndex</code>
074     */
075    private int columnToSortIndex;
076    
077    /**
078     * the name of the collection being looked up by the calling page.  This value will be returned unmodified to the 
079     * calling page (indicated by super.getBackLocation()), which should use it to determine in which collection the 
080     * selected results will be returned.
081     */
082    private String lookedUpCollectionName;
083    
084    /**
085     * Those object IDs that were selected before the current page is rendered 
086     */
087    private Set<String> previouslySelectedObjectIdSet;
088    /**
089     * Those object IDs that are rendered on the current page
090     */
091    private Set<String> displayedObjectIdSet;
092    /**
093     * Those object IDs that are selected/checked on the current page
094     */
095    private Set<String> selectedObjectIdSet;
096    /**
097     * The object IDs that are selected after the struts action is complete; the obj IDs in the keys of this Map will be considered checked in the UI
098     */
099    private Map<String, String> compositeObjectIdMap;
100    
101    public MultipleValueLookupForm() {
102        tableMetadata = new KualiTableRenderFormMetadata();
103        setHtmlDataType(HtmlData.INPUT_HTML_DATA_TYPE);
104    }
105    
106    @Override
107    public void populate(HttpServletRequest request) {
108        super.populate(request);
109        
110        if (StringUtils.isNotBlank(request.getParameter(KRADConstants.TableRenderConstants.VIEWED_PAGE_NUMBER))) {
111            setViewedPageNumber(Integer.parseInt(request.getParameter(KRADConstants.TableRenderConstants.VIEWED_PAGE_NUMBER)));
112        }
113        else {
114            setViewedPageNumber(0); // first page is page 0
115        }
116        
117        if (KRADConstants.TableRenderConstants.SWITCH_TO_PAGE_METHOD.equals(getMethodToCall())) {
118            final String paramPrefix = KRADConstants.DISPATCH_REQUEST_PARAMETER + "." + KRADConstants.TableRenderConstants.SWITCH_TO_PAGE_METHOD + ".";
119                setSwitchToPageNumber(PagingBannerUtils.getNumbericalValueAfterPrefix(paramPrefix, request.getParameterNames()));
120            if (getSwitchToPageNumber() == -1) {
121                throw new RuntimeException("Couldn't find page number");
122            }
123        }
124        
125        if (KRADConstants.TableRenderConstants.SORT_METHOD.equals(getMethodToCall())) {
126            final String paramPrefix = KRADConstants.DISPATCH_REQUEST_PARAMETER + "." + KRADConstants.TableRenderConstants.SORT_METHOD + ".";
127            setColumnToSortIndex(
128                    PagingBannerUtils.getNumbericalValueAfterPrefix(paramPrefix, request.getParameterNames()));
129            if (getColumnToSortIndex() == -1) {
130                throw new RuntimeException("Couldn't find column to sort");
131            }
132        }
133        
134        setPreviouslySelectedObjectIdSet(parsePreviouslySelectedObjectIds(request));
135        setSelectedObjectIdSet(parseSelectedObjectIdSet(request));
136        setDisplayedObjectIdSet(parseDisplayedObjectIdSet(request));
137
138        setSearchUsingOnlyPrimaryKeyValues(parseSearchUsingOnlyPrimaryKeyValues(request));
139        if (isSearchUsingOnlyPrimaryKeyValues()) {
140            setPrimaryKeyFieldLabels(getLookupable().getPrimaryKeyFieldLabels());
141        }
142    }
143    
144
145    
146    /**
147     * This method converts the composite object IDs into a String
148     * @return
149     */
150    public String getCompositeSelectedObjectIds() {
151        return LookupUtils.convertSetOfObjectIdsToString(getCompositeObjectIdMap().keySet());
152    }
153
154    protected Set<String> parsePreviouslySelectedObjectIds(HttpServletRequest request) {
155        String previouslySelectedObjectIds = request.getParameter(KRADConstants.MULTIPLE_VALUE_LOOKUP_PREVIOUSLY_SELECTED_OBJ_IDS_PARAM);
156        return LookupUtils.convertStringOfObjectIdsToSet(previouslySelectedObjectIds);
157    }
158    
159    protected Set<String> parseSelectedObjectIdSet(HttpServletRequest request) {
160        Set<String> set = new HashSet<String>();
161        
162        Enumeration paramNames = request.getParameterNames();
163        while (paramNames.hasMoreElements()) {
164            String paramName = (String) paramNames.nextElement();
165            if (paramName.startsWith(KRADConstants.MULTIPLE_VALUE_LOOKUP_SELECTED_OBJ_ID_PARAM_PREFIX) && StringUtils.isNotBlank(request.getParameter(paramName))) {
166                set.add(StringUtils.substringAfter(paramName, KRADConstants.MULTIPLE_VALUE_LOOKUP_SELECTED_OBJ_ID_PARAM_PREFIX));
167            }
168        }
169        return set;
170    }
171    
172    protected Set<String> parseDisplayedObjectIdSet(HttpServletRequest request) {
173        Set<String> set = new HashSet<String>();
174        
175        Enumeration paramNames = request.getParameterNames();
176        while (paramNames.hasMoreElements()) {
177            String paramName = (String) paramNames.nextElement();
178            if (paramName.startsWith(KRADConstants.MULTIPLE_VALUE_LOOKUP_DISPLAYED_OBJ_ID_PARAM_PREFIX) && StringUtils.isNotBlank(request.getParameter(paramName))) {
179                set.add(StringUtils.substringAfter(paramName, KRADConstants.MULTIPLE_VALUE_LOOKUP_DISPLAYED_OBJ_ID_PARAM_PREFIX));
180            }
181        }
182        return set;
183    }
184    
185    /**
186     * Iterates through the request params, looks for the parameter representing the method to call in the format like
187     * methodToCall.sort.1.(::;true;::).x, and returns the boolean value in the (::; and ;::) delimiters.
188     * 
189     * @see MultipleValueLookupForm#parseSearchUsingOnlyPrimaryKeyValues(String)
190     * 
191     * @param request
192     * @return
193     */
194    protected boolean parseSearchUsingOnlyPrimaryKeyValues(HttpServletRequest request) {
195        // the param we're looking for looks like: methodToCall.sort.1.(::;true;::).x , we want to parse out the "true" component
196        String paramPrefix = KRADConstants.DISPATCH_REQUEST_PARAMETER + "." + getMethodToCall() + ".";
197        for (Enumeration i = request.getParameterNames(); i.hasMoreElements();) {
198            String parameterName = (String) i.nextElement();
199            if (parameterName.startsWith(paramPrefix) && parameterName.endsWith(".x")) {
200                return parseSearchUsingOnlyPrimaryKeyValues(parameterName);
201            }
202        }
203        // maybe doing an initial search, so no value will be present 
204        return false;
205    }
206    
207    /**
208     * Parses the method to call parameter passed in as a post parameter
209     * 
210     * The parameter should be something like methodToCall.sort.1.(::;true;::).x, this method will return the value
211     * between (::; and ;::) as a boolean
212     * 
213     * @param methodToCallParam the method to call in a format described above
214     * @return the value between the delimiters, false if there are no delimiters
215     */
216    protected boolean parseSearchUsingOnlyPrimaryKeyValues(String methodToCallParam) {
217        String searchUsingOnlyPrimaryKeyValuesStr = StringUtils.substringBetween(methodToCallParam, KRADConstants.METHOD_TO_CALL_PARM12_LEFT_DEL, KRADConstants.METHOD_TO_CALL_PARM12_RIGHT_DEL);
218        if (StringUtils.isBlank(searchUsingOnlyPrimaryKeyValuesStr)) {
219            return false;
220        }
221        return Boolean.parseBoolean(searchUsingOnlyPrimaryKeyValuesStr);
222    }
223    
224    public int getViewedPageNumber() {
225        return tableMetadata.getViewedPageNumber();
226    }
227
228    public void setViewedPageNumber(int pageNumberBeingViewedForMultivalueLookups) {
229        tableMetadata.setViewedPageNumber(pageNumberBeingViewedForMultivalueLookups);
230    }
231
232    public String getLookupResultsSequenceNumber() {
233        return lookupResultsSequenceNumber;
234    }
235
236    public void setLookupResultsSequenceNumber(String lookupResultSequenceNumber) {
237        this.lookupResultsSequenceNumber = lookupResultSequenceNumber;
238    }
239    
240    public int getTotalNumberOfPages() {
241        return tableMetadata.getTotalNumberOfPages();
242    }
243
244    public void setTotalNumberOfPages(int totalNumberOfPages) {
245        tableMetadata.setTotalNumberOfPages(totalNumberOfPages);
246    }
247
248    public int getFirstRowIndex() {
249        return tableMetadata.getFirstRowIndex();
250    }
251
252    public void setFirstRowIndex(int firstRowIndex) {
253        tableMetadata.setFirstRowIndex(firstRowIndex);
254    }
255
256    public int getLastRowIndex() {
257        return tableMetadata.getLastRowIndex();
258    }
259
260    public void setLastRowIndex(int lastRowIndex) {
261        tableMetadata.setLastRowIndex(lastRowIndex);
262    }
263
264    public int getSwitchToPageNumber() {
265        return tableMetadata.getSwitchToPageNumber();
266    }
267
268    protected void setSwitchToPageNumber(int switchToPageNumber) {
269        tableMetadata.setSwitchToPageNumber(switchToPageNumber);
270    }
271
272    public Set<String> getPreviouslySelectedObjectIdSet() {
273        return previouslySelectedObjectIdSet;
274    }
275
276    public void setPreviouslySelectedObjectIdSet(Set<String> previouslySelectedObjectIds) {
277        this.previouslySelectedObjectIdSet = previouslySelectedObjectIds;
278    }
279
280    public Set<String> getSelectedObjectIdSet() {
281        return selectedObjectIdSet;
282    }
283
284    public void setSelectedObjectIdSet(Set<String> selectedObjectIdSet) {
285        this.selectedObjectIdSet = selectedObjectIdSet;
286    }
287
288    public Set<String> getDisplayedObjectIdSet() {
289        return displayedObjectIdSet;
290    }
291
292    public void setDisplayedObjectIdSet(Set<String> displayedObjectIdSet) {
293        this.displayedObjectIdSet = displayedObjectIdSet;
294    }
295
296    public Map<String, String> getCompositeObjectIdMap() {
297        return compositeObjectIdMap;
298    }
299
300    public void setCompositeObjectIdMap(Map<String, String> compositeObjectIdMap) {
301        this.compositeObjectIdMap = compositeObjectIdMap;
302    }
303
304    public int getColumnToSortIndex() {
305        return columnToSortIndex;
306    }
307
308    public void setColumnToSortIndex(int columnToSortIndex) {
309        this.columnToSortIndex = columnToSortIndex;
310    }
311
312    public String getPreviouslySortedColumnIndex() {
313        return previouslySortedColumnIndex;
314    }
315
316    public void setPreviouslySortedColumnIndex(String previouslySortedColumnIndex) {
317        this.previouslySortedColumnIndex = previouslySortedColumnIndex;
318    }
319
320    /**
321     * gets the name of the collection being looked up by the calling page.  This value will be returned unmodified to the 
322     * calling page (indicated by super.getBackLocation()), which should use it to determine in which collection the 
323     * selected results will be returned.
324     * 
325     * @return
326     */
327    public String getLookedUpCollectionName() {
328        return lookedUpCollectionName;
329    }
330
331    /**
332     * sets the name of the collection being looked up by the calling page.  This value will be returned unmodified to the 
333     * calling page (indicated by super.getBackLocation()), which should use it to determine in which collection the 
334     * selected results will be returned
335     * 
336     * @param lookedUpCollectionName
337     */
338    public void setLookedUpCollectionName(String lookedUpCollectionName) {
339        this.lookedUpCollectionName = lookedUpCollectionName;
340    }
341
342    public int getResultsActualSize() {
343        return resultsActualSize;
344    }
345
346    public void setResultsActualSize(int resultsActualSize) {
347        this.resultsActualSize = resultsActualSize;
348    }
349
350    public int getResultsLimitedSize() {
351        return resultsLimitedSize;
352    }
353
354    public void setResultsLimitedSize(int resultsLimitedSize) {
355        this.resultsLimitedSize = resultsLimitedSize;
356    }
357    
358    public void jumpToFirstPage(int listSize, int maxRowsPerPage) {
359        tableMetadata.jumpToFirstPage(listSize, maxRowsPerPage);
360    }
361    
362    public void jumpToLastPage(int listSize, int maxRowsPerPage) {
363        tableMetadata.jumpToLastPage(listSize, maxRowsPerPage);
364    }
365    
366    public void jumpToPage(int pageNumber, int listSize, int maxRowsPerPage) {
367        tableMetadata.jumpToPage(pageNumber, listSize, maxRowsPerPage);
368    }
369}