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.krad.lookup; 017 018import org.apache.commons.lang.StringUtils; 019import org.kuali.rice.krad.uif.UifConstants.ViewType; 020import org.kuali.rice.krad.util.KRADConstants; 021import org.kuali.rice.krad.util.KRADUtils; 022import org.kuali.rice.krad.web.bind.RequestAccessible; 023import org.kuali.rice.krad.web.form.UifFormBase; 024import org.springframework.http.HttpMethod; 025 026import javax.servlet.http.HttpServletRequest; 027import java.util.ArrayList; 028import java.util.Collection; 029import java.util.HashMap; 030import java.util.List; 031import java.util.Map; 032 033/** 034 * Form class containing backing data for {@link LookupView}. 035 * 036 * @author Kuali Rice Team (rice.collab@kuali.org) 037 */ 038public class LookupForm extends UifFormBase { 039 private static final long serialVersionUID = -7323484966538685327L; 040 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(LookupForm.class); 041 042 @RequestAccessible 043 private String dataObjectClassName; 044 045 @RequestAccessible 046 private boolean multipleValuesSelect; 047 048 @RequestAccessible 049 private boolean redirectedLookup; 050 051 @RequestAccessible 052 private boolean returnByScript; 053 054 @RequestAccessible 055 private String returnTarget; 056 057 @RequestAccessible 058 private String lookupCollectionName; 059 060 @RequestAccessible 061 private String lookupCollectionId; 062 063 @RequestAccessible 064 private String referencesToRefresh; 065 066 @RequestAccessible 067 private String quickfinderId; 068 069 @RequestAccessible 070 private Map<String, String> fieldConversions; 071 private List<String> multiValueReturnFields; 072 073 @RequestAccessible 074 private Map<String, String> lookupCriteria; 075 076 private Collection<?> lookupResults; 077 078 @RequestAccessible 079 private boolean displayResults; 080 081 public LookupForm() { 082 super(); 083 084 setViewTypeName(ViewType.LOOKUP); 085 086 lookupCriteria = new HashMap<String, String>(); 087 fieldConversions = new HashMap<String, String>(); 088 multiValueReturnFields = new ArrayList<String>(); 089 } 090 091 /** 092 * Picks out data object name from the request to retrieve a lookupable and for the initial get request 093 * populates the {@link #getFieldConversions()} property. 094 * 095 * {@inheritDoc} 096 */ 097 @Override 098 public void postBind(HttpServletRequest request) { 099 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}