이 콘텐츠는 선택한 언어로 제공되지 않습니다.
Chapter 14. Functions
14.1. Functions 링크 복사링크가 클립보드에 복사되었습니다!
링크 복사링크가 클립보드에 복사되었습니다!
Functions are a way to put semantic code in a rule source file, as opposed to in normal Java classes. The main advantage of using functions in a rule is that you can keep the logic all in one place. You can change the functions as needed.
Functions are most useful for invoking actions on the consequence (
then
) part of a rule, especially if that particular action is used repeatedly.
14.2. Function Declaration Example 링크 복사링크가 클립보드에 복사되었습니다!
링크 복사링크가 클립보드에 복사되었습니다!
A typical function declaration looks like this:
function String hello(String name) { return "Hello "+name+"!"; }
function String hello(String name) {
return "Hello "+name+"!";
}
Note
Note that the
function
keyword is used, even though it's not technically part of Java. Parameters to the function are defined as for a method. You don't have to have parameters if they are not needed. The return type is defined just like in a regular method.
14.3. Function Declaration with Static Method Example 링크 복사링크가 클립보드에 복사되었습니다!
링크 복사링크가 클립보드에 복사되었습니다!
This example of a function declaration shows the static method in a helper class (
Foo.hello()
. JBoss Rules supports the use of function imports, so the following code is all you would need to enter the following:
import function my.package.Foo.hello
import function my.package.Foo.hello
14.4. Calling a Function Declaration Example 링크 복사링크가 클립보드에 복사되었습니다!
링크 복사링크가 클립보드에 복사되었습니다!
Irrespective of the way the function is defined or imported, you use a function by calling it by its name, in the consequence or inside a semantic code block. This is shown below:
14.5. Type Declarations 링크 복사링크가 클립보드에 복사되었습니다!
링크 복사링크가 클립보드에 복사되었습니다!
Type declarations have two main goals in the rules engine: to allow the declaration of new types, and to allow the declaration of metadata for types.
14.6. Type Declaration Roles 링크 복사링크가 클립보드에 복사되었습니다!
링크 복사링크가 클립보드에 복사되었습니다!
Role | Description |
---|---|
Declaring new types |
JBoss Rules out of the box with plain Java objects as facts. However, should a user wish to define the model directly to the rules engine, they can do so by declaring a new type. This can also be used when there is a domain model already built, but the user wants to complement this model with additional entities that are used mainly during the reasoning process.
|
Declaring metadata |
Facts may have meta information associated to them. Examples of meta information include any kind of data that is not represented by the fact attributes and is consistent among all instances of that fact type. This meta information may be queried at runtime by the engine and used in the reasoning process.
|
14.7. Declaring New Types 링크 복사링크가 클립보드에 복사되었습니다!
링크 복사링크가 클립보드에 복사되었습니다!
To declare a new type, the keyword
declare
is used, followed by the list of fields and the keyword end
. A new fact must have a list of fields, otherwise the engine will look for an existing fact class in the classpath and raise an error if not found.
14.8. Declaring a New Fact Type Example 링크 복사링크가 클립보드에 복사되었습니다!
링크 복사링크가 클립보드에 복사되었습니다!
In this example, a new fact type called
Address
is used. This fact type will have three attributes: number
, streetName
and city
. Each attribute has a type that can be any valid Java type, including any other class created by the user or other fact types previously declared:
declare Address number : int streetName : String city : String end
declare Address
number : int
streetName : String
city : String
end
14.9. Declaring a New Fact Type Additional Example 링크 복사링크가 클립보드에 복사되었습니다!
링크 복사링크가 클립보드에 복사되었습니다!
This fact type declaration uses a
Person
example. dateOfBirth
is of the type java.util.Date
(from the Java API) and address
is of the fact type Address.
declare Person name : String dateOfBirth : java.util.Date address : Address end
declare Person
name : String
dateOfBirth : java.util.Date
address : Address
end
14.10. Using Import Example 링크 복사링크가 클립보드에 복사되었습니다!
링크 복사링크가 클립보드에 복사되었습니다!
This example illustrates how to use the
import
feature to avoid he need to use fully qualified class names:
14.11. Generated Java Classes 링크 복사링크가 클립보드에 복사되었습니다!
링크 복사링크가 클립보드에 복사되었습니다!
When you declare a new fact type, JBoss Rules generate bytecode that implements a Java class representing the fact type. The generated Java class will be a one-to-one Java Bean mapping of the type definition.
14.12. Generated Java Class Example 링크 복사링크가 클립보드에 복사되었습니다!
링크 복사링크가 클립보드에 복사되었습니다!
This is an example of a generated Java class using the
Person
fact type:
14.13. Using the Declared Types in Rules Example 링크 복사링크가 클립보드에 복사되었습니다!
링크 복사링크가 클립보드에 복사되었습니다!
Since the generated class is a simple Java class, it can be used transparently in the rules like any other fact:
14.14. Declaring Metadata 링크 복사링크가 클립보드에 복사되었습니다!
링크 복사링크가 클립보드에 복사되었습니다!
Metadata may be assigned to several different constructions in JBoss Rules: fact types, fact attributes and rules. JBoss Rules uses the at sign ('@') to introduce metadata and it always uses the form:
@metadata_key( metadata_value )
@metadata_key( metadata_value )
The parenthesized metadata_value is optional.
14.15. Working with Metadata Attributes 링크 복사링크가 클립보드에 복사되었습니다!
링크 복사링크가 클립보드에 복사되었습니다!
JBoss Rules allows the declaration of any arbitrary metadata attribute, but some will have special meaning to the engine, while others are simply available for querying at runtime. JBoss Rules allows the declaration of metadata both for fact types and for fact attributes. Any metadata that is declared before the attributes of a fact type are assigned to the fact type, while metadata declared after an attribute are assigned to that particular attribute.
14.16. Declaring a Metadata Attribute with Fact Types Example 링크 복사링크가 클립보드에 복사되었습니다!
링크 복사링크가 클립보드에 복사되었습니다!
This is an example of declaring metadata attributes for fact types and attributes. There are two metadata items declared for the fact type (
@author
and @dateOfCreation
) and two more defined for the name attribute (@key
and @maxLength
). The @key
metadata has no required value, and so the parentheses and the value were omitted:
14.17. The @position Attribute 링크 복사링크가 클립보드에 복사되었습니다!
링크 복사링크가 클립보드에 복사되었습니다!
The
@position
attribute can be used to declare the position of a field, overriding the default declared order. This is used for positional constraints in patterns.
14.18. @position Example 링크 복사링크가 클립보드에 복사되었습니다!
링크 복사링크가 클립보드에 복사되었습니다!
This is what the @position attribute looks like in use:
14.19. Predefined Class Level Annotations 링크 복사링크가 클립보드에 복사되었습니다!
링크 복사링크가 클립보드에 복사되었습니다!
Annotation | Description |
---|---|
@role( <fact | event> ) |
This attribute can be used to assign roles to facts and events.
|
@typesafe( <boolean> ) |
By default, all type declarations are compiled with type safety enabled.
@typesafe( false ) provides a means to override this behavior by permitting a fall-back, to type unsafe evaluation where all constraints are generated as MVEL constraints and executed dynamically. This is useful when dealing with collections that do not have any generics or mixed type collections.
|
@timestamp( <attribute name> ) |
Creates a timestamp.
|
@duration( <attribute name> ) |
Sets a duration for the implementation of an attribute.
|
@expires( <time interval> ) |
Allows you to define when the attribute should expire.
|
@propertyChangeSupport |
Facts that implement support for property changes as defined in the Javabean spec can now be annotated so that the engine register itself to listen for changes on fact properties. .
|
@propertyReactive | Makes the type property reactive. |
14.20. @key Attribute Functions 링크 복사링크가 클립보드에 복사되었습니다!
링크 복사링크가 클립보드에 복사되었습니다!
Declaring an attribute as a key attribute has 2 major effects on generated types:
- The attribute will be used as a key identifier for the type, and as so, the generated class will implement the equals() and hashCode() methods taking the attribute into account when comparing instances of this type.
- JBoss Rules will generate a constructor using all the key attributes as parameters.
14.21. @key Declaration Example 링크 복사링크가 클립보드에 복사되었습니다!
링크 복사링크가 클립보드에 복사되었습니다!
This is an example of @key declarations for a type. JBoss Rules will generate equals() and hashCode() methods that will check the firstName and lastName attributes to determine if two instances of Person are equal to each other. It will not check the age attribute. It will also generate a constructor taking firstName and lastName as parameters:
14.22. Creating an Instance with the Key Instructor Example 링크 복사링크가 클립보드에 복사되었습니다!
링크 복사링크가 클립보드에 복사되었습니다!
This is what creating an instance using the key constructor looks like:
Person person = new Person( "John", "Doe" );
Person person = new Person( "John", "Doe" );
14.23. Positional Arguments 링크 복사링크가 클립보드에 복사되었습니다!
링크 복사링크가 클립보드에 복사되었습니다!
Patterns support positional arguments on type declarations and are defined by the
@position
attribute.
Positional arguments are when you don't need to specify the field name, as the position maps to a known named field. (That is, Person( name == "mark" ) can be rewritten as Person( "mark"; ).) The semicolon ';' is important so that the engine knows that everything before it is a positional argument. You can mix positional and named arguments on a pattern by using the semicolon ';' to separate them. Any variables used in a positional that have not yet been bound will be bound to the field that maps to that position.
14.24. Positional Argument Example 링크 복사링크가 클립보드에 복사되었습니다!
링크 복사링크가 클립보드에 복사되었습니다!
Observe the example below:
The default order is the declared order, but this can be overridden using @position
14.25. The @Position Annotation 링크 복사링크가 클립보드에 복사되었습니다!
링크 복사링크가 클립보드에 복사되었습니다!
The @Position annotation can be used to annotate original pojos on the classpath. Currently only fields on classes can be annotated. Inheritance of classes is supported, but not interfaces of methods.
14.26. Example Patterns 링크 복사링크가 클립보드에 복사되었습니다!
링크 복사링크가 클립보드에 복사되었습니다!
These example patterns have two constraints and a binding. The semicolon ';' is used to differentiate the positional section from the named argument section. Variables and literals and expressions using just literals are supported in positional arguments, but not variables:
Cheese( "stilton", "Cheese Shop", p; ) Cheese( "stilton", "Cheese Shop"; p : price ) Cheese( "stilton"; shop == "Cheese Shop", p : price ) Cheese( name == "stilton"; shop == "Cheese Shop", p : price )
Cheese( "stilton", "Cheese Shop", p; )
Cheese( "stilton", "Cheese Shop"; p : price )
Cheese( "stilton"; shop == "Cheese Shop", p : price )
Cheese( name == "stilton"; shop == "Cheese Shop", p : price )