Skip to end of metadata
Go to start of metadata

KFS provides an abstraction layer over Rice's parameter system to make it easier to use.  This page will describe KFS's parameter system and parameter naming conventions within KFS.

Parameter Classes

The org.kuali.core.bo.Parameter BO represents a record in SH_PARM_T. If a parameter represents one of many allowed or denied values, then each of the values should be delimited by a semicolon. For example, the parameter value with "A;B;C" represents a list containing the values A, B, and C.

Within KFS, the use of the Parameter has been restricted to KFS core classes, and module code has been made agnostic of the Parameter BO by using the ParameterService.

Parameter Data Model

  • Parameter (SH_PARM_T): Parameters allow users to control the aspects of the application's behavior that they should be responsible for and which should be able to change independently of application releases.
    • Namespace Code (primary key)
    • Detailed Type Code (primary key)
    • Name (primary key)
    • Type Code
    • Workgroup
    • Value
    • Description
    • Constraint (values allowed or disallowed)- must be A or D
  • Parameter Namespace (SH_PARM_NMSPC_T): High-level classification that allows the association of parameters with a particular application and module. Format is Application-Module, e.g. KFS-FP (KFS Financial Processing), KR-NS (Rice Nervous System), KFS-SY (KFS System Wide)
    • Namespace Code (primary key)
    • Namespace Name
    • Active Indicator
  • Parameter Type (SH_PARM_TYP_T): High-Level classification that allows the grouping of parameters by functional type: e.g Configuration, Authorization, Validation, Help
    • Type Code (primary key)
    • Type Name
    • Active Indicator
  • Parameter Detailed Type (SH_PARM_DTL_TYP_T): I.E. Component - Entities such as maintenance tables or transactional documents and batch steps. There are also general values that can be used when the parameter does not relate to a specific entity or batch step: Lookup, Inquiry, Document, Batch, and All.
    • Namespace Code (primary key)
    • Detailed Type Code (primary key)
    • Detailed Type Name
    • Active Indicator

KFS Parameter Conventions

There are three primary formats for a parameter's value:

  1. Indicator value: Y (true) or N (false).
  2. List of values: a list of values in a string delimited by semicolons (e.g. A;B123;C for A, B123, and C). Whether the list represents allowed or denied values is determined by the parameter's constraint code. Each element of the list is delimited with a semicolon.
  3. List of constraining/constrained value mappings: a semicolon delimited list of constraining/constrained value pairs.  A constraining value maps to a list of constrained values, which are comma delimited.  A constraining/constrained value pair represents all of the values associated with the constraining value.  Whether the association refers to an allowed or denied relationship is based on the parameter's constraint code.  For example, assume that the chart code DD may only be associated with the object codes 1111 and 2222.  The constraining value is the chart code, and the constrained value is the object code.  The pair would be "DD=1111,2222", and if the parameter constraint is A (allow), then this value would be interpreted as, "chart code DD (i.e. the constraining value) must have object codes 1111 or 2222 (i.e.the constrained values)".  Multiple pairs may be delimited with semicolons.  For example, a deny parameter with the value of "DD=1111,2222;EE=3333,4444" (note the semicolons and commas) can be interpreted as, "If the chart code is DD, then the object code cannot be 1111 or 2222.  If the chart code is EE then the object code cannot be 3333 or 4444.

In addition, there are two primary uses for a parameter in KFS:

  1. Parameters are used to provide configuration values. Examples include flags to turn on/off certain processing and email addresses to which to send notifications.
  2. Parameters are used to define valid/invalid values for validation purposes.

How a parameter is used depends on the code is implemented, which will be discussed below.

Role of parameters for validation

Icon

There are various data validation mechanisms in Rice/KFS:

  • Data dictionary-based validation
  • Document/business rules
  • Parameters

Data dictionary-based (see DictionaryValidationService) validation uses attribute metadata specified in the data dictionary file to perform elementary validations of a business object/document prior to persistence. For example, it is able to determine which attributes are required and whether they conform to a necessary format (e.g. all numbers), and to display error messages if they do not conform.

Document/business rules are full-fledged java classes that allow for very flexible validation rule logic. Rules have access to all Spring services, giving them a wide range of computational power. In fact, document/business rules use parameters to perform some of its validation.

Parameters are ideal when functional specifications require that a value be in a list of allowed values (or not on a list of denied values). That is, parameters work extremely well for straightforward matching. However, institutions may desire to do the matching logic, but use a different list of values. Parameter-based validation allows them to change the list of values without revising code.

Compound Parameters

Because of the data model, a parameter (i.e. a row in SH_PARM_T) may represent either a list of allowed values or a list of denied values.   To provide flexibility, one allowed and one deny constraining/constrained parameters can be logically combined to form a compound parameter. The only restriction on the mappings for both parameters is that they may not share the same constraining value. For example, if the allow parameter is "AA=11;BB=2", then the deny parameter cannot have a mapping for either AA or BB.

For any constraining value and compound parameter:

  • if both parameters define a mapping for the constraining value, then error.
  • Otherwise, if both parameters do not define a mapping for a constraining value or have an empty mapping, then the validation will always succeed.
  • Otherwise, the constrained value must satisfy whichever parameter has a mapping for the constraining value.

Parameters in a compound parameter have the same namespace and detail type and have very similar names (see naming conventions).

KFS Parameter Service

The parameter table, SH_PARM_T, has 3 fields that comprise its primary key: namespace, detail type/component, and parameter name.  In KFS, most of the ParameterService's methods take in a java.lang.class object and a parameter name to specify a parameter.  The mapping mechanism is described in the next section.  This section will deal primarily with how to use parameters with the parameter service.

Non-existent parameters

Icon

If the parameter service attempts to retrieve a non-existent parameter, the parameter service will throw an exception. This allows for missing parameters to be easily detected during development and to avoid undefined behavior when parameters are missing.

The method ParameterService.parameterExists allows code to determine whether a parameter exists.

Parameter Service Class Arguments

As noted already, the parameter service takes in as arguments a class object instead of the namespace and detail type. The class object should be closely related to the processing being done.

For example:

  • if the code is accessing a parameter necessary to validate a document, then the document class should be passed in as the argument.
  • if the code is accessing a parameter related to running a batch step, then the step class should be passed in as the argument.

How a class is resolved into a namespace and detail type will be discussed below. For the purposes of discussion about how to use the parameter service, it is sufficient to understand that a class object is mapped to a namespace and detail type in a one-to-one mapping.

Using Parameters in Code

Using Parameters to Provide Configuration Values

Parameters can be used to store configuration values within the database, so that the application server does not need to be restarted to make the changes. This section will describe how developers should use the parameter service.

Using Indicator Parameters

Indicator parameters are analogous to configuration flags and are simple to use. For example:

Retrieving Configuration Values

The ParameterService methods named getParameterValue and getParameterValues are used to retrieve parameter values. There are two variations of each of these method, with slightly different uses.

  • getParameterValue(Class componentClass, String paramName): Returns the value is stored in the database for the parameter. This method does no parsing whatsoever of the parameter value and treats delimiter characters as regular text.
  • getParameterValue(Class componentClass, String paramName, String constrainingValue): Returns the constrained value for the constraining value. For the KFS default implementation, if there are multiple constrained values for a constraining value (i.e. a comma in the list of constrained values for the constraining value), then the method will return null. For example, if the parameter value were "AA=123;BB=222,333", then calling:
    •  getParameterValue(someClass, paramName, "AA") returns "123" because AA is mapped to exactly one value
    •  getParameterValue(someClass, paramName, "BB") returns null because BB is mapped to two values (222 and 333)
    •  getParameterValue(someClass, paramName, "CC") returns null because CC is not mapped to any value
  •  getParameterValues(Class componentClass, String paramName): Returns a java.util.List of the parameter's values, delimited using the semicolons in the value. For example:
    •  If the parameter value is "A", then a list containing only "A" is returned.
    •  If the parameter value is "A;B;C", then a list containing only "A", "B", and "C" is returned.
    •  If the parameter value is AA=123;BB=222,333, then a list containing only "AA=123" and "BB=222,333" is returned (the comma delimiters are ignored).
  •  getParameterValues(Class componentClass, String paramName, String constrainingValue): Returns a java.util.List of constrained values for the constraining value. For example: if the parameter value were "AA=123;BB=222,333", then calling:
    •  getParameterValue(someClass, paramName, "AA") returns a list with only "123" because AA is mapped to exactly one value
    •  getParameterValue(someClass, paramName, "BB") returns a list with only "222" and "333" because BB is mapped to two values
    •  getParameterValue(someClass, paramName, "CC") returns an empty list because "CC" is not mapped to anything

Using Parameters for Validation

The ParameterService has many methods that return ParameterEvaluator objects. The evaluator is a wrapper around a parameter object to evaluate whether a value passes validation. The following are the primary methods that retrieve evaluator objects:

  • getParameterEvaluator(Class componentClass, String parameterName)
  • getParameterEvaluator(Class componentClass, String parameterName, String constrainedValue)
  • getParameterEvaluator(Class componentClass, String allowParameterName, String denyParameterName, String constrainingValue, String constrainedValue)

There are other methods. See javadocs for more information.

The meaning of the above method arguments are as follows:

  • componentClass: the class that maps to a namespace and detail type
  • parameterName: the name of the parameter
  • constrainedValue: the value to validate (e.g. a value coming from a form).
  • allowParameterName: the name of the allow parameter in a compound parameter.
  • denyParameterName: the name of the deny parameter in a compound parameter.
Parameter Evaluators

Parameter evaluators are wrappers around a parameter BO that facilitate the evaluation of whether a constrained value satisfies the conditions of the parameter. Constrained values need to be set within the evaluator, either by calling a ParameterService method that takes in the constrained value or calling ParameterEvaluator.setConstrainedValue. Parameter evaluators have two main methods:

  • evaluationSucceeds(): returns whether the constrained value already set into the evaluator meets the condition of the parameter
  • evaluateAndAddError(...): calls evaluationSucceeds and if the constrained value does not satisfy the parameter, an error is added into the ErrorMap.

This code sample demonstrates how to use parameter evaluators' evaluationSucceeds method.

In the above sample, "DisbursementVoucherDocument.class" represents the component class for the parameter. "NONEMPLOYEE_TRAVEL_PAYMENT_REASONS" is the parameter name. "disbursementVoucherDocument.getDvPayeeDetail().getDisbVchrPaymentReasonCode() represents the constrained value to see if it satisfies the constraint specified by the parameter.

This following code sample demonstrates how to use a compound parameter and the evaluateAndAddError(...) method.

In the above sample, the first document.getClass() represents the component class for the parameter. "VALID_DOCUMENTATION_LOCATIONS_BY_PAYMENT_REASON" and "INVALID_DOCUMENTATION_LOCATIONS_BY_PAYMENT_REASON" represent the allow and deny parameter of the compound parameter. "document.getDvPayeeDetail().getDisbVchrPaymentReasonCode()" is the constraining value. "documentationLocationCode" is the constrained value. If there's an error, the framework will highlight the "disbursementVoucherDocumentationLocationCode" attribute on the document, and uses the DD to help build the error text using the DD entry for document.getClass() and the attribute name of "disbursementVoucherDocumentationLocationCode".

KFS Parameter Namespace and Component Resolution

This section will describe how the KFS parameter service maps a class object to a namespace and detail type code.  This will allow developers to determine which parameter is associated with a document, step, business object, etc and to determine what the primary key values of a new parameter should be.

Namespace Resolution

The namespace is resolved using the following rules in the following order (see ParameterServiceImpl.getNamespace(...):

  1. If the class is annotated with the org.kuali.kfs.service.impl.ParameterConstants.NAMESPACE annotation, then the namespace is whatever's defined as the annotation parameter.
  2. Otherwise, if the package name managed by a module Spring bean (i.e. the bean is an instance of org.kuali.core.KualiModule) is a prefix of the class' package, then the namespace will be the code of the module prefixed by "KFS-".  For example, the following is part of the GL Spring bean definition. If we pass in a class object for org.kuali.module.gl.batch.ScrubberStep, org.kuali.module.gl, managed by the glModule bean, is a prefix of org.kuali.module.gl.batch. The GL module code is GL, so the namespace returned is "KFS-GL".
    Simplified GL module bean definition from KualiSpringBeansGl.xml
  3. Otherwise, if the fully qualified class name begins with org.kuali.core, then the namespace is "KR-NS", which is primarily used for core Rice parameters.
  4. Otherwise, if the fully qualified class name begins with org.kuali.kfs, then the namespace is "KFS-SY", which is primarily used for KFS Nervous System parameters.
  5. Otherwise, it's an error.

Detail Type / Component Resolution

The detail type code is resolved using the following rules, in the following order:

  1. If the class is annotated with the org.kuali.kfs.service.impl.ParameterConstants.COMPONENT annotation, then the detail type is whatever's defined as the annotation parameter.
  2. Otherwise, if the class is assignable from the TransactionalDocument interface, then the detail type is the simple name of the class with all instances of the "Document" string removed. For example, the InternalBillingDocument class would have a detail type of "InternalBilling".
  3. Otherwise, if the class is assignable from the BusinessObject or the Step interfaces, then the detail type is the simple class name.
  4. Otherwise, it's an error.

Runtime Parameter Specification

An advantage of this method of resolution is to allow for the runtime resolution of a parameter based on the type of the document/step/etc being validated. For example, assume that for all accounting documents, there is a list of valid object codes. In the following hypothetical rule methods, which validates a document's accounting line to ensure that the object code is valid, we see that using runtime parameter specification results in much shorter and cleaner code.

The disadvantage is that developers need to be careful to ensure that all of the necessary parameters exist depending on all of the possible classes that are passed in to retrieve a parameter evaluator.

Runtime parameter specification

Static parameter specification

KFS Parameter Naming Conventions

The parameter names used within KFS generally follow these conventions:

  • Words are not abbreviated.
  • Underscores separate words (as opposed to spaces or camelCaps).
  • The list of valid values for component/detailed type is built from what's actually in SH_PARM_DTL_TYP_T, the simple names of business objects, the workflow document type names specified in the data dictionary, and the names of batch steps in spring.
  • Entities are referred to by the same name under which they are listed in the component/detailed type lookup (substituting underscores for case changes).
  • Parameter names avoid the use of the words VALID, INVALID, ALLOW, DENY, and RESTRICTED, unless otherwise specified below. The constraint column should account for that information.
  • The _GROUP suffix on parameters refer to workgroups.
  • Parameters that can have a value of Y or N should have a suffix of _IND.  (e.g. SHOW_CONTINUATION_ACCOUNT_WARNING_FISCAL_OFFICERS_IND.)
  • When defining restrictions on one value (the constrained value) based on another value (the constraining value), i.e. creating a compound rule, the terms VALID and INVALID are used to distinguish between the allow and deny parameters. But, we also have examples where INCLUDE and EXCLUDE make more sense, and one case of even more custom naming. Users should still be able to find all of these compound rules by search for name like *_BY_*. The format of the parameter values should be "constraining value 1=constrained value 1,constrained value 2;constraining value 2=constrained value 3,constrained value 4,constrained value 5;...".
    • <optional grouping prefix>-VALID_<name of entity associated with constrained field>BY<name of entity associated with constraining field>, e.g. VALID_DOCUMENTATION_LOCATIONS_BY_CAMPUS.
    • <optional grouping prefix>-INVALID_<name of entity associated with constrained field>BY<name of entity associated with constraining field>, e.g. INVALID_DOCUMENTATION_LOCATIONS_BY_CAMPUS.
  • When defining what the value of one field (determined field) should be, based on a the value of another field (determining field), you should create one parameter. The format of the parameter value should be "determining value 1=determined value 1;determining value 2=determined value 2;...".
    • <optional grouping prefix>-<name of entity associated with the value that is being derived>_BY_<name of entity associated with the value that is determining the value that is being derived>, e.g. NRA_TAX_FEDERAL-OBJECT_BY_INCOME_CLASS
  • When creating a run indicator of user parameter for a batch step, the name should be RUN_IND or USER. By default steps will run and a session will be created for the system user, so these are needed only to specify these when the step should not run or should run as another user.
Unable to render {include} The included page could not be found.
  • No labels