Coverage Report - org.kuali.rice.kns.web.struts.form.pojo.PojoFormBase
 
Classes in this File Line Coverage Branch Coverage Complexity
PojoFormBase
0%
0/190
0%
0/64
2.068
 
 1  
 /**
 2  
  * Copyright 2005-2011 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  
 // begin Kuali Foundation modification
 17  
 package org.kuali.rice.kns.web.struts.form.pojo;
 18  
 
 19  
 import org.apache.commons.beanutils.PropertyUtils;
 20  
 import org.apache.commons.lang.StringUtils;
 21  
 import org.apache.commons.lang.time.StopWatch;
 22  
 import org.apache.log4j.Logger;
 23  
 import org.apache.struts.action.ActionForm;
 24  
 import org.kuali.rice.core.framework.services.CoreFrameworkServiceLocator;
 25  
 import org.kuali.rice.core.web.format.FormatException;
 26  
 import org.kuali.rice.core.web.format.Formatter;
 27  
 import org.kuali.rice.kns.util.WebUtils;
 28  
 import org.kuali.rice.kns.web.EditablePropertiesHistoryHolder;
 29  
 import org.kuali.rice.krad.exception.ValidationException;
 30  
 import org.kuali.rice.krad.util.GlobalVariables;
 31  
 import org.kuali.rice.krad.util.KRADConstants;
 32  
 import org.kuali.rice.krad.util.ObjectUtils;
 33  
 
 34  
 import javax.servlet.http.HttpServletRequest;
 35  
 import java.lang.reflect.InvocationTargetException;
 36  
 import java.util.ArrayList;
 37  
 import java.util.Collections;
 38  
 import java.util.Enumeration;
 39  
 import java.util.HashMap;
 40  
 import java.util.HashSet;
 41  
 import java.util.Iterator;
 42  
 import java.util.List;
 43  
 import java.util.Map;
 44  
 import java.util.Set;
 45  
 
 46  
 /**
 47  
  * This class is the base form which implements the PojoForm interface.
 48  
  * Kuali Foundation modification: javadoc comments changed
 49  
  */
 50  
 // begin Kuali Foundation modification: this class was named SLActionForm
 51  0
 public class PojoFormBase extends ActionForm implements PojoForm {
 52  
     private static final long serialVersionUID = 1L;
 53  
     
 54  
     // begin Kuali Foundation modification
 55  0
     private static final Logger LOG = Logger.getLogger(PojoFormBase.class);
 56  
     
 57  
     private static final String PREVIOUS_REQUEST_EDITABLE_PROPERTIES_GUID = "editablePropertiesGuid";
 58  
 
 59  
         // removed member variables: cachedActionErrors, coder, errorInfo, fieldOrder, formConfig, HEADING_KEY, IGNORED_KEYS,
 60  
         //     invalidValueKeys, logger, messageResourceKey, messageResources, padNonRequiredFields, valueBinder
 61  
          
 62  
     static final String CREATE_ERR_MSG = "Can't create formatter for keypath ";
 63  
     static final String CONVERT_ERR_MSG = "Can't convert value for keypath: ";
 64  
 
 65  0
     static Map classCache = Collections.synchronizedMap(new HashMap());
 66  
 
 67  0
     private Map unconvertedValues = new HashMap();
 68  0
     private List unknownKeys = new ArrayList();
 69  0
     private Map formatterTypes = new HashMap();
 70  0
     private List<String> maxUploadFileSizes = new ArrayList<String>();
 71  0
     private Set<String> editableProperties = new HashSet<String>();
 72  0
     protected Set<String> requiredNonEditableProperties = new HashSet<String>();
 73  
     private String strutsActionMappingScope; 
 74  0
     private boolean isNewForm = true;
 75  
     
 76  
     private String populateEditablePropertiesGuid;
 77  
     private String actionEditablePropertiesGuid;
 78  
 
 79  
     // removed methods: PojoFormBase()/SLActionForm(), addFormLevelMessageInfo, addGlobalMessage, addIgnoredKey, addIgnoredKeys, addLengthValidation, addMessageIfAbsent
 80  
     //     addPatternValidation, addPropertyValidationRules, addRangeValidation, addRequiredField, addRequiredFields
 81  
     //     addUnknownKey, addValidationRule(String, ValidationRule), addValidationRule(ValidationRule), cachedActionErrors, clearIgnoredKeys,
 82  
     //     clearUnknownKeys, clearValidationErrors, coalesceMessageArgs, containsKey, convertValue, createActionMessage, createMessageResourcesIfNecessary, fieldOrder, fieldValidationRuleOrder,
 83  
     //     formatMessage, formatMessageArgs, formatterSettingsForKeypath, formatterTypeForKeypath, formBeanConfigForKey, formConfig, formValidationRuleOrder,
 84  
     //     generateErrorMessages, getActionErrors, getActionMessages, getErrorMessages, getFieldLabel, getFormatterTypes, getGlobalMessages, getIgnoredKeys, getInvalidValueKeys, getLabels, getLengthValidations, getLocale,
 85  
     //     getMultipartRequestParameters, getPadNonRequiredFields, 
 86  
     //     getPatternValidations, getPropertyConfig, getRangeValidations, getRequiredFields, hasErrorMessageForKey, hasErrors, hasFormatterForKeypath,
 87  
     //     hasGlobalMessageForKey, isMultipart, messageForKey, messageForRule, messageInfoForRule, messageResourcesConfigForKey, messageResourcesKey, messageResourcesPath,
 88  
     //     messagesForFormLevelRule, messagesForKey, moduleConfigForRequest, removeIgnoredKey, removePropertyConfig,
 89  
     //     renderErrorMessages, renderGlobalMessages, renderMessages, setFieldLabel, setFieldOrder, setFormatterType(String, Class, Map)
 90  
     //     setFormConfig, setInvalidValueKeys, setLengthValidations, setMessageResourceKey,setPadNonRequiredFields, setPatternValidations, setPropertyConfig, setRangeValidations,
 91  
     //     setRequiredFields, setValueBinder, shouldFormat, validate, validateForm, validateLength, validatePattern, validateProperty, validateRange, validateRequestValues, validateRequired, valueBinder
 92  
 
 93  
         // end Kuali Foundation modification
 94  
         
 95  
 
 96  
         // begin Kuali Foundation modification
 97  
     /**
 98  
      * Method is called after parameters from a multipart request have been made accessible to request.getParameter calls, but
 99  
      * before request parameter values are used to instantiate and populate business objects. Important note: parameters in the
 100  
      * given Map which were created from a multipart-encoded parameter will, apparently, be stored in the given Map as String[]
 101  
      * instead of as String.
 102  
      *
 103  
      * @param requestParameters
 104  
      */
 105  
 
 106  
     @Override
 107  
         public void postprocessRequestParameters(Map requestParameters) {
 108  
         // do nothing
 109  0
     }
 110  
     // end Kuali Foundation modification
 111  
 
 112  
  
 113  
 
 114  
     /**
 115  
      * Populates the form with values from the current request. Uses instances of Formatter to convert strings to the Java types of
 116  
      * the properties to which they are bound. Values that can't be converted are cached in a map of unconverted values. Returns an
 117  
      * ActionErrors containing ActionMessage instances for each conversion error that occured, if any.
 118  
      */
 119  
     @Override
 120  
         public void populate(HttpServletRequest request) {
 121  0
         String watchName = "PojoFormBase.populate";
 122  0
         StopWatch watch = new StopWatch();
 123  0
         watch.start();
 124  0
         if (LOG.isDebugEnabled()) {
 125  0
             LOG.debug(watchName + ": started");
 126  
         }
 127  0
         unconvertedValues.clear();
 128  0
         unknownKeys = new ArrayList();
 129  0
         addRequiredNonEditableProperties();
 130  0
         Map params = request.getParameterMap();
 131  
 
 132  0
         String contentType = request.getContentType();
 133  0
         String method = request.getMethod();
 134  
 
 135  0
         if ("POST".equalsIgnoreCase(method) && contentType != null && contentType.startsWith("multipart/form-data")) {
 136  0
             Map fileElements = (HashMap)request.getAttribute(KRADConstants.UPLOADED_FILE_REQUEST_ATTRIBUTE_KEY);
 137  0
             Enumeration names = Collections.enumeration(fileElements.keySet());
 138  0
             while (names.hasMoreElements()) {
 139  0
                 String name = (String) names.nextElement();
 140  0
                 params.put(name, fileElements.get(name));
 141  0
             }
 142  
         }
 143  
 
 144  0
         postprocessRequestParameters(params);
 145  
 
 146  
 
 147  
         /**
 148  
          * Iterate through request parameters, if parameter matches a form variable, get the property type, formatter and convert,
 149  
          * if not add to the unknowKeys map.
 150  
          */
 151  0
         for (Iterator iter = params.keySet().iterator(); iter.hasNext();) {
 152  0
             String keypath = (String) iter.next();
 153  0
             if (shouldPropertyBePopulatedInForm(keypath, request)) {
 154  0
                     Object param = params.get(keypath);
 155  
                     //LOG.debug("(keypath,paramType)=(" + keypath + "," + param.getClass().getName() + ")");
 156  
         
 157  0
                     populateForProperty(keypath, param, params);
 158  
             }
 159  0
         }
 160  0
         this.registerIsNewForm(false);
 161  0
         watch.stop();
 162  0
         if (LOG.isDebugEnabled()) {
 163  0
             LOG.debug(watchName + ": " + watch.toString());        
 164  
         }
 165  0
     }
 166  
 
 167  
 
 168  
 
 169  
         /**
 170  
          * Populates a given parameter value into the given property path
 171  
          * @param paramPath the path to a property within the form
 172  
          * @param paramValue the value of that property
 173  
          * @param params the Map of parameters from the request
 174  
          */
 175  
         protected void populateForProperty(String paramPath, Object paramValue,
 176  
                         Map params) {
 177  
                 // get type for property
 178  0
                 Class type = null;
 179  
                 try {
 180  
                     // TODO: see KULOWF-194
 181  
                     //testForPojoHack(this, keypath);
 182  0
                     type = getPropertyType(paramPath);
 183  
                 }
 184  0
                 catch (Exception e) {
 185  
                     // deleted redundant unknownKeys.add(keypath)
 186  0
                 }
 187  
 
 188  
                 // keypath does not match anything on form
 189  0
                 if (type == null) {
 190  0
                     unknownKeys.add(paramPath);
 191  
                 }
 192  
                 else {
 193  0
                     Formatter formatter = null;
 194  
                     try {
 195  0
                         formatter = buildFormatter(paramPath, type, params);
 196  
 
 197  0
                         ObjectUtils.setObjectProperty(formatter, this, paramPath, type, paramValue);
 198  
                             }
 199  0
                     catch (FormatException e1) {
 200  0
                         GlobalVariables.getMessageMap().putError(paramPath, e1.getErrorKey(), e1.getErrorArgs());
 201  0
                         cacheUnconvertedValue(paramPath, paramValue);
 202  
                     }
 203  0
                     catch (InvocationTargetException e1) {
 204  0
                         if (e1.getTargetException().getClass().equals(FormatException.class)) {
 205  
                             // Handle occasional case where FormatException is wrapped in an InvocationTargetException
 206  0
                             FormatException formatException = (FormatException) e1.getTargetException();
 207  0
                             GlobalVariables.getMessageMap().putError(paramPath, formatException.getErrorKey(), formatException.getErrorArgs());
 208  0
                             cacheUnconvertedValue(paramPath, paramValue);
 209  0
                         }
 210  
                         else {
 211  0
                             LOG.error("Error occurred in populate " + e1.getMessage());
 212  0
                             throw new RuntimeException(e1.getMessage(), e1);
 213  
                         }
 214  
                     }
 215  0
                     catch (Exception e1) {
 216  0
                         LOG.error("Error occurred in populate " + e1.getMessage());
 217  0
                             LOG.error("FormClass:       " + this.getClass().getName() );
 218  0
                             LOG.error("keypath:         " + paramPath );
 219  0
                             LOG.error("Detected Type:   " + type.getName() );
 220  0
                             LOG.error( "Value:          " + paramValue );
 221  0
                             if ( paramValue != null ) {
 222  0
                                         LOG.error( "Value Class:    " + paramValue.getClass().getName() );
 223  
                             }
 224  0
                         throw new RuntimeException(e1.getMessage(), e1);
 225  0
                     }
 226  
                 }
 227  0
         }
 228  
 
 229  
         // begin Kuali Foundation modification
 230  
     private Formatter buildFormatter(String keypath, Class propertyType, Map requestParams) {
 231  0
         Formatter formatter = buildFormatterForKeypath(keypath, propertyType, requestParams);
 232  0
         if (formatter == null) {
 233  0
             formatter = buildFormatterForType(propertyType);
 234  
         }
 235  0
         return formatter;
 236  
     }
 237  
     // end Kuali Foundation modification
 238  
 
 239  
         // begin Kuali Foundation modification
 240  
     private Formatter buildFormatterForKeypath(String keypath, Class propertyType, Map requestParams) {
 241  0
         Formatter formatter = null;
 242  
 
 243  0
         Class formatterClass = formatterClassForKeypath(keypath);
 244  
 
 245  0
         if (formatterClass != null) {
 246  
             try {
 247  0
                 formatter = (Formatter) formatterClass.newInstance();
 248  
             }
 249  0
             catch (InstantiationException e) {
 250  0
                 throw new FormatException("unable to instantiate formatter class '" + formatterClass.getName() + "'", e);
 251  
             }
 252  0
             catch (IllegalAccessException e) {
 253  0
                 throw new FormatException("unable to access formatter class '" + formatterClass.getName() + "'", e);
 254  0
             }
 255  0
             formatter.setPropertyType(propertyType);
 256  
         }
 257  0
         return formatter;
 258  
     }
 259  
     // end Kuali Foundation modification
 260  
 
 261  
         // begin Kuali Foundation modification
 262  
     private Formatter buildFormatterForType(Class propertyType) {
 263  0
         Formatter formatter = null;
 264  
 
 265  0
         if (Formatter.findFormatter(propertyType) != null) {
 266  0
             formatter = Formatter.getFormatter(propertyType);
 267  
         }
 268  0
         return formatter;
 269  
     }
 270  
     // end Kuali Foundation modification
 271  
 
 272  
         /**
 273  
      * Delegates to {@link PropertyUtils#getPropertyType(Object, String)}to look up the property type for the provided keypath.
 274  
      * Caches the resulting class so that subsequent lookups for the same keypath can be satisfied by looking in the cache.
 275  
      *
 276  
      * @throws NoSuchMethodException
 277  
      * @throws InvocationTargetException
 278  
      * @throws IllegalAccessException
 279  
      */
 280  
     protected Class getPropertyType(String keypath) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
 281  0
         Map propertyTypes = (Map) classCache.get(getClass());
 282  0
         if (propertyTypes == null) {
 283  0
             propertyTypes = new HashMap();
 284  0
             classCache.put(getClass(), propertyTypes);
 285  
         }
 286  
 
 287  
         // if type has not been retrieve previousely, use ObjectUtils to get type
 288  0
         if (!propertyTypes.containsKey(keypath)) {
 289  0
             Class type = ObjectUtils.easyGetPropertyType(this, keypath);
 290  0
             propertyTypes.put(keypath, type);
 291  
         }
 292  
 
 293  0
         Class propertyType = (Class) propertyTypes.get(keypath);
 294  0
         return propertyType;
 295  
     }
 296  
 
 297  
 
 298  
     /**
 299  
      * Retrieves a formatter for the keypath and property type.
 300  
      *
 301  
      * @param keypath
 302  
      * @param propertyType
 303  
      * @return
 304  
      */
 305  
     protected Formatter getFormatter(String keypath, Class propertyType) {
 306  
         // check for a formatter associated with the keypath
 307  0
         Class type = formatterClassForKeypath(keypath);
 308  
 
 309  
         Formatter formatter;
 310  0
         if (type == null) {
 311  
             // retrieve formatter based on property type
 312  0
             formatter = Formatter.getFormatter(propertyType);
 313  
         }
 314  
         else {
 315  
             try {
 316  0
                 formatter = (Formatter) type.newInstance();
 317  0
                 formatter.setPropertyType(propertyType);
 318  
             }
 319  0
             catch (Exception e) {
 320  0
                 throw new ValidationException(CREATE_ERR_MSG, e);
 321  0
             }
 322  
         }
 323  0
         return formatter;
 324  
     }
 325  
 
 326  
 
 327  
         // begin Kuali Foundation modification
 328  
     /**
 329  
      * Retrieves any formatters associated specially with the keypath.
 330  
      *
 331  
      * @param keypath
 332  
      * @return
 333  
      */
 334  
     protected Class formatterClassForKeypath(String keypath) {
 335  
         // remove traces of array and map indices from the incoming keypath
 336  0
         String indexlessKey = keypath.replaceAll("(\\[[0-9]*+\\]|\\(.*?\\))", "");
 337  
 
 338  0
         return (Class)formatterTypes.get( indexlessKey );
 339  
     }
 340  
     // end Kuali Foundation modification
 341  
 
 342  
     /**
 343  
      * Tries to format the provided value by passing it to a suitable {@link Formatter}. Adds an ActionMessage to the ActionErrors
 344  
      * in the request if a FormatException is thrown.
 345  
      * <p>
 346  
      * Caution should be used when invoking this method. It should never be called prior to {@link #populate(HttpServletRequest)}
 347  
      * because the cached request reference could be stale.
 348  
      */
 349  
     @Override
 350  
         public Object formatValue(Object value, String keypath, Class type) {
 351  
 
 352  0
         Formatter formatter = getFormatter(keypath, type);
 353  0
         if ( LOG.isDebugEnabled() ) {
 354  0
             LOG.debug("formatValue (value,keypath,type) = (" + value + "," + keypath + "," + type.getName() + ")");
 355  
         }
 356  
 
 357  
         try {
 358  0
             return Formatter.isSupportedType(type) ? formatter.formatForPresentation(value) : value;
 359  
         }
 360  0
         catch (FormatException e) {
 361  0
             GlobalVariables.getMessageMap().putError(keypath, e.getErrorKey(), e.getErrorArgs());
 362  0
             return value.toString();
 363  
         }
 364  
     }
 365  
 
 366  
     /**
 367  
      * Sets the Formatter class to use for a given keypath. This class will be used by the form instead of the one returned by calls
 368  
      * to {@link Formatter#getFormatter(Class)}, which is the default mechanism.
 369  
      */
 370  
     public void setFormatterType(String keypath, Class type) {
 371  0
         formatterTypes.put(keypath, type);
 372  0
     }
 373  
 
 374  
     @Override
 375  
         public Map getUnconvertedValues() {
 376  0
         return unconvertedValues;
 377  
     }
 378  
 
 379  
     public void setUnconvertedValues(Map unconvertedValues) {
 380  0
         this.unconvertedValues = unconvertedValues;
 381  0
     }
 382  
 
 383  
     protected List getUnknownKeys() {
 384  0
         return unknownKeys;
 385  
     }
 386  
 
 387  
     protected void cacheUnconvertedValue(String key, Object value) {
 388  0
         Class type = value.getClass();
 389  0
         if (type.isArray()) {
 390  0
             value = Formatter.isEmptyValue(value) ? null : ((Object[]) value)[0];
 391  
         }
 392  
 
 393  0
         unconvertedValues.put(key, value);
 394  0
     }
 395  
 
 396  
         // begin Kuali Foundation modification
 397  
     @Override
 398  
         public void processValidationFail() {
 399  
         // do nothing - subclasses can implement this if they want to.
 400  0
     }
 401  
     // end Kuali Foundation modification
 402  
 
 403  
 
 404  
         // begin Kuali Foundation modification
 405  
     /**
 406  
      * Gets the formatterTypes attribute.
 407  
      * 
 408  
      * @return Returns the formatterTypes.
 409  
      */
 410  
     public Map getFormatterTypes() {
 411  0
         return formatterTypes;
 412  
     }
 413  
     // end Kuali Foundation modification
 414  
 
 415  
 
 416  
         // begin Kuali Foundation modification
 417  
     /**
 418  
      * Sets the formatterTypes attribute value.
 419  
      * @param formatterTypes The formatterTypes to set.
 420  
      */
 421  
     public void setFormatterTypes(Map formatterTypes) {
 422  0
         this.formatterTypes = formatterTypes;
 423  0
     }
 424  
     // end Kuali Foundation modification
 425  
 
 426  
 
 427  
         // begin Kuali Foundation modification
 428  
     /**
 429  
      * Adds the given string as a maximum size to the form.  It will be used if a file upload is used.
 430  
      * 
 431  
      * @param sizeString
 432  
      */
 433  
     protected final void addMaxUploadSize( String sizeString ) {
 434  0
         maxUploadFileSizes.add( sizeString );
 435  0
     }
 436  
 
 437  
     /**
 438  
      * Initializes the list of max upload sizes if necessary. 
 439  
      *
 440  
      */
 441  
     protected final void initMaxUploadSizes() {
 442  0
             if ( maxUploadFileSizes.isEmpty() ) {
 443  0
                 customInitMaxUploadSizes();
 444  
                 // if it's still empty, add the default
 445  0
                 if ( maxUploadFileSizes.isEmpty() ) {
 446  0
                     addMaxUploadSize(CoreFrameworkServiceLocator.getParameterService().getParameterValueAsString(
 447  
                         KRADConstants.KRAD_NAMESPACE, KRADConstants.DetailTypes.ALL_DETAIL_TYPE, KRADConstants.MAX_UPLOAD_SIZE_PARM_NM));
 448  
                 }
 449  
             }        
 450  0
     }
 451  
     
 452  
     /**
 453  
      * Subclasses can override this to add their own max upload size to the list.  Only the largest passed will be used.
 454  
      *
 455  
      */
 456  
     protected void customInitMaxUploadSizes() {
 457  
         // nothing here
 458  0
     }
 459  
     
 460  
     public final List<String> getMaxUploadSizes() {
 461  0
         initMaxUploadSizes();
 462  
         
 463  0
         return maxUploadFileSizes;
 464  
     }
 465  
     
 466  
     @Override
 467  
         public void registerEditableProperty(String editablePropertyName){
 468  0
             if ( LOG.isDebugEnabled() ) {
 469  0
                     LOG.debug( "KualiSessionId: " + GlobalVariables.getUserSession().getKualiSessionId() + " -- Registering Property: " + editablePropertyName );
 470  
             }
 471  0
             editableProperties.add(editablePropertyName);
 472  0
     }
 473  
     
 474  
     public void registerRequiredNonEditableProperty(String requiredNonEditableProperty) {
 475  0
             requiredNonEditableProperties.add(requiredNonEditableProperty);
 476  0
     }
 477  
     
 478  
     @Override
 479  
         public void clearEditablePropertyInformation(){
 480  0
             if ( LOG.isDebugEnabled() ) {
 481  0
                     LOG.debug( "KualiSessionId: " + GlobalVariables.getUserSession().getKualiSessionId() + " -- Clearing Editable Properties" );
 482  
             }
 483  0
             editableProperties = new HashSet<String>();
 484  0
     }
 485  
     
 486  
     @Override
 487  
         public Set<String> getEditableProperties(){
 488  0
             return editableProperties;
 489  
     }
 490  
  
 491  
     public boolean isPropertyEditable(String propertyName) {
 492  0
             final Set<String> populateEditableProperties = getPopulateEditableProperties();
 493  0
         return WebUtils.isPropertyEditable(populateEditableProperties, propertyName);
 494  
     }
 495  
     
 496  
     /***
 497  
      * @see PojoForm#addRequiredNonEditableProperties()
 498  
      */
 499  
     @Override
 500  
         public void addRequiredNonEditableProperties(){
 501  0
     }
 502  
     
 503  
     public boolean isPropertyNonEditableButRequired(String propertyName) {
 504  0
         return WebUtils.isPropertyEditable(requiredNonEditableProperties, propertyName);
 505  
     }
 506  
     
 507  
     protected String getParameter(HttpServletRequest request, String parameterName){
 508  0
             return request.getParameter(parameterName);
 509  
     }
 510  
     
 511  
     protected String[] getParameterValues(HttpServletRequest request, String parameterName){
 512  0
             return request.getParameterValues(parameterName);
 513  
     }
 514  
     
 515  
     @Override
 516  
         public Set<String> getRequiredNonEditableProperties(){
 517  0
             return requiredNonEditableProperties;
 518  
     }
 519  
     
 520  
         /**
 521  
          * @see PojoForm#registerStrutsActionMappingScope(String)
 522  
          */
 523  
         @Override
 524  
         public void registerStrutsActionMappingScope(String strutsActionMappingScope) {
 525  0
                 this.strutsActionMappingScope = strutsActionMappingScope;
 526  0
         }
 527  
         
 528  
         public String getStrutsActionMappingScope() {
 529  0
                 return strutsActionMappingScope;
 530  
         }
 531  
         
 532  
         /**
 533  
          * @see PojoForm#registerStrutsActionMappingScope(String)
 534  
          */
 535  
         @Override
 536  
         public void registerIsNewForm(boolean isNewForm) {
 537  0
                 this.isNewForm = isNewForm;
 538  0
         }
 539  
         
 540  
         @Override
 541  
         public boolean getIsNewForm() {
 542  0
                 return this.isNewForm;
 543  
         }
 544  
         
 545  
         
 546  
         /**
 547  
          * @see PojoForm#shouldPropertyBePopulatedInForm(java.lang.String, javax.servlet.http.HttpServletRequest)
 548  
          */
 549  
         @Override
 550  
         public boolean shouldPropertyBePopulatedInForm(String requestParameterName, HttpServletRequest request) {
 551  
                 
 552  0
                 if (requestParameterName.equals(PojoFormBase.PREVIOUS_REQUEST_EDITABLE_PROPERTIES_GUID)) {
 553  0
                         return false; // don't repopulate this
 554  
                 }
 555  0
                 else if (StringUtils.equalsIgnoreCase("session",getStrutsActionMappingScope()) && !getIsNewForm()) {
 556  0
                         return isPropertyEditable(requestParameterName) || isPropertyNonEditableButRequired(requestParameterName); 
 557  
                 }
 558  0
                 return true;
 559  
                 
 560  
         }
 561  
 
 562  
         /**
 563  
          * Base implementation that returns just "start".  sub-implementations should not add values to Set instance returned
 564  
          * by this method, and should create its own instance.
 565  
          * 
 566  
          * @see PojoForm#getMethodToCallsToBypassSessionRetrievalForGETRequests()
 567  
          */
 568  
         @Override
 569  
         public Set<String> getMethodToCallsToBypassSessionRetrievalForGETRequests() {
 570  0
                 Set<String> defaultMethodToCalls = new HashSet<String>();
 571  0
                 defaultMethodToCalls.add(KRADConstants.START_METHOD);
 572  0
                 return defaultMethodToCalls;
 573  
         }
 574  
 
 575  
 
 576  
 
 577  
         /**
 578  
          * Sets the guid to editable properties consulted during population
 579  
          * 
 580  
          */
 581  
         @Override
 582  
         public void setPopulateEditablePropertiesGuid(String guid) {
 583  0
                 this.populateEditablePropertiesGuid = guid;
 584  0
         }
 585  
         
 586  
         /**
 587  
          * @return the guid for the populate editable properties
 588  
          */
 589  
         public String getPopulateEditablePropertiesGuid() {
 590  0
                 return this.populateEditablePropertiesGuid;
 591  
         }
 592  
         
 593  
         /**
 594  
          * Sets the guid of the editable properties which were registered by the action
 595  
          * @see PojoForm#setActionEditablePropertiesGuid(java.lang.String)
 596  
          */
 597  
         @Override
 598  
         public void setActionEditablePropertiesGuid(String guid) {
 599  0
                 this.actionEditablePropertiesGuid = guid;
 600  0
         }
 601  
         
 602  
         /**
 603  
          * @return the guid of the editable properties which had been registered by the action processing
 604  
          */
 605  
         public String getActionEditablePropertiesGuid() {
 606  0
                 return actionEditablePropertiesGuid;
 607  
         }
 608  
         
 609  
         /**
 610  
          * @return the editable properties to be consulted during population
 611  
          */
 612  
         public Set<String> getPopulateEditableProperties() {
 613  0
                 EditablePropertiesHistoryHolder holder = (EditablePropertiesHistoryHolder) GlobalVariables.getUserSession().getObjectMap().get(
 614  
                 KRADConstants.EDITABLE_PROPERTIES_HISTORY_HOLDER_ATTR_NAME);
 615  0
             if (holder == null) {
 616  0
                     holder = new EditablePropertiesHistoryHolder();
 617  
             }
 618  0
             GlobalVariables.getUserSession().addObject(KRADConstants.EDITABLE_PROPERTIES_HISTORY_HOLDER_ATTR_NAME, holder);
 619  
                 
 620  0
                 return holder.getEditableProperties(getPopulateEditablePropertiesGuid());
 621  
         }
 622  
         
 623  
         /**
 624  
          * Copies all editable properties in the populate editable properties to the action editable properties
 625  
          */
 626  
         public void copyPopulateEditablePropertiesToActionEditableProperties() {
 627  0
                 Set<String> populateEditableProperties = getPopulateEditableProperties();
 628  0
                 for (String property : populateEditableProperties) {
 629  0
                         registerEditableProperty(property);
 630  
                 }
 631  0
         }
 632  
         
 633  
         // end Kuali Foundation modification
 634  
 }