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