Skip to main content
Pentaho Documentation

Refinement

pentaho.type.Refinement

A refinement type represents a refinement of a representation type.

Representation types

Representation types are the types that contribute to an instance's implementation, or representation, and thus define its behavior. Instances are created by the instance constructors of concrete representation types.

The representation types of this system are pentaho.type.Element and pentaho.type.List and its subtypes.

Refinement types

On the contrary, refinement types are intrinsically abstract and never create instances. Refinement types are also never the base types of types that do create instances.

A refinement type reduces the set of valid instances of the associated representation type, by requiring these to satisfy additional conditions. The valid instances of the refinement type are a subset of the valid instances of its representation type. It follows that, conceptually, a refinement type is an abstract subtype of its (usually concrete) representation type.

A refinement type can be used wherever its representation type can be:

  1. As the value type of a property
  2. As the element type of a list

Besides supporting refined validation, refinement types are also useful to enable more refined type configuration.

Instance interface

The instance interface of a refinement type, represented by this class, is meaningless.

The fact that an instance constructor exists in this system is a matter of uniformity and convenience.

Calling the instance constructor actually calls the representation type's instance constructor under the hood, and returns a direct instance of it instead.

Attributes of refinement types

A refinement type is a Value type and, as such, metadata can be specified for it.

Conveniently, inheritable metadata attributes of a refinement type default to the value of the same attributes of its representation type.

The inheritable metadata attributes are label, description, category, helpUrl, isBrowsable, isAdvanced, ordinal and defaultView,

Although the styleClass attribute is not inheritable, the value of inheritedStyleClasses of the representation type is included in the value of inheritedStyleClasses of the refinement type.

Although, conceptually, a refinement type is always abstract, the refinement type's isAbstract attribute, instead, more usefully indicates whether its representation type is abstract or not.

Defining a refinement type

To define a refinement type, call the refine method of the representation type's instance constructor.

An existing refinement type can be further refined simply by calling its pentaho.type.Refinement.extend method.

There are two ways to specify the additional validation constraints of a refinement type:

  1. Override the validateInstance method and perform arbitrary validation.
  2. Mix any number of refinement facets into the refinement type, using property facets, and specify the configuration attributes these define.

The latter is the preferred method since the configuration attributes defined by refinement facets can be used elsewhere. For example, to add a UI control to directly constrain input values.

Examples

In the following example, the refinement type PositiveNumber is defined using the validateInstance method:

define(["module", "pentaho/type/ValidationError"], function(module, ValidationError) {

  // return type factory
  return function(context) {

    // Get the representation type's instance constructor
    var Number = context.get("number");

    // Call its refine method and return the
    // newly created refinement type's instance constructor
    return Number.refine("my.PositiveNumber", {
      type: {
        id: module.id,
        label: "Positive number",

        validateInstance: function(num) {
          var errors = this.base(num);
          if(!errors) {
            if(num <= 0) errors = [new ValidationError("Not a positive number.")];
          }
          return errors;
        }
      }
    });
  };

});

In the following, the same refinement type, PositiveNumber, is defined using the refinement facet method instead, making use of the provided refinement facet mixin, pentaho.type.facets.OrdinalDomain:

define(["module"], function(module) {

  // return type factory
  return function(context) {

    // Get the representation type's instance constructor
    var Number = context.get("number");

    // Call its refine method and return the
    // newly created refinement type's instance constructor
    return Number.refine("my.PositiveNumber", {
      type: {
        id: module.id,
        label: "Positive number",

        // Mixin desired refinement facets
        facets: ["OrdinalDomain"],

        // Configure facet attributes
        min: 0,
        minInclusive: false
      }
    });
  };

});

Refinement types can also be defined inline, as the following example shows:

define(["module"], function(module) {

  // return type factory
  return function(context) {

    // Get the base type's instance constructor
    var Complex = context.get("complex");

    // Define a complex type
    return Complex.extend({
      type: {
        id: module.id,
        label: "My Product",

        props: [
          {
            name:  "id",
            label: "Product Id",
            type:  "string",
            isRequired: true
          },
          {
            name:  "price",
            label: "Product Unit Price",
            type: {
              base:   "refinement",
              of:     "number",
              facets: ["OrdinalDomain"],
              min:    0
            },
            isRequired: true
          }
        ]
      }
    });
  };

});

AMD Module

require(["pentaho/type/refinement"], function(Refinement) { /* code goes here */ });

See also:  https://en.wikipedia.org/wiki/Refinement_(computing)#Refinement_types

Constructor

Name Description
new Refinement()

The constructor of a refinement type always returns instances of the representation type.

Classes

Name Summary
Type

The type class of refinement types.

Methods

Name Description
extend(name, instSpec, classSpec, keyArgs) : Class.<pentaho.type.Refinement>
 
Static

Creates a subtype of this one.

Constructor Details

new Refinement()

The constructor of a refinement type always returns instances of the representation type.

Source: javascript/web/pentaho/type/refinement.js, line 49

See also:  https://en.wikipedia.org/wiki/Refinement_(computing)#Refinement_types

Methods Details

extend(name, instSpec, classSpec, keyArgs) : Class.<pentaho.type.Refinement>
 
Static

Creates a subtype of this one.

For more information on class extension, in general, see pentaho.lang.Base.extend.

Source: javascript/web/pentaho/type/refinement.js, line 718

Parameters:
Name Default Value Summary
name : string
 
Optional

The name of the created class; used for debugging purposes.

instSpec : Object
 
Optional

The refinement type specification.

classSpec : Object
 
Optional

The static specification.

keyArgs : Object
 
Optional

The keyword arguments.

Returns:
Name Description
Class.<pentaho.type.Refinement>

The new refinement instance subclass.

See also:  pentaho.lang.Value.extend