org.drools.compiler.builder.impl.CompositeKnowledgeBuilderImpl Maven / Gradle / Ivy
/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.drools.compiler.builder.impl;
import org.drools.compiler.compiler.BPMN2ProcessFactory;
import org.drools.compiler.compiler.PackageRegistry;
import org.drools.compiler.lang.descr.AbstractClassTypeDeclarationDescr;
import org.drools.compiler.lang.descr.CompositePackageDescr;
import org.drools.compiler.lang.descr.EnumDeclarationDescr;
import org.drools.compiler.lang.descr.ImportDescr;
import org.drools.compiler.lang.descr.PackageDescr;
import org.drools.compiler.lang.descr.TypeDeclarationDescr;
import org.drools.core.builder.conf.impl.JaxbConfigurationImpl;
import org.drools.core.util.StringUtils;
import org.kie.api.io.Resource;
import org.kie.api.io.ResourceConfiguration;
import org.kie.api.io.ResourceType;
import org.kie.internal.builder.ChangeType;
import org.kie.internal.builder.CompositeKnowledgeBuilder;
import org.kie.internal.builder.ResourceChange;
import org.kie.internal.builder.ResourceChangeSet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class CompositeKnowledgeBuilderImpl implements CompositeKnowledgeBuilder {
private final KnowledgeBuilderImpl kBuilder;
private final Map> resourcesByType = new HashMap>();
private RuntimeException buildException = null;
public ResourceType currentType = null;
public CompositeKnowledgeBuilderImpl(KnowledgeBuilderImpl kBuilder) {
this.kBuilder = kBuilder;
}
public CompositeKnowledgeBuilder type(ResourceType type) {
currentType = type;
return this;
}
public CompositeKnowledgeBuilder add(Resource resource) {
if (currentType == null) {
throw new RuntimeException("You must declare the type of the resource");
}
return add(resource, currentType);
}
public CompositeKnowledgeBuilder add(Resource resource, ResourceType type) {
return add(resource, type, resource.getConfiguration());
}
public CompositeKnowledgeBuilder add(Resource resource, ResourceType type, ResourceChangeSet changes) {
return add(resource, type, resource.getConfiguration(), changes);
}
public CompositeKnowledgeBuilder add(Resource resource, ResourceType type, ResourceConfiguration configuration) {
return add(resource, type, configuration, null);
}
public CompositeKnowledgeBuilder add(Resource resource, ResourceType type, ResourceConfiguration configuration, ResourceChangeSet changes) {
ResourceDescr resourceDescr = new ResourceDescr(configuration, resource, changes);
List resourceDescrs = this.resourcesByType.get(type);
if (resourceDescrs == null) {
resourceDescrs = new ArrayList();
resourcesByType.put(type, resourceDescrs);
}
resourceDescrs.add(resourceDescr);
return this;
}
private List getResources() {
List resources = new ArrayList();
for (List resourceDescrs : resourcesByType.values()) {
for (ResourceDescr resourceDescr : resourceDescrs) {
resources.add(resourceDescr.resource);
}
}
return resources;
}
public void build() {
buildException = null;
kBuilder.registerBuildResources(getResources());
buildResources();
buildPackages();
buildOthers();
resourcesByType.clear();
if (buildException != null) {
throw buildException;
}
}
private void buildPackages() {
Collection packages = buildPackageDescr();
initPackageRegistries(packages);
normalizeTypeAnnotations( packages );
buildTypeDeclarations(packages);
buildEntryPoints( packages );
buildOtherDeclarations(packages);
normalizeRuleAnnotations( packages );
buildRules(packages);
}
private void normalizeTypeAnnotations( Collection packages ) {
for (CompositePackageDescr packageDescr : packages) {
kBuilder.normalizeTypeDeclarationAnnotations( packageDescr );
}
}
private void normalizeRuleAnnotations( Collection packages ) {
for (CompositePackageDescr packageDescr : packages) {
kBuilder.normalizeRuleAnnotations( packageDescr );
}
}
private void buildEntryPoints( Collection packages ) {
for (CompositePackageDescr packageDescr : packages) {
kBuilder.processEntryPointDeclarations(kBuilder.getPackageRegistry( packageDescr.getNamespace() ), packageDescr);
}
}
private void buildResources() {
buildResourceType(DSL_RESOURCE_BUILDER, ResourceType.DSL);
buildResourceType(DRF_RESOURCE_BUILDER, ResourceType.DRF);
buildResourceType(BPMN2_RESOURCE_BUILDER, ResourceType.BPMN2);
buildResourceType(PKG_RESOURCE_BUILDER, ResourceType.PKG);
buildResourceType(CHANGE_SET_RESOURCE_BUILDER, ResourceType.CHANGE_SET);
buildResourceType(XSD_RESOURCE_BUILDER, ResourceType.XSD);
buildResourceType(PMML_RESOURCE_BUILDER, ResourceType.PMML);
}
private void buildResourceType(ResourceBuilder resourceBuilder, ResourceType resourceType) {
List resourcesByType = this.resourcesByType.remove(resourceType);
if (resourcesByType != null) {
for (ResourceDescr resourceDescr : resourcesByType) {
try {
kBuilder.setAssetFilter(resourceDescr.getFilter());
resourceBuilder.build( kBuilder, resourceDescr );
} catch (RuntimeException e) {
if (buildException == null) {
buildException = e;
}
} catch (Exception e) {
if (buildException == null) {
buildException = new RuntimeException( e );
}
} finally{
kBuilder.setAssetFilter(null);
}
}
}
}
private interface ResourceBuilder {
void build(KnowledgeBuilderImpl kBuilder, ResourceDescr resourceDescr) throws Exception;
}
private static final ResourceBuilder DSL_RESOURCE_BUILDER = new ResourceBuilder() {
@Override
public void build( KnowledgeBuilderImpl kBuilder, ResourceDescr resourceDescr ) throws Exception {
kBuilder.addDsl( resourceDescr.resource );
}
};
private static final ResourceBuilder PMML_RESOURCE_BUILDER = new ResourceBuilder() {
@Override
public void build( KnowledgeBuilderImpl kBuilder, ResourceDescr resourceDescr ) throws Exception {
kBuilder.addPackageFromPMML(resourceDescr.resource, ResourceType.PMML, resourceDescr.configuration);
}
};
private static final ResourceBuilder XSD_RESOURCE_BUILDER = new ResourceBuilder() {
@Override
public void build( KnowledgeBuilderImpl kBuilder, ResourceDescr resourceDescr ) throws Exception {
if (resourceDescr.configuration instanceof JaxbConfigurationImpl) {
// if the xsd file doesn't have a jaxb configuration it doesn't belong to the kprojact and then can be skipped
kBuilder.addPackageFromXSD( resourceDescr.resource, (JaxbConfigurationImpl) resourceDescr.configuration );
}
}
};
private static final ResourceBuilder CHANGE_SET_RESOURCE_BUILDER = new ResourceBuilder() {
@Override
public void build( KnowledgeBuilderImpl kBuilder, ResourceDescr resourceDescr ) throws Exception {
kBuilder.addPackageFromChangeSet( resourceDescr.resource);
}
};
private static final ResourceBuilder PKG_RESOURCE_BUILDER = new ResourceBuilder() {
@Override
public void build( KnowledgeBuilderImpl kBuilder, ResourceDescr resourceDescr ) throws Exception {
kBuilder.addPackageFromInputStream(resourceDescr.resource );
}
};
private static final ResourceBuilder BPMN2_RESOURCE_BUILDER = new ResourceBuilder() {
@Override
public void build( KnowledgeBuilderImpl kBuilder, ResourceDescr resourceDescr ) throws Exception {
BPMN2ProcessFactory.configurePackageBuilder( kBuilder );
kBuilder.addProcessFromXml( resourceDescr.resource );
}
};
private static final ResourceBuilder DRF_RESOURCE_BUILDER = new ResourceBuilder() {
@Override
public void build( KnowledgeBuilderImpl kBuilder, ResourceDescr resourceDescr ) throws Exception {
kBuilder.addProcessFromXml(resourceDescr.resource);
}
};
private void buildOthers() {
try {
for (Map.Entry> entry : resourcesByType.entrySet()) {
for (ResourceDescr resourceDescr : entry.getValue()) {
kBuilder.setAssetFilter(resourceDescr.getFilter());
kBuilder.addPackageForExternalType(resourceDescr.resource, entry.getKey(), resourceDescr.configuration);
kBuilder.setAssetFilter(null);
}
}
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException( e );
}
}
private void buildOtherDeclarations(Collection packages) {
for (CompositePackageDescr packageDescr : packages) {
kBuilder.setAssetFilter(packageDescr.getFilter());
PackageRegistry pkgRegistry = kBuilder.getPackageRegistry(packageDescr.getNamespace());
kBuilder.processOtherDeclarations( pkgRegistry, packageDescr );
kBuilder.setAssetFilter(null);
}
}
private void buildRules(Collection packages) {
for (CompositePackageDescr packageDescr : packages) {
kBuilder.setAssetFilter(packageDescr.getFilter());
PackageRegistry pkgRegistry = kBuilder.getPackageRegistry(packageDescr.getNamespace());
kBuilder.compileAllRules(packageDescr, pkgRegistry);
kBuilder.setAssetFilter(null);
}
}
private void buildTypeDeclarations( Collection packages ) {
Map unprocesseableDescrs = new HashMap();
List unresolvedTypes = new ArrayList();
List unsortedDescrs = new ArrayList();
for (CompositePackageDescr packageDescr : packages) {
for (TypeDeclarationDescr typeDeclarationDescr : packageDescr.getTypeDeclarations()) {
unsortedDescrs.add( typeDeclarationDescr );
}
for (EnumDeclarationDescr enumDeclarationDescr : packageDescr.getEnumDeclarations()) {
unsortedDescrs.add( enumDeclarationDescr );
}
}
kBuilder.getTypeBuilder().processTypeDeclarations( packages, unsortedDescrs, unresolvedTypes, unprocesseableDescrs );
for ( CompositePackageDescr packageDescr : packages ) {
for ( ImportDescr importDescr : packageDescr.getImports() ) {
kBuilder.getPackageRegistry( packageDescr.getNamespace() ).addImport( importDescr );
}
}
}
private void initPackageRegistries(Collection packages) {
for ( CompositePackageDescr packageDescr : packages ) {
if ( kBuilder.getPackageRegistry( packageDescr.getName() ) == null ) {
if ( StringUtils.isEmpty(packageDescr.getName()) ) {
packageDescr.setName( kBuilder.getBuilderConfiguration().getDefaultPackageName() );
}
kBuilder.createPackageRegistry( packageDescr );
}
}
}
private Collection buildPackageDescr() {
Map packages = new HashMap();
buildResource(packages, ResourceType.DRL, DRL_TO_PKG_DESCR);
buildResource(packages, ResourceType.GDRL, DRL_TO_PKG_DESCR);
buildResource(packages, ResourceType.RDRL, DRL_TO_PKG_DESCR);
buildResource(packages, ResourceType.DESCR, DRL_TO_PKG_DESCR);
buildResource(packages, ResourceType.DSLR, DSLR_TO_PKG_DESCR);
buildResource(packages, ResourceType.RDSLR, DSLR_TO_PKG_DESCR);
buildResource(packages, ResourceType.XDRL, XML_TO_PKG_DESCR);
buildResource(packages, ResourceType.DTABLE, DTABLE_TO_PKG_DESCR);
buildResource(packages, ResourceType.SCARD, SCARD_TO_PKG_DESCR);
buildResource(packages, ResourceType.TDRL, DRL_TO_PKG_DESCR);
buildResource(packages, ResourceType.TEMPLATE, TEMPLATE_TO_PKG_DESCR);
buildResource(packages, ResourceType.GDST, GUIDED_DTABLE_TO_PKG_DESCR);
buildResource(packages, ResourceType.SCGD, GUIDED_SCARD_TO_PKG_DESCR);
this.resourcesByType.remove(ResourceType.DRT); // drt is a template for dtables but doesn't have to be built on its own
return packages.values();
}
private void buildResource(Map packages, ResourceType resourceType, ResourceToPkgDescrMapper mapper) {
List resourcesByType = this.resourcesByType.remove(resourceType);
if (resourcesByType != null) {
for (ResourceDescr resourceDescr : resourcesByType) {
try {
registerPackageDescr(resourceDescr, packages, resourceDescr.resource, mapper.map(kBuilder, resourceDescr));
} catch (RuntimeException e) {
if (buildException == null) {
buildException = e;
}
} catch (Exception e) {
if (buildException == null) {
buildException = new RuntimeException( e );
}
}
}
}
}
private void registerPackageDescr(ResourceDescr resourceDescr, Map packages, Resource resource, PackageDescr packageDescr) {
if (packageDescr != null) {
CompositePackageDescr compositePackageDescr = packages.get(packageDescr.getNamespace());
if (compositePackageDescr == null) {
compositePackageDescr = packageDescr instanceof CompositePackageDescr ?
( (CompositePackageDescr) packageDescr ) :
new CompositePackageDescr(resource, packageDescr);
packages.put(packageDescr.getNamespace(), compositePackageDescr);
} else {
compositePackageDescr.addPackageDescr(resource, packageDescr);
}
compositePackageDescr.addFilter( resourceDescr.getFilter() );
}
}
private static class ResourceDescr {
final Resource resource;
final ResourceConfiguration configuration;
final ResourceChangeSet changes;
final Map changeMap;
final ChangeType globalChangeType;
private ResourceDescr(ResourceConfiguration configuration, Resource resource, ResourceChangeSet changes) {
this.configuration = configuration;
this.resource = resource;
this.changes = changes;
if ( changes != null ) {
changeMap = new HashMap();
if (!changes.getChanges().isEmpty()) {
for ( ResourceChange c : changes.getChanges() ) {
changeMap.put( assetId( c.getType(), c.getName() ), c );
}
globalChangeType = null;
} else {
globalChangeType = changes.getChangeType();
}
} else {
changeMap = null;
globalChangeType = null;
}
}
public KnowledgeBuilderImpl.AssetFilter getFilter() {
return changeMap == null ? null : this.new ChangeSetAssetFilter();
}
private class ChangeSetAssetFilter implements KnowledgeBuilderImpl.AssetFilter {
@Override
public Action accept(ResourceChange.Type type, String pkgName, String assetName) {
if (globalChangeType != null) {
return toFilterAction( globalChangeType );
}
ResourceChange change = changeMap.get( assetId(type, assetName) );
return change != null ? toFilterAction( change.getChangeType() ) : Action.DO_NOTHING;
}
private Action toFilterAction( ChangeType changeType ) {
switch (changeType) {
case ADDED: return Action.ADD;
case REMOVED: return Action.REMOVE;
case UPDATED: return Action.UPDATE;
}
return Action.DO_NOTHING;
}
}
private String assetId(ResourceChange.Type type, String assetName) {
return type + "_" + assetName;
}
}
private interface ResourceToPkgDescrMapper {
PackageDescr map(KnowledgeBuilderImpl kBuilder, ResourceDescr resourceDescr) throws Exception;
}
private static final ResourceToPkgDescrMapper DRL_TO_PKG_DESCR = new ResourceToPkgDescrMapper() {
public PackageDescr map(KnowledgeBuilderImpl kBuilder, ResourceDescr resourceDescr) throws Exception {
return kBuilder.drlToPackageDescr(resourceDescr.resource);
}
};
private static final ResourceToPkgDescrMapper TEMPLATE_TO_PKG_DESCR = new ResourceToPkgDescrMapper() {
public PackageDescr map(KnowledgeBuilderImpl kBuilder, ResourceDescr resourceDescr) throws Exception {
return kBuilder.templateToPackageDescr( resourceDescr.resource);
}
};
private static final ResourceToPkgDescrMapper DSLR_TO_PKG_DESCR = new ResourceToPkgDescrMapper() {
public PackageDescr map(KnowledgeBuilderImpl kBuilder, ResourceDescr resourceDescr) throws Exception {
return kBuilder.dslrToPackageDescr(resourceDescr.resource);
}
};
private static final ResourceToPkgDescrMapper XML_TO_PKG_DESCR = new ResourceToPkgDescrMapper() {
public PackageDescr map(KnowledgeBuilderImpl kBuilder, ResourceDescr resourceDescr) throws Exception {
return kBuilder.xmlToPackageDescr(resourceDescr.resource);
}
};
private static final ResourceToPkgDescrMapper DTABLE_TO_PKG_DESCR = new ResourceToPkgDescrMapper() {
public PackageDescr map(KnowledgeBuilderImpl kBuilder, ResourceDescr resourceDescr) throws Exception {
return kBuilder.decisionTableToPackageDescr(resourceDescr.resource, resourceDescr.configuration);
}
};
private static final ResourceToPkgDescrMapper SCARD_TO_PKG_DESCR = new ResourceToPkgDescrMapper() {
public PackageDescr map(KnowledgeBuilderImpl kBuilder, ResourceDescr resourceDescr) throws Exception {
return kBuilder.scoreCardToPackageDescr(resourceDescr.resource, resourceDescr.configuration);
}
};
private static final ResourceToPkgDescrMapper GUIDED_DTABLE_TO_PKG_DESCR = new ResourceToPkgDescrMapper() {
public PackageDescr map(KnowledgeBuilderImpl kBuilder, ResourceDescr resourceDescr) throws Exception {
return kBuilder.guidedDecisionTableToPackageDescr(resourceDescr.resource);
}
};
private static final ResourceToPkgDescrMapper GUIDED_SCARD_TO_PKG_DESCR = new ResourceToPkgDescrMapper() {
public PackageDescr map(KnowledgeBuilderImpl kBuilder, ResourceDescr resourceDescr) throws Exception {
return kBuilder.guidedScoreCardToPackageDescr(resourceDescr.resource);
}
};
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy