The KnowledgeBuilder is responsible for taking source files, such as
a DRL file or an Excel file, and turning them into a Knowledge Package of
rule and process definitions which a Knowledge Base can consume. An object
of the class ResourceType
indicates the type of resource it is being
asked to build.
The ResourceFactory
provides capabilities to load resources from a
number of sources, such as Reader, ClassPath, URL, File, or ByteArray.
Binaries, such as decision tables (Excel .xls files), should not use a Reader based
resource handler, which is only suitable for text based resources.
The KnowlegeBuilder is created using the KnowledgeBuilderFactory.
A KnowledgeBuilder can be created using the default configuration.
Example 3.1. Creating a new KnowledgeBuilder
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
A configuration can be created using the KnowledgeBuilderFactory
.
This allows the behavior of the Knowledge Builder to be modified. The most
common usage is to provide a custom class loader so that the KnowledgeBuilder
object can resolve classes that are not in the default classpath. The first parameter
is for properties and is optional, i.e., it may be left null, in which case the
default options will be used. The options parameter can be used for things
like changing the dialect or registering new accumulator functions.
Example 3.2. Creating a new KnowledgeBuilder with a custom ClassLoader
KnowledgeBuilderConfiguration kbuilderConf = KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration(null, classLoader ); KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(kbuilderConf);
Resources of any type can be added iteratively. Below, a DRL file is added. Unlike Drools 4.0 Package Builder, the Knowledge Builder can now handle multiple namespaces, so you can just keep adding resources regardless of namespace.
Example 3.3. Adding DRL Resources
kbuilder.add( ResourceFactory.newFileResource( "/project/myrules.drl" ), ResourceType.DRL);
It is best practice to always check the hasErrors()
method after an
addition. You should not add more resources or retrieve the Knowledge Packages
if there are errors. getKnowledgePackages()
returns an empty list if
there are errors.
Example 3.4. Validating
if( kbuilder.hasErrors() ) { System.out.println( kbuilder.getErrors() ); return; }
When all the resources have been added and there are no errors the collection of Knowledge Packages can be retrieved. It is a Collection because there is one Knowledge Package per package namespace. These Knowledge Packages are serializable and often used as a unit of deployment.
Example 3.5. Getting the KnowledgePackages
Collection<KnowledgePackage> kpkgs = kbuilder.getKnowledgePackages();
The final example puts it all together.
Example 3.6. Putting it all together
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); if( kbuilder.hasErrors() ) { System.out.println( kbuilder.getErrors() ); return; } KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); kbuilder.add( ResourceFactory.newFileResource( "/project/myrules1.drl" ), ResourceType.DRL); kbuilder.add( ResourceFactory.newFileResource( "/project/myrules2.drl" ), ResourceType.DRL); if( kbuilder.hasErrors() ) { System.out.println( kbuilder.getErrors() ); return; } Collection<KnowledgePackage> kpkgs = kbuilder.getKnowledgePackages();
Instead of adding the resources to create definitions programmatically it is also possible to do it by configuration, via the ChangeSet XML. The simple XML file supports three elements: add, remove, and modify, each of which has a sequence of <resource> subelements defining a configuration entity. The following XML schema is not normative and intended for illustration only.
Example 3.7. XML Schema for ChangeSet XML (not normative)
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://drools.org/drools-5.0/change-set" targetNamespace="http://drools.org/drools-5.0/change-set"> <xs:element name="change-set" type="ChangeSet"/> <xs:complexType name="ChangeSet"> <xs:choice maxOccurs="unbounded"> <xs:element name="add" type="Operation"/> <xs:element name="remove" type="Operation"/> <xs:element name="modify" type="Operation"/> </xs:choice> </xs:complexType> <xs:complexType name="Operation"> <xs:sequence> <xs:element name="resource" type="Resource" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:complexType name="Resource"> <xs:sequence> <xs:element name="decisiontable-conf" type="DecTabConf" minOccurs="0"/> </xs:sequence> <xs:attribute name="source" type="xs:string"/> <xs:attribute name="type" type="ResourceType"/> </xs:complexType> <xs:complexType name="DecTabConf"> <xs:attribute name="input-type" type="DecTabInpType"/> <xs:attribute name="worksheet-name" type="xs:string" use="optional"/> </xs:complexType> <xs:simpleType name="ResourceType"> <xs:restriction base="xs:string"> <xs:enumeration value="DRL"/> <xs:enumeration value="XDRL"/> <xs:enumeration value="DSL"/> <xs:enumeration value="DSLR"/> <xs:enumeration value="DRF"/> <xs:enumeration value="DTABLE"/> <xs:enumeration value="PKG"/> <xs:enumeration value="BRL"/> <xs:enumeration value="CHANGE_SET"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="DecTabInpType"> <xs:restriction base="xs:string"> <xs:enumeration value="XLS"/> <xs:enumeration value="CSV"/> </xs:restriction> </xs:simpleType> </xs:schema>
Currently only the add element is supported, but the others will be implemented to support iterative changes. The following example loads a single DRL file.
Example 3.8. Simple ChangeSet XML
<change-set xmlns='http://drools.org/drools-5.0/change-set' xmlns:xs='http://www.w3.org/2001/XMLSchema-instance' xs:schemaLocation='http://drools.org/drools-5.0/change-set.xsd' > <add> <resource source='file:/project/myrules.drl' type='DRL' /> </add> </change-set>
Notice the file:
prefix, which signifies the protocol for the
resource. The Change Set supports all the protocols provided by
java.net.URL, such as "file" and "http", as well as an additional
"classpath". Currently the type attribute must always be specified for a
resource, as it is not inferred from the file name extension. Using the
ClassPath resource loader in Java allows you to specify the Class Loader to
be used to locate the resource but this is not possible from XML. Instead,
the Class Loader will default to the one used by the Knowledge Builder
unless the ChangeSet XML is itself loaded by the ClassPath resource, in
which case it will use the Class Loader specified for that resource.
Currently you still need to use the API to load that ChangeSet, but we will add support for containers such as Spring in the future, so that the process of creating a Knowledge Base can be done completely by XML configuration. Loading resources using an XML file couldn't be simpler, as it's just another resource type.
Example 3.9. Loading the ChangeSet XML
kbuilder.add( ResourceFactory.newUrlResource( url ), ResourceType.CHANGE_SET );
ChangeSets can include any number of resources, and they even support additional configuration information, which currently is only needed for decision tables. Below, the example is expanded to load rules from a http URL location, and an Excel decision table from the classpath.
Example 3.10. ChangeSet XML with resource configuration
<change-set xmlns='http://drools.org/drools-5.0/change-set' xmlns:xs='http://www.w3.org/2001/XMLSchema-instance' xs:schemaLocation='http://drools.org/drools-5.0/change-set.xsd' > <add> <resource source='http:org/domain/myrules.drl' type='DRL' /> <resource source='classpath:data/IntegrationExampleTest.xls' type="DTABLE"> <decisiontable-conf input-type="XLS" worksheet-name="Tables_2" /> </resource> </add> </change-set>
The ChangeSet is especially useful when working with a Knowledge Agent, as it allows for change notification and automatic rebuilding of the Knowledge Base, which is covered in more detail in the section on the Knowledge Agent, under Deploying.
Directories can also be specified, to add all resources in that folder. Currently it is expected that all resources in that folder are of the same type. If you use the Knowledge Agent it will provide a continous scanning for added, modified or removed resources and rebuild the cached Knowledge Base. The KnowledgeAgent provides more information on this.
Example 3.11. ChangeSet XML which adds a directory's contents
<change-set xmlns='http://drools.org/drools-5.0/change-set' xmlns:xs='http://www.w3.org/2001/XMLSchema-instance' xs:schemaLocation='http://drools.org/drools-5.0/change-set.xsd' > <add> <resource source='file:/projects/myproject/myrules' type='DRL' /> </add> </change-set>