1 /**
2 * Copyright 2005-2016 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.krad.lookup;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.kuali.rice.krad.uif.UifConstants.ViewType;
20 import org.kuali.rice.krad.util.KRADConstants;
21 import org.kuali.rice.krad.util.KRADUtils;
22 import org.kuali.rice.krad.web.bind.RequestAccessible;
23 import org.kuali.rice.krad.web.form.UifFormBase;
24 import org.springframework.http.HttpMethod;
25
26 import javax.servlet.http.HttpServletRequest;
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.HashMap;
30 import java.util.List;
31 import java.util.Map;
32
33 /**
34 * Form class containing backing data for {@link LookupView}.
35 *
36 * @author Kuali Rice Team (rice.collab@kuali.org)
37 */
38 public class LookupForm extends UifFormBase {
39 private static final long serialVersionUID = -7323484966538685327L;
40 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(LookupForm.class);
41
42 @RequestAccessible
43 private String dataObjectClassName;
44
45 @RequestAccessible
46 private boolean multipleValuesSelect;
47
48 @RequestAccessible
49 private boolean redirectedLookup;
50
51 @RequestAccessible
52 private boolean returnByScript;
53
54 @RequestAccessible
55 private String returnTarget;
56
57 @RequestAccessible
58 private String lookupCollectionName;
59
60 @RequestAccessible
61 private String lookupCollectionId;
62
63 @RequestAccessible
64 private String referencesToRefresh;
65
66 @RequestAccessible
67 private String quickfinderId;
68
69 @RequestAccessible
70 private Map<String, String> fieldConversions;
71 private List<String> multiValueReturnFields;
72
73 @RequestAccessible
74 private Map<String, String> lookupCriteria;
75
76 private Collection<?> lookupResults;
77
78 @RequestAccessible
79 private boolean displayResults;
80
81 public LookupForm() {
82 super();
83
84 setViewTypeName(ViewType.LOOKUP);
85
86 lookupCriteria = new HashMap<String, String>();
87 fieldConversions = new HashMap<String, String>();
88 multiValueReturnFields = new ArrayList<String>();
89 }
90
91 /**
92 * Picks out data object name from the request to retrieve a lookupable and for the initial get request
93 * populates the {@link #getFieldConversions()} property.
94 *
95 * {@inheritDoc}
96 */
97 @Override
98 public void postBind(HttpServletRequest request) {
99 super.postBind(request);
100
101 if (StringUtils.isBlank(getDataObjectClassName())) {
102 setDataObjectClassName(((LookupView) getView()).getDataObjectClass().getName());
103 }
104
105 Lookupable lookupable = getLookupable();
106 if (lookupable != null) {
107 Class<?> dataObjectClass;
108 try {
109 dataObjectClass = Class.forName(getDataObjectClassName());
110 } catch (ClassNotFoundException e) {
111 throw new RuntimeException("Object class " + getDataObjectClassName() + " not found", e);
112 }
113
114 lookupable.setDataObjectClass(dataObjectClass);
115 }
116
117 // populate field conversions map on initial GET request
118 if (request.getMethod().equals(HttpMethod.GET.name()) && (request.getParameter(
119 KRADConstants.CONVERSION_FIELDS_PARAMETER) != null)) {
120 String conversionFields = request.getParameter(KRADConstants.CONVERSION_FIELDS_PARAMETER);
121 setFieldConversions(KRADUtils.convertStringParameterToMap(conversionFields));
122 }
123 }
124
125 /**
126 * Returns an {@link Lookupable} instance associated with the lookup view.
127 *
128 * @return Lookupable instance or null if one does not exist
129 */
130 public Lookupable getLookupable() {
131 if (getViewHelperService() != null) {
132 return (Lookupable) getViewHelperService();
133 }
134
135 return null;
136 }
137
138 /**
139 * Class name for the data object the lookup should be performed against.
140 *
141 * <p>The object class name is used to pick up a dictionary entry which will feed the attribute field
142 * definitions and other configuration. In addition it is to configure the
143 * {@link org.kuali.rice.krad.lookup.Lookupable} which will carry out the search action</p>
144 *
145 * @return lookup data object class
146 */
147 public String getDataObjectClassName() {
148 return this.dataObjectClassName;
149 }
150
151 /**
152 * Setter for {@link LookupForm#getDataObjectClassName()}
153 *
154 * @param dataObjectClassName property value
155 */
156 public void setDataObjectClassName(String dataObjectClassName) {
157 this.dataObjectClassName = dataObjectClassName;
158 }
159
160 /**
161 * Indicates whether multiple values select should be enabled for the lookup.
162 *
163 * <p>When set to true, the select field is enabled for the lookup results group that allows the user
164 * to select one or more rows for returning</p>
165 *
166 * @return boolean true if multiple values should be enabled, false otherwise
167 */
168 public boolean isMultipleValuesSelect() {
169 return multipleValuesSelect;
170 }
171
172 /**
173 * @see LookupForm#isMultipleValuesSelect()
174 */
175 public void setMultipleValuesSelect(boolean multipleValuesSelect) {
176 this.multipleValuesSelect = multipleValuesSelect;
177 }
178
179 /**
180 * Indicates whether the requested was redirected from the lookup framework due to an external object
181 * request.
182 *
183 * <p>This prevents the framework from performing another redirect check</p>
184 *
185 * @return boolean true if request was a redirect, false if not
186 */
187 public boolean isRedirectedLookup() {
188 return redirectedLookup;
189 }
190
191 /**
192 * @see LookupForm#isRedirectedLookup()
193 */
194 public void setRedirectedLookup(boolean redirectedLookup) {
195 this.redirectedLookup = redirectedLookup;
196 }
197
198 /**
199 * Indicates whether the return value from the lookup should occur through script or a server side
200 * post (default is false, server side post).
201 *
202 * @return boolean true if return should occur though script, false if return should be done through server
203 * side post
204 */
205 public boolean isReturnByScript() {
206 return returnByScript;
207 }
208
209 /**
210 * @see LookupForm#isReturnByScript()
211 */
212 public void setReturnByScript(boolean returnByScript) {
213 this.returnByScript = returnByScript;
214 }
215
216 /**
217 * Name of the window the lookup should return to.
218 *
219 * <p>The lookup can be invoked from several different contexts: new tab, lightbox within top window, lightbox
220 * within portal window. When the request is made, this parameter can be sent to specify the target for
221 * the return links.</p>
222 *
223 * @return String return target window name
224 */
225 public String getReturnTarget() {
226 return returnTarget;
227 }
228
229 /**
230 * org.kuali.rice.krad.lookup.LookupForm#getReturnTarget()
231 */
232 public void setReturnTarget(String returnTarget) {
233 this.returnTarget = returnTarget;
234 }
235
236 /**
237 * For the case of multi-value lookup, indicates the collection that should be populated with
238 * the return results.
239 *
240 * @return String collection name (must be full binding path)
241 */
242 public String getLookupCollectionName() {
243 return lookupCollectionName;
244 }
245
246 /**
247 * @see LookupForm#getLookupCollectionName()
248 */
249 public void setLookupCollectionName(String lookupCollectionName) {
250 this.lookupCollectionName = lookupCollectionName;
251 }
252
253 public String getLookupCollectionId() {
254 return lookupCollectionId;
255 }
256
257 public void setLookupCollectionId(String lookupCollectionId) {
258 this.lookupCollectionId = lookupCollectionId;
259 }
260
261 /**
262 * String containing references that should be refreshed when the lookup returns, passed back on the
263 * return URL.
264 *
265 * @return String containing references that should be refreshed on return from lookup
266 */
267 public String getReferencesToRefresh() {
268 return referencesToRefresh;
269 }
270
271 /**
272 * @see LookupForm#getReferencesToRefresh()
273 */
274 public void setReferencesToRefresh(String referencesToRefresh) {
275 this.referencesToRefresh = referencesToRefresh;
276 }
277
278 /**
279 * Id for the quickfinder that triggered the lookup action (if any).
280 *
281 * <p>When the lookup is triggered from a quickfinder, the return URLs will be present on the lookup
282 * results. In addition, the quickfinder id is passed back on the return URL so the caller can perform logic
283 * based on which quickfinder was invoked.</p>
284 *
285 * @return String id for quickfinder that invoked the lookup
286 */
287 public String getQuickfinderId() {
288 return quickfinderId;
289 }
290
291 /**
292 * @see LookupForm#getQuickfinderId()
293 */
294 public void setQuickfinderId(String quickfinderId) {
295 this.quickfinderId = quickfinderId;
296 }
297
298 /**
299 * Map of conversions that should occur on the lookup return between properties on the lookup data object
300 * and properties on the calling view.
301 *
302 * <p>When a lookup is invoked from a calling view, the purpose is to return one or more values that will
303 * populate fields on the calling view. To accomplish this, values for properties on the selected record
304 * are passed back on the URL as values for properties on the calling view. This map specifies which properties
305 * on the lookup data object should be pulled, and for each one what is the property on the caller to
306 * send the value back as.</p>
307 *
308 * <p>For example, suppose the map contained the entries id:document.bookId and title:document.bookTitle. When the
309 * return URL is selected for a record, the value for the id property will be retrieved and added to the return
310 * URL query string as 'document.bookId={idValue}'. Likewise the value for the title property will be pulled
311 * and added to the return URL query string as 'document.bookTitle={titleValue}'. So the query string will contain
312 * something like 'document.bookId=3&document.bookTitle=Animals'</p>
313 *
314 * @return Map of field conversions, each entry is a conversion between two properties. Key is property name
315 * on the lookup data object, entry value is the property name on the calling view/model
316 */
317 public Map<String, String> getFieldConversions() {
318 return this.fieldConversions;
319 }
320
321 /**
322 * @see LookupForm#getFieldConversions()
323 */
324 public void setFieldConversions(Map<String, String> fieldConversions) {
325 this.fieldConversions = fieldConversions;
326 }
327
328 /**
329 * Holds the column names for the multi-value lookup selected values
330 *
331 * Note: as of KULRICE-12125 secure field names will not be stored in this parameter
332 * @return a list of column names for the multi-value lookup
333 */
334 public List<String> getMultiValueReturnFields() {
335 return multiValueReturnFields;
336 }
337
338 /**
339 * @see LookupForm#getMultiValueReturnFields()
340 */
341 public void setMultiValueReturnFields(List<String> multiValueReturnFields) {
342 this.multiValueReturnFields = multiValueReturnFields;
343 }
344
345 /**
346 * Map containing the criteria to be used for performing the search.
347 *
348 * <p>Fields that are defined in the {@link org.kuali.rice.krad.lookup.LookupView#getCriteriaGroup()} bind
349 * to this map. The key of the map is the property path specified for the field, and the value of the map
350 * is the search value (if any) entered by the user. This map is then passed into the {@link Lookupable} to
351 * carry out the search.</p>
352 *
353 * @return Map of search criteria where key is the property the criteria will be applied to and the value is
354 * the search value entered by the user (if any)
355 */
356 public Map<String, String> getLookupCriteria() {
357 return this.lookupCriteria;
358 }
359
360 /**
361 * @see LookupForm#getLookupCriteria()
362 */
363 public void setLookupCriteria(Map<String, String> lookupCriteria) {
364 this.lookupCriteria = lookupCriteria;
365 }
366
367 /**
368 * Holds the results of a search action.
369 *
370 * <p>After the search action is invoked, the results of the search will be held by this property. The
371 * {@link org.kuali.rice.krad.lookup.LookupView#getResultsGroup()} binds to this property for displaying
372 * the results.</p>
373 *
374 * @return Collection of data objects that are the result of a search
375 */
376 public Collection<?> getLookupResults() {
377 return this.lookupResults;
378 }
379
380 /**
381 * @see LookupForm#getLookupResults()
382 */
383 public void setLookupResults(Collection<?> lookupResults) {
384 this.lookupResults = lookupResults;
385 }
386
387 public boolean isDisplayResults() {
388 return displayResults;
389 }
390
391 public void setDisplayResults(boolean displayResults) {
392 this.displayResults = displayResults;
393 }
394 }