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:
- As the
value type
of a property - 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:
- Override the
validateInstance
method and perform arbitrary validation. - 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.Factory} 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.< 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.< Static | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Creates a subtype of this one. For more information on class extension, in general, see Source: javascript/web/pentaho/type/refinement.js, line 718
See also: pentaho.lang.Value.extend |