Coverage Report - pt.digitalis.dif.dem.objects.parameters.types.AbstractParameter
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractParameter
0%
0/280
0%
0/162
3,089
 
 1  0
 /**
 2  
  * - Digitalis Internal Framework v2.0 - (C) 2007, Digitalis Informatica. Distribuicao e Gestao de Informatica, Lda.
 3  
  * Estrada de Paco de Arcos num.9 - Piso -1 2780-666 Paco de Arcos Telefone: (351) 21 4408990 Fax: (351) 21 4408999
 4  
  * http://www.digitalis.pt
 5  
  */
 6  
 package pt.digitalis.dif.dem.objects.parameters.types;
 7  
 
 8  
 import java.util.ArrayList;
 9  
 import java.util.HashMap;
 10  
 import java.util.List;
 11  
 import java.util.Map;
 12  
 import java.util.Map.Entry;
 13  
 
 14  
 import pt.digitalis.dif.controller.http.HTTPConstants;
 15  
 import pt.digitalis.dif.controller.interfaces.IDIFContext;
 16  
 import pt.digitalis.dif.controller.interfaces.IDIFSession;
 17  
 import pt.digitalis.dif.controller.security.objects.IDIFUser;
 18  
 import pt.digitalis.dif.dem.Entity;
 19  
 import pt.digitalis.dif.dem.annotations.parameter.Rule;
 20  
 import pt.digitalis.dif.dem.interfaces.IStageInstance;
 21  
 import pt.digitalis.dif.dem.managers.IMessageManager;
 22  
 import pt.digitalis.dif.dem.objects.messages.MessageList;
 23  
 import pt.digitalis.dif.dem.objects.parameters.IEditableParameter;
 24  
 import pt.digitalis.dif.dem.objects.parameters.IParameter;
 25  
 import pt.digitalis.dif.dem.objects.parameters.ParameterScope;
 26  
 import pt.digitalis.dif.dem.objects.parameters.constraints.IParameterConstraint;
 27  
 import pt.digitalis.dif.dem.objects.parameters.constraints.ParameterConstraintResult;
 28  
 import pt.digitalis.dif.dem.objects.parameters.errors.ParameterError;
 29  
 import pt.digitalis.dif.dem.objects.parameters.errors.ParameterErrorList;
 30  
 import pt.digitalis.dif.dem.objects.parameters.errors.ParameterErrorType;
 31  
 import pt.digitalis.dif.dem.objects.parameters.rules.IParameterRule;
 32  
 import pt.digitalis.dif.dem.objects.parameters.rules.ParameterRuleResult;
 33  
 import pt.digitalis.dif.dem.objects.parameters.validators.IParameterValidator;
 34  
 import pt.digitalis.dif.exception.objects.ParameterException;
 35  
 import pt.digitalis.dif.ioc.DIFIoCRegistry;
 36  
 import pt.digitalis.dif.startup.DIFGeneralConfigurationParameters;
 37  
 import pt.digitalis.dif.utils.ObjectFormatter;
 38  
 import pt.digitalis.dif.utils.extensions.document.DocumentRepositoryEntry;
 39  
 import pt.digitalis.dif.utils.logging.DIFLogger;
 40  
 import pt.digitalis.log.ILogWrapper;
 41  
 import pt.digitalis.utils.common.StringUtils;
 42  
 
 43  
 /**
 44  
  * This class will define a Parameter.
 45  
  * <p>
 46  
  * It will hold information relative to the Parameter value, ID key and validation constraints.
 47  
  * 
 48  
  * @param <T>
 49  
  *            generic type of the parameter
 50  
  * @author Pedro Viegas <a href="mailto:pviegas@digitalis.pt">pviegas@digitalis.pt</a><br/>
 51  
  * @author Rodrigo Gonçalves <a href="mailto:rgoncalves@digitalis.pt">rgoncalves@digitalis.pt</a>
 52  
  * @created 2007/05/04
 53  
  */
 54  0
 abstract public class AbstractParameter<T> implements IParameter<T>, IEditableParameter {
 55  
 
 56  
     /** Logger for specific logging needs */
 57  0
     static private ILogWrapper logger = DIFLogger.getLogger();
 58  
 
 59  
     /** The message manager to get class messages */
 60  
     static IMessageManager messageManager;
 61  
 
 62  
     /** Messages cache for all constraints */
 63  
     static private MessageList messages;
 64  
 
 65  
     /**
 66  
      * Get's the Message Manager from the IoC
 67  
      * 
 68  
      * @return the message manager instance
 69  
      */
 70  
     static private IMessageManager getMessageManager()
 71  
     {
 72  0
         if (messageManager == null)
 73  0
             messageManager = DIFIoCRegistry.getRegistry().getImplementation(IMessageManager.class);
 74  
 
 75  0
         return messageManager;
 76  
     }
 77  
 
 78  
     /**
 79  
      * Lazy loading getter of messages
 80  
      * 
 81  
      * @return the messages
 82  
      */
 83  
     public static MessageList getMessages()
 84  
     {
 85  
         // If the messages have not yet been loaded do it now
 86  0
         if (messages == null)
 87  
         {
 88  0
             messages = getMessageManager().collectEntityMessagesFromRepository(AbstractParameter.class);
 89  
         }
 90  
 
 91  0
         return messages;
 92  
     }
 93  
 
 94  
     /** If the USER scoped parameter can be accessed by anonymous access without reporting an error */
 95  0
     private boolean allowAnonymous = false;
 96  
 
 97  
     /** A list of constraints to validate on parameter setting */
 98  0
     private Map<String, IParameterConstraint> constraints = new HashMap<String, IParameterConstraint>();
 99  
 
 100  
     /** The parameter default value */
 101  
     private T defaultValue;
 102  
 
 103  
     /**
 104  
      * used to determine if it is the first run for static parameters first tme only initialization (default value
 105  
      * setting)
 106  
      */
 107  0
     private Boolean firstInitialization = true;
 108  
 
 109  
     /** if T allows the form parameter to be configured (thus declaring the form as configurable) */
 110  0
     private Boolean formConfigurable = false;
 111  
 
 112  
     /** The form the parameter is linked to if available */
 113  0
     private String formLinked = null;
 114  
 
 115  
     /** The id of the parameter */
 116  
     private String id;
 117  
 
 118  
     /** The parameter scope */
 119  
     private ParameterScope parameterScope;
 120  
 
 121  
     /** The id of the parent entity that owns the parameter */
 122  
     private String parentID;
 123  
 
 124  
     /** The entity type of the parent entity that owns the parameter */
 125  
     private Entity parentType;
 126  
 
 127  
     /** Persist to the persistent repository. Persist between JVM restarts */
 128  0
     private Boolean persistToRepository = false;
 129  
 
 130  
     /** If the parameter cannot be modified after initialization */
 131  0
     private Boolean readonly = false;
 132  
 
 133  
     /** If this parameter is referenced in a {@link Rule} used in another {@link IParameter} */
 134  0
     private Boolean referencedInARuleFromAnotherParameter = false;
 135  
 
 136  
     /** If the parameter must always be passed a value. Only for REQUEST scoped parameters */
 137  0
     private Boolean required = false;
 138  
 
 139  
     /** The parameter rules */
 140  0
     private List<IParameterRule<T>> rules = new ArrayList<IParameterRule<T>>();
 141  
 
 142  
     /** A list of associated validators to validate on parameter setting */
 143  0
     private Map<String, IParameterValidator> validators = new HashMap<String, IParameterValidator>();
 144  
 
 145  
     /** The parameter current value */
 146  
     private T value;
 147  
 
 148  
     /**
 149  
      * Modifier for the 'rules' attribute.
 150  
      * 
 151  
      * @param rule
 152  
      *            the new rule to add
 153  
      */
 154  
     public void addRule(IParameterRule<T> rule)
 155  
     {
 156  0
         this.rules.add(rule);
 157  0
     }
 158  
 
 159  
     /**
 160  
      * To override in each parameter type class as needed
 161  
      * 
 162  
      * @return the list of automatic constraints that each parameter type adds
 163  
      */
 164  
     protected String automaticConstraints()
 165  
     {
 166  0
         return "";
 167  
     }
 168  
 
 169  
     /**
 170  
      * @see java.lang.Object#clone()
 171  
      */
 172  
     @Override
 173  
     @SuppressWarnings("unchecked")
 174  
     public IParameter<T> clone() throws CloneNotSupportedException
 175  
     {
 176  
         try
 177  
         {
 178  
             IParameter<T> parameter;
 179  
 
 180  0
             parameter = this.getClass().newInstance();
 181  0
             parameter.forceInitialize(this.allowAnonymous, this.constraints, this.defaultValue, this.formLinked,
 182  0
                     this.id, this.parameterScope, this.parentID, this.parentType, this.persistToRepository,
 183  0
                     this.readonly, this.referencedInARuleFromAnotherParameter, this.required, this.formConfigurable,
 184  0
                     this.rules, this.validators, this.value);
 185  
 
 186  0
             return parameter;
 187  
         }
 188  0
         catch (InstantiationException e)
 189  
         {
 190  0
             throw new CloneNotSupportedException(e.getMessage());
 191  
         }
 192  0
         catch (IllegalAccessException e)
 193  
         {
 194  0
             throw new CloneNotSupportedException(e.getMessage());
 195  
         }
 196  
     }
 197  
 
 198  
     /**
 199  
      * Converts an object to strong format, according to any rules necessary in conversion of the given parameter type
 200  
      * 
 201  
      * @param obj
 202  
      *            the object to convert
 203  
      * @return the object in a string representation
 204  
      */
 205  
     protected String convertObjectToString(Object obj)
 206  
     {
 207  0
         return StringUtils.toStringOrNull(obj);
 208  
     }
 209  
 
 210  
     /**
 211  
      * @see pt.digitalis.dif.dem.objects.parameters.IParameter#forceInitialize(boolean, java.util.Map, java.lang.Object,
 212  
      *      java.lang.String, java.lang.String, pt.digitalis.dif.dem.objects.parameters.ParameterScope,
 213  
      *      java.lang.String, pt.digitalis.dif.dem.Entity, boolean, boolean, boolean, boolean, boolean, java.util.List,
 214  
      *      java.util.Map, java.lang.Object)
 215  
      */
 216  
     public void forceInitialize(boolean allowAnonymous, Map<String, IParameterConstraint> constraints, T defaultValue,
 217  
             String formLinked, String id, ParameterScope parameterScope, String parentID, Entity parentType,
 218  
             boolean persistToRepository, boolean readonly, boolean referencedInARuleFromAnotherParameter,
 219  
             boolean required, boolean formConfigurable, List<IParameterRule<T>> rules,
 220  
             Map<String, IParameterValidator> validators, T value)
 221  
     {
 222  0
         this.allowAnonymous = allowAnonymous;
 223  0
         this.defaultValue = defaultValue;
 224  0
         this.formLinked = formLinked;
 225  0
         this.id = id;
 226  0
         this.parameterScope = parameterScope;
 227  0
         this.parentID = parentID;
 228  0
         this.parentType = parentType;
 229  0
         this.persistToRepository = persistToRepository;
 230  0
         this.readonly = readonly;
 231  0
         this.referencedInARuleFromAnotherParameter = referencedInARuleFromAnotherParameter;
 232  0
         this.required = required;
 233  0
         this.formConfigurable = formConfigurable;
 234  
 
 235  0
         this.constraints = new HashMap<String, IParameterConstraint>();
 236  0
         this.constraints.putAll(constraints);
 237  
 
 238  0
         this.rules = new ArrayList<IParameterRule<T>>();
 239  0
         this.rules.addAll(rules);
 240  
 
 241  0
         this.validators = new HashMap<String, IParameterValidator>();
 242  0
         this.validators.putAll(validators);
 243  
 
 244  0
         this.value = value;
 245  0
     }
 246  
 
 247  
     /**
 248  
      * @return the constraints
 249  
      */
 250  
     public Map<String, IParameterConstraint> getConstraints()
 251  
     {
 252  0
         return constraints;
 253  
     }
 254  
 
 255  
     /**
 256  
      * Return a common debug prefix
 257  
      * 
 258  
      * @return the prefix
 259  
      */
 260  
     private String getDebugPrefix()
 261  
     {
 262  0
         return "[" + getParameterScope().toString() + " parameter \"" + getId() + "\"] ";
 263  
     }
 264  
 
 265  
     /**
 266  
      * @see pt.digitalis.dif.dem.objects.parameters.IParameter#getFormLinked()
 267  
      */
 268  
     public String getFormLinked()
 269  
     {
 270  0
         return formLinked;
 271  
     }
 272  
 
 273  
     /**
 274  
      * @return the id
 275  
      */
 276  
     public String getId()
 277  
     {
 278  0
         return id;
 279  
     }
 280  
 
 281  
     /**
 282  
      * Return the language from the context of the default if not available
 283  
      * 
 284  
      * @param context
 285  
      *            the context
 286  
      * @return the language
 287  
      */
 288  
     protected String getLanguage(IDIFContext context)
 289  
     {
 290  
         // If a session is available get the current language, else, the default will be used
 291  0
         if (context != null && context.getSession() != null && context.getSession().getLanguage() != null)
 292  
         {
 293  0
             return context.getSession().getLanguage().toLowerCase();
 294  
         }
 295  
         else
 296  0
             return DIFGeneralConfigurationParameters.getInstance().getDefaultLanguage();
 297  
     }
 298  
 
 299  
     /**
 300  
      * @return the parameterScope
 301  
      */
 302  
     public ParameterScope getParameterScope()
 303  
     {
 304  0
         return parameterScope;
 305  
     }
 306  
 
 307  
     /**
 308  
      * @return the parentID
 309  
      */
 310  
     public String getParentID()
 311  
     {
 312  0
         return parentID;
 313  
     }
 314  
 
 315  
     /**
 316  
      * @return the parentType
 317  
      */
 318  
     public Entity getParentType()
 319  
     {
 320  0
         return parentType;
 321  
     }
 322  
 
 323  
     /**
 324  
      * @see pt.digitalis.dif.dem.objects.parameters.IParameter#getRules()
 325  
      */
 326  
     public List<IParameterRule<T>> getRules()
 327  
     {
 328  0
         return rules;
 329  
     }
 330  
 
 331  
     /**
 332  
      * @return the validators
 333  
      */
 334  
     public Map<String, IParameterValidator> getValidators()
 335  
     {
 336  0
         return validators;
 337  
     }
 338  
 
 339  
     /**
 340  
      * @see pt.digitalis.dif.dem.objects.parameters.IParameter#getValue(IDIFContext)
 341  
      */
 342  
     @SuppressWarnings("unchecked")
 343  
     public T getValue(IDIFContext context) throws ParameterException
 344  
     {
 345  
 
 346  0
         if (parameterScope == ParameterScope.SESSION)
 347  
         {
 348  0
             if (context == null || context.getSession() == null)
 349  
             {
 350  
                 String message;
 351  
 
 352  0
                 if (context == null)
 353  0
                     message = getMessages().getMessages().get("noSession");
 354  
                 else
 355  0
                     message = getMessages().getMessages(context.getLanguage()).get("noSession");
 356  
 
 357  0
                 throw new ParameterException(getDebugPrefix() + message, this);
 358  
             }
 359  
 
 360  0
             return (T) context.getSession().getAttribute(getId());
 361  
 
 362  
         }
 363  0
         else if (parameterScope == ParameterScope.USER)
 364  
         {
 365  0
             if (context == null || context.getSession() == null || context.getSession().getUser() == null)
 366  0
                 if (allowAnonymous)
 367  
                 {
 368  0
                     logWarning("Can't process a USER scoped parameter without a user authenticated in session. Returning null.");
 369  0
                     return null;
 370  
                 }
 371  
                 else
 372  
                 {
 373  0
                     String language = (context == null ? DIFGeneralConfigurationParameters.getInstance()
 374  0
                             .getDefaultLanguage() : context.getLanguage());
 375  
 
 376  0
                     throw new ParameterException(getDebugPrefix() + getMessages().getMessages(language).get("noUser"),
 377  0
                             this);
 378  
                 }
 379  
 
 380  
             // FIXME: This will fail since the value is not kept through all user instances
 381  0
             return (T) context.getSession().getUser().getParameter(getId());
 382  
 
 383  
         }
 384  
         else
 385  0
             return this.value;
 386  
     }
 387  
 
 388  
     /**
 389  
      * @see pt.digitalis.dif.dem.objects.parameters.IParameter#getValueAsDocument(pt.digitalis.dif.controller.interfaces.IDIFContext)
 390  
      */
 391  
     public DocumentRepositoryEntry getValueAsDocument(IDIFContext context) throws ParameterException
 392  
     {
 393  
         // Normally a parameter does not implement this mathod...
 394  0
         throw new ParameterException(getMessages().getMessages(context.getLanguage()).get("invalidUsage"), this);
 395  
     }
 396  
 
 397  
     /**
 398  
      * @see pt.digitalis.dif.dem.objects.parameters.IParameter#getValueAsString(IDIFContext)
 399  
      */
 400  
     public String getValueAsString(IDIFContext context) throws ParameterException
 401  
     {
 402  0
         T currentValue = getValue(context);
 403  
 
 404  0
         if (currentValue == null)
 405  0
             return null;
 406  
         else
 407  0
             return currentValue.toString();
 408  
     }
 409  
 
 410  
     /**
 411  
      * @param context
 412  
      *            the current stage context
 413  
      * @return T if the linked form has been submitted
 414  
      */
 415  
     protected boolean hasFormBeenSubmited(IDIFContext context)
 416  
     {
 417  0
         if (getFormLinked() == null)
 418  0
             return false;
 419  
         else
 420  
         {
 421  
 
 422  0
             Object submitStage = context.getRequest().getParameter(HTTPConstants.FORM_SUBMIT_STAGE);
 423  0
             Object submitForm = context.getRequest().getParameter(HTTPConstants.FORM_SUBMIT_NAME);
 424  
 
 425  0
             return (submitStage != null && submitForm != null && context.getStage().equals(submitStage) && getFormLinked()
 426  0
                     .equals(submitForm.toString()));
 427  
         }
 428  
     }
 429  
 
 430  
     /**
 431  
      * @return T when the parameter has a value set
 432  
      */
 433  
     protected boolean hasValue()
 434  
     {
 435  0
         return this.value != null;
 436  
     }
 437  
 
 438  
     /**
 439  
      * @see pt.digitalis.dif.dem.objects.parameters.IParameter#initialize(java.lang.String, pt.digitalis.dif.dem.Entity,
 440  
      *      java.lang.String, boolean, boolean, boolean, pt.digitalis.dif.dem.objects.parameters.ParameterScope,
 441  
      *      java.lang.String, java.lang.String, java.util.Map, java.util.List)
 442  
      */
 443  
     public void initialize(String id, Entity parentType, String parentID, boolean formConfigurable,
 444  
             boolean persistToRepository, boolean allowAnonymousAccess, ParameterScope parameterScope,
 445  
             String defaultValue, String constraintDefinition, Map<String, IParameterValidator> validators,
 446  
             List<IParameterRule<T>> rules) throws ParameterException
 447  
     {
 448  
 
 449  0
         this.id = id.toLowerCase();
 450  0
         this.parentID = parentID.toLowerCase();
 451  0
         this.parentType = parentType;
 452  0
         this.allowAnonymous = allowAnonymousAccess;
 453  0
         this.persistToRepository = persistToRepository;
 454  0
         this.parameterScope = parameterScope;
 455  0
         this.formConfigurable = formConfigurable;
 456  
 
 457  0
         if (validators == null)
 458  0
             this.validators = new HashMap<String, IParameterValidator>();
 459  
         else
 460  0
             this.validators = validators;
 461  
 
 462  0
         if (rules == null)
 463  0
             this.rules = new ArrayList<IParameterRule<T>>();
 464  
         else
 465  0
             this.rules = rules;
 466  
 
 467  0
         this.constraints = new HashMap<String, IParameterConstraint>();
 468  
 
 469  
         // Add automatic constraints
 470  0
         if (!"".equals(automaticConstraints()))
 471  
         {
 472  0
             if (constraintDefinition == null || "".equals(constraintDefinition))
 473  0
                 constraintDefinition = automaticConstraints();
 474  
             else
 475  0
                 constraintDefinition = automaticConstraints() + "," + constraintDefinition;
 476  
         }
 477  
 
 478  
         // If there are constraints defined...
 479  0
         if (constraintDefinition != null && !"".equals(constraintDefinition))
 480  
         {
 481  
 
 482  0
             String[] constraintStrings = constraintDefinition.split(",");
 483  
 
 484  
             // For each declared constraint
 485  0
             for (String constraintString: constraintStrings)
 486  
             {
 487  
                 String constraintID;
 488  0
                 int posEqual = constraintString.indexOf("=");
 489  
 
 490  0
                 constraintID = (posEqual == -1 ? constraintString : constraintString.substring(0, posEqual));
 491  0
                 constraintID = constraintID.trim().toLowerCase();
 492  
 
 493  
                 // Readonly is a constraint with special treatment in the
 494  
                 // Parameter class itself. Does not have an
 495  
                 // IParameterConstraint implementation. No need.
 496  0
                 if (constraintID.equals("readonly"))
 497  0
                     this.readonly = true;
 498  0
                 else if (constraintID.equals("required"))
 499  
                     // Required only for REQUEST parameters
 500  0
                     this.required = true;
 501  
                 else
 502  
                 {
 503  0
                     IParameterConstraint constraint = DIFIoCRegistry.getRegistry().getImplementation(
 504  0
                             IParameterConstraint.class, constraintID);
 505  
 
 506  0
                     if (constraint == null)
 507  
                     {
 508  
                         // Bad constraint name. Report error
 509  0
                         throw new ParameterException("Inexistant constraint \"" + constraintID + "\"", this);
 510  
                     }
 511  
                     else
 512  
                     {
 513  0
                         constraint.configureConstraint(constraintString);
 514  0
                         constraints.put(constraintID, constraint);
 515  
                     }
 516  
                 }
 517  
             }
 518  
         }
 519  
 
 520  0
         if (defaultValue != null && !"".equals(defaultValue))
 521  
         {
 522  0
             setValueFromString(defaultValue, null);
 523  0
             this.defaultValue = value;
 524  
         }
 525  
 
 526  
         if (persistToRepository)
 527  
         {
 528  
             // TODO: Implement persistence. Should read the value if available from the repository.
 529  
         }
 530  0
     }
 531  
 
 532  
     /**
 533  
      * @see pt.digitalis.dif.dem.objects.parameters.IParameter#isAllowAnonymous()
 534  
      */
 535  
     public boolean isAllowAnonymous()
 536  
     {
 537  0
         return allowAnonymous;
 538  
     }
 539  
 
 540  
     /**
 541  
      * Inspector for the 'firstInitialization' attribute.
 542  
      * 
 543  
      * @return the firstInitialization value
 544  
      */
 545  
     public boolean isFirstInitialization()
 546  
     {
 547  0
         return firstInitialization;
 548  
     }
 549  
 
 550  
     /**
 551  
      * @see pt.digitalis.dif.dem.objects.parameters.IParameter#isFormConfigurable()
 552  
      */
 553  
     public boolean isFormConfigurable()
 554  
     {
 555  0
         return formConfigurable && StringUtils.isNotBlank(this.getFormLinked());
 556  
     }
 557  
 
 558  
     /**
 559  
      * @return the persistToRepository
 560  
      */
 561  
     public boolean isPersistToRepository()
 562  
     {
 563  0
         return persistToRepository;
 564  
     }
 565  
 
 566  
     /**
 567  
      * @return the readonly
 568  
      */
 569  
     public boolean isReadonly()
 570  
     {
 571  0
         return readonly;
 572  
     }
 573  
 
 574  
     /**
 575  
      * @see pt.digitalis.dif.dem.objects.parameters.IParameter#isReferencedInARuleFromAnotherParameter()
 576  
      */
 577  
     public boolean isReferencedInARuleFromAnotherParameter()
 578  
     {
 579  0
         return referencedInARuleFromAnotherParameter;
 580  
     }
 581  
 
 582  
     /**
 583  
      * @see pt.digitalis.dif.dem.objects.parameters.IParameter#isRequired()
 584  
      */
 585  
     public boolean isRequired()
 586  
     {
 587  0
         return required;
 588  
     }
 589  
 
 590  
     /**
 591  
      * @see pt.digitalis.dif.dem.objects.parameters.IParameter#isStringSetterSupported()
 592  
      */
 593  
     public boolean isStringSetterSupported()
 594  
     {
 595  0
         return true;
 596  
     }
 597  
 
 598  
     /**
 599  
      * Logs a warning
 600  
      * 
 601  
      * @param warning
 602  
      *            the warning message to log
 603  
      */
 604  
     protected void logWarning(String warning)
 605  
     {
 606  
 
 607  0
         if (DIFLogger.getLogger().isDebugEnabled())
 608  0
             DIFLogger.getLogger().warn(getDebugPrefix() + warning + "\n" + this.toString());
 609  
         else
 610  0
             DIFLogger.getLogger().warn(getDebugPrefix() + warning);
 611  0
     }
 612  
 
 613  
     /**
 614  
      * @see pt.digitalis.dif.dem.objects.parameters.IParameter#refreshParameterValue(pt.digitalis.dif.dem.interfaces.IStageInstance)
 615  
      */
 616  
     @SuppressWarnings("unchecked")
 617  
     public ParameterErrorList refreshParameterValue(IStageInstance stageInstance)
 618  
     {
 619  0
         IDIFContext context = (stageInstance == null ? null : stageInstance.getContext());
 620  
 
 621  0
         if (context == null)
 622  0
             return new ParameterErrorList(this, null);
 623  
         else
 624  
         {
 625  0
             String language = context.getLanguage();
 626  0
             ParameterErrorList list = new ParameterErrorList(this, null);
 627  
 
 628  
             // Read the value from the request
 629  0
             Object requestValue = context.getRequest().getParameter(getId());
 630  0
             boolean parameterExistsInRequest = context.getRequest().getParameters().containsKey(getId());
 631  
 
 632  
             // IMPLEMENTATION NOTE:
 633  
             //
 634  
             // The parameter will be updated based on the following conditions:
 635  
             // - Parameter Scope: REQUEST, STATIC, SESSION, USER
 636  
             // - Persist the value: Read it from a persistent repository on initialization
 637  
             // - Default present: If no previous value a default value may be used
 638  
             // - Context: The context may be a source for values for REQUEST, USER or SESSION scopes
 639  
             // - Form submission for parameters that are linkedToForm's
 640  
 
 641  0
             if (requestValue == null && !parameterExistsInRequest)
 642  
             {
 643  0
                 if (getParameterScope().equals(ParameterScope.SESSION))
 644  
                 {
 645  
                     // No value passed, read the value from the session
 646  
                     // Gets the session from the context
 647  0
                     IDIFSession session = context.getSession();
 648  
 
 649  0
                     if (session == null)
 650  
                     {
 651  0
                         ParameterError error = new ParameterError(getMessages().getMessages(language).get("noSession"),
 652  0
                                 ParameterErrorType.NO_SESSION);
 653  0
                         list.addError(error);
 654  
                     }
 655  0
                     else if (session.containsAttribute(getId()))
 656  
                     {
 657  
                         // If the parameter already exists in session
 658  0
                         Object sessionValue = session.getAttribute(getId());
 659  
 
 660  
                         // Recover value in session
 661  0
                         logger.debug(getDebugPrefix() + "Setting to \"" + sessionValue + "\" (read from Session)");
 662  
 
 663  0
                         requestValue = sessionValue;
 664  
                     }
 665  
                 }
 666  0
                 else if (getParameterScope().equals(ParameterScope.USER))
 667  
                 {
 668  
                     // TODO: Check the problem of several copies of the same user so the parameter is not kept between
 669  
                     // requests
 670  
 
 671  0
                     IDIFSession session = context.getSession();
 672  
 
 673  0
                     if (session == null)
 674  
                     {
 675  0
                         ParameterError error = new ParameterError(getMessages().getMessages(language).get("noSession"),
 676  0
                                 ParameterErrorType.NO_SESSION);
 677  0
                         list.addError(error);
 678  
                     }
 679  
                     else
 680  
                     {
 681  
                         // Gets the user from the context
 682  0
                         IDIFUser user = session.getUser();
 683  
 
 684  0
                         if (user == null && !allowAnonymous)
 685  
                         {
 686  0
                             ParameterError error = new ParameterError(
 687  0
                                     getMessages().getMessages(language).get("noUser"), ParameterErrorType.NO_USER);
 688  0
                             list.addError(error);
 689  
                         }
 690  0
                         else if (user != null && user.containsParameter(getId()))
 691  
                         {
 692  
                             // If the parameter already exists in the user
 693  0
                             requestValue = user.getParameter(getId());
 694  
 
 695  0
                             logger.debug(getDebugPrefix() + "Setting to \"" + requestValue + "\" (read from User)");
 696  
                         }
 697  
                     }
 698  
                 }
 699  
             }
 700  
 
 701  
             // IMPLEMENTATION NOTE:
 702  
             // If the Scope is Static there is nothing to do since the initializations have already taken care of it in
 703  
             // the CodeGen and this value will persist through all the JVM life BUT we must check the REQUEST for value
 704  
             // setting
 705  
 
 706  
             // All validations and initializations have taken place. Set the value now if existent
 707  
             // If no value present in the request (omitted or passed as null)...
 708  0
             if (requestValue == null)
 709  
             {
 710  
 
 711  0
                 if (isRequired() && !isReferencedInARuleFromAnotherParameter())
 712  
                 {
 713  
 
 714  
                     // Request parameters with required must be set!
 715  0
                     ParameterError error = new ParameterError(getMessages().getMessages(language).get("required"),
 716  0
                             ParameterErrorType.MISSING);
 717  0
                     list.addError(error);
 718  0
                     list.addErrorList(setValue(null, stageInstance, true).getErrorList());
 719  
                 }
 720  
                 else
 721  
                 {
 722  0
                     if (!parameterExistsInRequest
 723  0
                             && (this.getParameterScope() != ParameterScope.STATIC || this.isFirstInitialization()))
 724  
                     {
 725  
                         // Set if to the default value (or null if none is set)...
 726  0
                         logger.debug(getDebugPrefix() + "No value passed - Setting to "
 727  0
                                 + (defaultValue == null ? "null" : "default \"" + defaultValue.toString() + "\""));
 728  0
                         list.addErrorList(setDefaultValue(stageInstance, true).getErrorList());
 729  
                     }
 730  
 
 731  0
                     this.setFirstInitialization(false);
 732  
                 }
 733  
             }
 734  
             else
 735  
             {
 736  0
                 logger.debug(getDebugPrefix() + "Setting to \"" + requestValue + "\" (read from request)");
 737  
 
 738  0
                 if (isStringSetterSupported())
 739  0
                     list.addErrorList(setValueFromString(this.convertObjectToString(requestValue), stageInstance, true)
 740  0
                             .getErrorList());
 741  
                 else
 742  0
                     list.addErrorList(setValue((T) requestValue, stageInstance, true).getErrorList());
 743  
             }
 744  
 
 745  0
             return list;
 746  
         }
 747  
     }
 748  
 
 749  
     /**
 750  
      * @see pt.digitalis.dif.dem.objects.parameters.IParameter#setDefaultValue(pt.digitalis.dif.dem.interfaces.IStageInstance)
 751  
      */
 752  
     public ParameterErrorList setDefaultValue(IStageInstance stageInstance)
 753  
     {
 754  0
         return setDefaultValue(stageInstance, false);
 755  
     }
 756  
 
 757  
     /**
 758  
      * @see pt.digitalis.dif.dem.objects.parameters.IParameter#setDefaultValue(pt.digitalis.dif.dem.interfaces.IStageInstance,
 759  
      *      boolean)
 760  
      */
 761  
     public ParameterErrorList setDefaultValue(IStageInstance stageInstance, boolean initializationInProgress)
 762  
     {
 763  0
         return setValue(defaultValue, stageInstance, initializationInProgress);
 764  
     }
 765  
 
 766  
     /**
 767  
      * Modifier for the 'firstInitialization' attribute.
 768  
      * 
 769  
      * @param firstInitialization
 770  
      *            the new firstInitialization value to set
 771  
      */
 772  
     public void setFirstInitialization(boolean firstInitialization)
 773  
     {
 774  0
         this.firstInitialization = firstInitialization;
 775  0
     }
 776  
 
 777  
     /**
 778  
      * @see pt.digitalis.dif.dem.objects.parameters.IParameter#setFormConfigurable(boolean)
 779  
      */
 780  
     public void setFormConfigurable(boolean formConfigurable)
 781  
     {
 782  0
         this.formConfigurable = formConfigurable;
 783  0
     }
 784  
 
 785  
     /**
 786  
      * @see pt.digitalis.dif.dem.objects.parameters.IParameter#setFormLinked(java.lang.String)
 787  
      */
 788  
     public void setFormLinked(String formLinked)
 789  
     {
 790  0
         this.formLinked = formLinked;
 791  0
     }
 792  
 
 793  
     /**
 794  
      * @see pt.digitalis.dif.dem.objects.parameters.IParameter#setReferencedInARuleFromAnotherParameter(boolean)
 795  
      */
 796  
     public void setReferencedInARuleFromAnotherParameter(boolean referencedInARuleFromAnotherParameter)
 797  
     {
 798  0
         this.referencedInARuleFromAnotherParameter = referencedInARuleFromAnotherParameter;
 799  0
     }
 800  
 
 801  
     /**
 802  
      * @see pt.digitalis.dif.dem.objects.parameters.IEditableParameter#setRequired(boolean)
 803  
      */
 804  
     public void setRequired(boolean required)
 805  
     {
 806  0
         this.required = required;
 807  0
     }
 808  
 
 809  
     /**
 810  
      * Sets the value of the parameter and runs all constraints and validations
 811  
      * 
 812  
      * @param value
 813  
      *            the value to set
 814  
      * @param stageInstance
 815  
      *            the DIF stage to read if needed. WARNING: If null is interpreted like an initialization and no scope
 816  
      *            repositories will be accessed/updated.
 817  
      * @return return the error messages if the validation fails
 818  
      */
 819  
     public ParameterErrorList setValue(T value, IStageInstance stageInstance)
 820  
     {
 821  0
         return setValue(value, stageInstance, false);
 822  
     }
 823  
 
 824  
     /**
 825  
      * Sets the value of the parameter and runs all constraints and validations
 826  
      * 
 827  
      * @param value
 828  
      *            the value to set
 829  
      * @param stageInstance
 830  
      *            the DIF stage to read if needed. WARNING: If null is interpreted like an initialization and no scope
 831  
      *            repositories will be accessed/updated.
 832  
      * @param initializationInProgress
 833  
      *            T if called within the dif parameter initialization
 834  
      * @return return the error messages if the validation fails
 835  
      */
 836  
     public ParameterErrorList setValue(T value, IStageInstance stageInstance, boolean initializationInProgress)
 837  
     {
 838  
 
 839  0
         ParameterErrorList list = new ParameterErrorList(this, value);
 840  
         IDIFContext context;
 841  
 
 842  0
         if (stageInstance == null)
 843  0
             context = null;
 844  
         else
 845  0
             context = stageInstance.getContext();
 846  
 
 847  
         // Perform validation. Will create the error list if not valid
 848  0
         list = validateParameterValue(value, stageInstance, initializationInProgress);
 849  
 
 850  0
         if (context == null)
 851  
             // Null context is interpreted like an initialization so it will not try to update the repositories defined
 852  
             // by it's scope
 853  0
             this.value = value;
 854  
 
 855  
         else
 856  
         {
 857  0
             if (parameterScope == ParameterScope.SESSION)
 858  
             {
 859  0
                 if (context.getSession() == null)
 860  
                 {
 861  0
                     list.addError(new ParameterError(getMessages().getMessages(context.getLanguage()).get("noSession"),
 862  0
                             ParameterErrorType.NO_SESSION));
 863  
 
 864  0
                     this.value = null;
 865  
                 }
 866  
                 else
 867  
                 {
 868  0
                     context.getSession().addAttribute(getId(), value);
 869  
                 }
 870  
 
 871  
             }
 872  0
             else if (parameterScope == ParameterScope.USER)
 873  
             {
 874  0
                 if (context.getSession() == null || context.getSession().getUser() == null)
 875  
                 {
 876  0
                     if (!allowAnonymous)
 877  0
                         list.addError(new ParameterError(
 878  0
                                 getMessages().getMessages(context.getLanguage()).get("noUser"),
 879  0
                                 ParameterErrorType.NO_USER));
 880  
 
 881  0
                     this.value = null;
 882  
                 }
 883  
                 else
 884  
                 {
 885  
                     // FIXME: This will fail since the value is not kept through all user instances
 886  0
                     context.getSession().getUser().setParameter(getId(), value);
 887  
                 }
 888  
 
 889  
             }
 890  0
             else if (parameterScope == ParameterScope.REQUEST)
 891  
             {
 892  
                 // The parameter will be thrown away after the request is processed
 893  0
                 this.value = value;
 894  
 
 895  
             }
 896  0
             else if (parameterScope == ParameterScope.STATIC)
 897  
                 // Static values are kept in the inner value attribute. The only ones that keep it here.
 898  0
                 this.value = value;
 899  
 
 900  0
             if (isPersistToRepository())
 901  
             {
 902  
                 // TODO: Persist to persistent repository
 903  
             }
 904  
         }
 905  
 
 906  0
         return list;
 907  
     }
 908  
 
 909  
     /**
 910  
      * @see pt.digitalis.dif.dem.objects.parameters.IParameter#setValueFromString(java.lang.String,
 911  
      *      pt.digitalis.dif.dem.interfaces.IStageInstance)
 912  
      */
 913  
     public final ParameterErrorList setValueFromString(String value, IStageInstance stageInstance)
 914  
     {
 915  
 
 916  0
         return this.setValueFromString(value, stageInstance, false);
 917  
     }
 918  
 
 919  
     /**
 920  
      * @see java.lang.Object#toString()
 921  
      */
 922  
     @Override
 923  
     public String toString()
 924  
     {
 925  0
         ObjectFormatter formatter = new ObjectFormatter();
 926  0
         formatter.addItem("ID", this.id);
 927  0
         formatter.addItem("Value", value);
 928  0
         formatter.addItem("Value Type", this.value == null ? "n/a" : this.value.getClass().getCanonicalName());
 929  0
         formatter.addItem("Parent", "(" + this.parentType + ") " + this.parentID);
 930  0
         formatter.addItem("Scope", this.parameterScope);
 931  0
         formatter.addItem("Persist", this.persistToRepository);
 932  0
         formatter.addItem("Readonly", this.readonly);
 933  0
         formatter.addItem("Required", this.required);
 934  0
         formatter.addItem("Default Value", this.defaultValue);
 935  0
         formatter.addItem("Link to Form", this.formLinked);
 936  0
         formatter.addItem("Form Configurable", this.formConfigurable);
 937  0
         formatter.addItem("Constraints", this.constraints);
 938  0
         formatter.addItem("Validators", this.validators);
 939  0
         formatter.addItem("Rules", this.rules);
 940  0
         formatter.addItem("Referenced in a rule from another parameter", this.referencedInARuleFromAnotherParameter);
 941  
 
 942  0
         return formatter.getFormatedObject();
 943  
     }
 944  
 
 945  
     /**
 946  
      * Validate a parameter value on type, constraints, validators and rules, if applied.
 947  
      * 
 948  
      * @param value
 949  
      *            the value to validate
 950  
      * @param stageInstance
 951  
      *            the stage where the parameter is being validated
 952  
      * @param initializationInProgress
 953  
      *            T if called within the dif parameter initialization
 954  
      * @return the list of errors found upon validation
 955  
      */
 956  
     protected ParameterErrorList validateParameterValue(T value, IStageInstance stageInstance,
 957  
             boolean initializationInProgress)
 958  
     {
 959  0
         ParameterErrorList list = new ParameterErrorList(this, value);
 960  
         IDIFContext context;
 961  
 
 962  0
         if (stageInstance == null)
 963  0
             context = null;
 964  
         else
 965  0
             context = stageInstance.getContext();
 966  
 
 967  
         // Validate all constraints
 968  0
         for (Entry<String, IParameterConstraint> constraintEntry: getConstraints().entrySet())
 969  
         {
 970  
 
 971  0
             ParameterConstraintResult constraintResult = constraintEntry.getValue().getValidationResult(value,
 972  0
                     stageInstance);
 973  0
             if (!constraintResult.isValid())
 974  
             {
 975  0
                 list.addError(new ParameterError(constraintEntry.getKey(), constraintResult));
 976  
             }
 977  
         }
 978  
 
 979  
         // Validate all validators
 980  0
         for (Entry<String, IParameterValidator> validatorEntry: getValidators().entrySet())
 981  
         {
 982  0
             if (!validatorEntry.getValue().validate(value, context))
 983  
             {
 984  0
                 ParameterError error = new ParameterError(validatorEntry.getValue().validationErrorMessage(
 985  0
                         getLanguage(context)), ParameterErrorType.VALIDATOR);
 986  0
                 error.setValidator(validatorEntry.getKey(), validatorEntry.getValue());
 987  
 
 988  0
                 list.addError(error);
 989  
             }
 990  
         }
 991  
 
 992  
         // Validate all rules
 993  0
         for (IParameterRule<T> rule: getRules())
 994  
         {
 995  
             ParameterRuleResult result;
 996  
             try
 997  
             {
 998  0
                 result = rule.getValidationResult(stageInstance, value, initializationInProgress, this);
 999  
 
 1000  0
                 if (!result.isValid())
 1001  
                 {
 1002  0
                     ParameterError error = new ParameterError(result.getErrorMessage(), ParameterErrorType.RULE);
 1003  0
                     error.setRule(rule);
 1004  
 
 1005  0
                     list.addError(error);
 1006  
                 }
 1007  
             }
 1008  0
             catch (ParameterException e)
 1009  
             {
 1010  0
                 ParameterError error = new ParameterError(e.getMessage(), ParameterErrorType.RULE);
 1011  0
                 error.setRule(rule);
 1012  
 
 1013  0
                 list.addError(error);
 1014  
             }
 1015  
 
 1016  
         }
 1017  
 
 1018  0
         return list;
 1019  
     }
 1020  
 }