View Javadoc

1   /**
2    * Copyright 2005-2013 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.kns.web.struts.form;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.kns.lookup.HtmlData;
20  import org.kuali.rice.kns.lookup.LookupUtils;
21  import org.kuali.rice.kns.util.PagingBannerUtils;
22  import org.kuali.rice.krad.util.KRADConstants;
23  
24  import javax.servlet.http.HttpServletRequest;
25  import java.util.Enumeration;
26  import java.util.HashSet;
27  import java.util.Map;
28  import java.util.Set;
29  
30  /**
31   * Form to handle multiple value lookups 
32   * 
33   * @author Kuali Rice Team (rice.collab@kuali.org)
34   *
35   */
36  public class MultipleValueLookupForm extends LookupForm {
37      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(MultipleValueLookupForm.class);
38      
39      private KualiTableRenderFormMetadata tableMetadata;
40      
41      private String lookupResultsSequenceNumber;
42      
43      /**
44       * @see LookupForm#addRequiredNonEditableProperties()
45       */
46      @Override
47      public void addRequiredNonEditableProperties(){
48      	super.addRequiredNonEditableProperties();
49      	registerRequiredNonEditableProperty(KRADConstants.LOOKUP_RESULTS_SEQUENCE_NUMBER);
50      	registerRequiredNonEditableProperty(KRADConstants.LOOKED_UP_COLLECTION_NAME);
51      }
52      
53      /**
54       * The number of rows that match the query criteria
55       */
56      private int resultsActualSize;
57      
58      /**
59       * The number of rows that match the query criteria or
60       *  the max results limit size (if applicable), whichever is less
61       */
62      private int resultsLimitedSize;
63      
64      /**
65       * when the looked results screen was rendered, the index of the column that the results were sorted on.  -1 for unknown, index numbers
66       * starting at 0
67       */
68      private String previouslySortedColumnIndex;
69      
70      /**
71       * Comment for <code>columnToSortIndex</code>
72       */
73      private int columnToSortIndex;
74      
75      /**
76       * the name of the collection being looked up by the calling page.  This value will be returned unmodified to the 
77       * calling page (indicated by super.getBackLocation()), which should use it to determine in which collection the 
78       * selected results will be returned.
79       */
80      private String lookedUpCollectionName;
81      
82      /**
83       * Those object IDs that were selected before the current page is rendered 
84       */
85      private Set<String> previouslySelectedObjectIdSet;
86      /**
87       * Those object IDs that are rendered on the current page
88       */
89      private Set<String> displayedObjectIdSet;
90      /**
91       * Those object IDs that are selected/checked on the current page
92       */
93      private Set<String> selectedObjectIdSet;
94      /**
95       * 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
96       */
97      private Map<String, String> compositeObjectIdMap;
98      
99      public MultipleValueLookupForm() {
100         tableMetadata = new KualiTableRenderFormMetadata();
101         setHtmlDataType(HtmlData.INPUT_HTML_DATA_TYPE);
102     }
103     
104     @Override
105     public void populate(HttpServletRequest request) {
106         super.populate(request);
107         
108         if (StringUtils.isNotBlank(request.getParameter(KRADConstants.TableRenderConstants.VIEWED_PAGE_NUMBER))) {
109             setViewedPageNumber(Integer.parseInt(request.getParameter(KRADConstants.TableRenderConstants.VIEWED_PAGE_NUMBER)));
110         }
111         else {
112             setViewedPageNumber(0); // first page is page 0
113         }
114         
115         if (KRADConstants.TableRenderConstants.SWITCH_TO_PAGE_METHOD.equals(getMethodToCall())) {
116             final String paramPrefix = KRADConstants.DISPATCH_REQUEST_PARAMETER + "." + KRADConstants.TableRenderConstants.SWITCH_TO_PAGE_METHOD + ".";
117         	setSwitchToPageNumber(PagingBannerUtils.getNumbericalValueAfterPrefix(paramPrefix, request.getParameterNames()));
118             if (getSwitchToPageNumber() == -1) {
119                 throw new RuntimeException("Couldn't find page number");
120             }
121         }
122         
123         if (KRADConstants.TableRenderConstants.SORT_METHOD.equals(getMethodToCall())) {
124             final String paramPrefix = KRADConstants.DISPATCH_REQUEST_PARAMETER + "." + KRADConstants.TableRenderConstants.SORT_METHOD + ".";
125             setColumnToSortIndex(
126                     PagingBannerUtils.getNumbericalValueAfterPrefix(paramPrefix, request.getParameterNames()));
127             if (getColumnToSortIndex() == -1) {
128                 throw new RuntimeException("Couldn't find column to sort");
129             }
130         }
131         
132         setPreviouslySelectedObjectIdSet(parsePreviouslySelectedObjectIds(request));
133         setSelectedObjectIdSet(parseSelectedObjectIdSet(request));
134         setDisplayedObjectIdSet(parseDisplayedObjectIdSet(request));
135 
136         setSearchUsingOnlyPrimaryKeyValues(parseSearchUsingOnlyPrimaryKeyValues(request));
137         if (isSearchUsingOnlyPrimaryKeyValues()) {
138             setPrimaryKeyFieldLabels(getLookupable().getPrimaryKeyFieldLabels());
139         }
140     }
141     
142 
143     
144     /**
145      * This method converts the composite object IDs into a String
146      * @return
147      */
148     public String getCompositeSelectedObjectIds() {
149         return LookupUtils.convertSetOfObjectIdsToString(getCompositeObjectIdMap().keySet());
150     }
151 
152     protected Set<String> parsePreviouslySelectedObjectIds(HttpServletRequest request) {
153         String previouslySelectedObjectIds = request.getParameter(KRADConstants.MULTIPLE_VALUE_LOOKUP_PREVIOUSLY_SELECTED_OBJ_IDS_PARAM);
154         return LookupUtils.convertStringOfObjectIdsToSet(previouslySelectedObjectIds);
155     }
156     
157     protected Set<String> parseSelectedObjectIdSet(HttpServletRequest request) {
158         Set<String> set = new HashSet<String>();
159         
160         Enumeration paramNames = request.getParameterNames();
161         while (paramNames.hasMoreElements()) {
162             String paramName = (String) paramNames.nextElement();
163             if (paramName.startsWith(KRADConstants.MULTIPLE_VALUE_LOOKUP_SELECTED_OBJ_ID_PARAM_PREFIX) && StringUtils.isNotBlank(request.getParameter(paramName))) {
164                 set.add(StringUtils.substringAfter(paramName, KRADConstants.MULTIPLE_VALUE_LOOKUP_SELECTED_OBJ_ID_PARAM_PREFIX));
165             }
166         }
167         return set;
168     }
169     
170     protected Set<String> parseDisplayedObjectIdSet(HttpServletRequest request) {
171         Set<String> set = new HashSet<String>();
172         
173         Enumeration paramNames = request.getParameterNames();
174         while (paramNames.hasMoreElements()) {
175             String paramName = (String) paramNames.nextElement();
176             if (paramName.startsWith(KRADConstants.MULTIPLE_VALUE_LOOKUP_DISPLAYED_OBJ_ID_PARAM_PREFIX) && StringUtils.isNotBlank(request.getParameter(paramName))) {
177                 set.add(StringUtils.substringAfter(paramName, KRADConstants.MULTIPLE_VALUE_LOOKUP_DISPLAYED_OBJ_ID_PARAM_PREFIX));
178             }
179         }
180         return set;
181     }
182     
183     /**
184      * Iterates through the request params, looks for the parameter representing the method to call in the format like
185      * methodToCall.sort.1.(::;true;::).x, and returns the boolean value in the (::; and ;::) delimiters.
186      * 
187      * @see MultipleValueLookupForm#parseSearchUsingOnlyPrimaryKeyValues(String)
188      * 
189      * @param request
190      * @return
191      */
192     protected boolean parseSearchUsingOnlyPrimaryKeyValues(HttpServletRequest request) {
193         // the param we're looking for looks like: methodToCall.sort.1.(::;true;::).x , we want to parse out the "true" component
194         String paramPrefix = KRADConstants.DISPATCH_REQUEST_PARAMETER + "." + getMethodToCall() + ".";
195         for (Enumeration i = request.getParameterNames(); i.hasMoreElements();) {
196             String parameterName = (String) i.nextElement();
197             if (parameterName.startsWith(paramPrefix) && parameterName.endsWith(".x")) {
198                 return parseSearchUsingOnlyPrimaryKeyValues(parameterName);
199             }
200         }
201         // maybe doing an initial search, so no value will be present 
202         return false;
203     }
204     
205     /**
206      * Parses the method to call parameter passed in as a post parameter
207      * 
208      * The parameter should be something like methodToCall.sort.1.(::;true;::).x, this method will return the value
209      * between (::; and ;::) as a boolean
210      * 
211      * @param methodToCallParam the method to call in a format described above
212      * @return the value between the delimiters, false if there are no delimiters
213      */
214     protected boolean parseSearchUsingOnlyPrimaryKeyValues(String methodToCallParam) {
215         String searchUsingOnlyPrimaryKeyValuesStr = StringUtils.substringBetween(methodToCallParam, KRADConstants.METHOD_TO_CALL_PARM12_LEFT_DEL, KRADConstants.METHOD_TO_CALL_PARM12_RIGHT_DEL);
216         if (StringUtils.isBlank(searchUsingOnlyPrimaryKeyValuesStr)) {
217             return false;
218         }
219         return Boolean.parseBoolean(searchUsingOnlyPrimaryKeyValuesStr);
220     }
221     
222     public int getViewedPageNumber() {
223         return tableMetadata.getViewedPageNumber();
224     }
225 
226     public void setViewedPageNumber(int pageNumberBeingViewedForMultivalueLookups) {
227         tableMetadata.setViewedPageNumber(pageNumberBeingViewedForMultivalueLookups);
228     }
229 
230     public String getLookupResultsSequenceNumber() {
231         return lookupResultsSequenceNumber;
232     }
233 
234     public void setLookupResultsSequenceNumber(String lookupResultSequenceNumber) {
235         this.lookupResultsSequenceNumber = lookupResultSequenceNumber;
236     }
237     
238     public int getTotalNumberOfPages() {
239         return tableMetadata.getTotalNumberOfPages();
240     }
241 
242     public void setTotalNumberOfPages(int totalNumberOfPages) {
243         tableMetadata.setTotalNumberOfPages(totalNumberOfPages);
244     }
245 
246     public int getFirstRowIndex() {
247         return tableMetadata.getFirstRowIndex();
248     }
249 
250     public void setFirstRowIndex(int firstRowIndex) {
251         tableMetadata.setFirstRowIndex(firstRowIndex);
252     }
253 
254     public int getLastRowIndex() {
255         return tableMetadata.getLastRowIndex();
256     }
257 
258     public void setLastRowIndex(int lastRowIndex) {
259         tableMetadata.setLastRowIndex(lastRowIndex);
260     }
261 
262     public int getSwitchToPageNumber() {
263         return tableMetadata.getSwitchToPageNumber();
264     }
265 
266     protected void setSwitchToPageNumber(int switchToPageNumber) {
267         tableMetadata.setSwitchToPageNumber(switchToPageNumber);
268     }
269 
270     public Set<String> getPreviouslySelectedObjectIdSet() {
271         return previouslySelectedObjectIdSet;
272     }
273 
274     public void setPreviouslySelectedObjectIdSet(Set<String> previouslySelectedObjectIds) {
275         this.previouslySelectedObjectIdSet = previouslySelectedObjectIds;
276     }
277 
278     public Set<String> getSelectedObjectIdSet() {
279         return selectedObjectIdSet;
280     }
281 
282     public void setSelectedObjectIdSet(Set<String> selectedObjectIdSet) {
283         this.selectedObjectIdSet = selectedObjectIdSet;
284     }
285 
286     public Set<String> getDisplayedObjectIdSet() {
287         return displayedObjectIdSet;
288     }
289 
290     public void setDisplayedObjectIdSet(Set<String> displayedObjectIdSet) {
291         this.displayedObjectIdSet = displayedObjectIdSet;
292     }
293 
294     public Map<String, String> getCompositeObjectIdMap() {
295         return compositeObjectIdMap;
296     }
297 
298     public void setCompositeObjectIdMap(Map<String, String> compositeObjectIdMap) {
299         this.compositeObjectIdMap = compositeObjectIdMap;
300     }
301 
302     public int getColumnToSortIndex() {
303         return columnToSortIndex;
304     }
305 
306     public void setColumnToSortIndex(int columnToSortIndex) {
307         this.columnToSortIndex = columnToSortIndex;
308     }
309 
310     public String getPreviouslySortedColumnIndex() {
311         return previouslySortedColumnIndex;
312     }
313 
314     public void setPreviouslySortedColumnIndex(String previouslySortedColumnIndex) {
315         this.previouslySortedColumnIndex = previouslySortedColumnIndex;
316     }
317 
318     /**
319      * gets the name of the collection being looked up by the calling page.  This value will be returned unmodified to the 
320      * calling page (indicated by super.getBackLocation()), which should use it to determine in which collection the 
321      * selected results will be returned.
322      * 
323      * @return
324      */
325     public String getLookedUpCollectionName() {
326         return lookedUpCollectionName;
327     }
328 
329     /**
330      * sets the name of the collection being looked up by the calling page.  This value will be returned unmodified to the 
331      * calling page (indicated by super.getBackLocation()), which should use it to determine in which collection the 
332      * selected results will be returned
333      * 
334      * @param lookedUpCollectionName
335      */
336     public void setLookedUpCollectionName(String lookedUpCollectionName) {
337         this.lookedUpCollectionName = lookedUpCollectionName;
338     }
339 
340     public int getResultsActualSize() {
341         return resultsActualSize;
342     }
343 
344     public void setResultsActualSize(int resultsActualSize) {
345         this.resultsActualSize = resultsActualSize;
346     }
347 
348     public int getResultsLimitedSize() {
349         return resultsLimitedSize;
350     }
351 
352     public void setResultsLimitedSize(int resultsLimitedSize) {
353         this.resultsLimitedSize = resultsLimitedSize;
354     }
355     
356     public void jumpToFirstPage(int listSize, int maxRowsPerPage) {
357         tableMetadata.jumpToFirstPage(listSize, maxRowsPerPage);
358     }
359     
360     public void jumpToLastPage(int listSize, int maxRowsPerPage) {
361         tableMetadata.jumpToLastPage(listSize, maxRowsPerPage);
362     }
363     
364     public void jumpToPage(int pageNumber, int listSize, int maxRowsPerPage) {
365         tableMetadata.jumpToPage(pageNumber, listSize, maxRowsPerPage);
366     }
367 }