diff --git a/drools-compiler/src/main/java/org/drools/compiler/builder/impl/KnowledgeBuilderImpl.java b/drools-compiler/src/main/java/org/drools/compiler/builder/impl/KnowledgeBuilderImpl.java index 4a5a1da4b38..e7bab184c2f 100644 --- a/drools-compiler/src/main/java/org/drools/compiler/builder/impl/KnowledgeBuilderImpl.java +++ b/drools-compiler/src/main/java/org/drools/compiler/builder/impl/KnowledgeBuilderImpl.java @@ -36,6 +36,7 @@ import java.util.Set; import java.util.Stack; import java.util.UUID; +import java.util.function.Supplier; import org.drools.compiler.compiler.AnnotationDeclarationError; import org.drools.compiler.compiler.BPMN2ProcessFactory; @@ -210,6 +211,8 @@ public class KnowledgeBuilderImpl implements KnowledgeBuilder { private final TypeDeclarationBuilder typeBuilder; + private Map builderCache; + /** * Use this when package is starting from scratch. */ @@ -2441,4 +2444,15 @@ private void normalizeStrictAnnotation(TypeResolver typeResolver, AnnotationDesc "Unknown annotation: " + annotationDescr.getName())); } } + + private Map getBuilderCache() { + if (builderCache == null) { + builderCache = new HashMap<>(); + } + return builderCache; + } + + public T getCachedOrCreate( String key, Supplier creator ) { + return (T) getBuilderCache().computeIfAbsent( key, k -> creator.get() ); + } } \ No newline at end of file diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/assembler/DMNAssemblerService.java b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/assembler/DMNAssemblerService.java index 14113b7a1b2..41de19eb46f 100644 --- a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/assembler/DMNAssemblerService.java +++ b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/assembler/DMNAssemblerService.java @@ -16,6 +16,11 @@ package org.kie.dmn.core.assembler; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import org.drools.compiler.builder.impl.KnowledgeBuilderImpl; import org.drools.compiler.compiler.PackageRegistry; import org.drools.compiler.lang.descr.PackageDescr; @@ -28,7 +33,6 @@ import org.kie.dmn.api.core.DMNModel; import org.kie.dmn.api.marshalling.v1_1.DMNExtensionRegister; import org.kie.dmn.core.api.DMNFactory; -import org.kie.dmn.core.compiler.DMNCompilerConfigurationImpl; import org.kie.dmn.core.impl.DMNKnowledgeBuilderError; import org.kie.dmn.core.impl.DMNPackageImpl; import org.kie.internal.assembler.KieAssemblerService; @@ -38,15 +42,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - public class DMNAssemblerService implements KieAssemblerService { private static final Logger logger = LoggerFactory.getLogger( DMNAssemblerService.class ); public static final String DMN_EXTENSION_REGISTER_PREFIX = "org.kie.dmn.marshaller.extension."; + public static final String DMN_COMPILER_CACHE_KEY = "DMN_COMPILER_CACHE_KEY"; @Override public ResourceType getResourceType() { @@ -56,13 +56,13 @@ public ResourceType getResourceType() { @Override public void addResource(KnowledgeBuilder kbuilder, Resource resource, ResourceType type, ResourceConfiguration configuration) throws Exception { - DMNCompiler dmnCompiler = getCompiler(kbuilder); + KnowledgeBuilderImpl kbuilderImpl = (KnowledgeBuilderImpl) kbuilder; + DMNCompiler dmnCompiler = kbuilderImpl.getCachedOrCreate( DMN_COMPILER_CACHE_KEY, () -> getCompiler( kbuilderImpl ) ); DMNModel model = dmnCompiler.compile(resource); if( model != null ) { String namespace = model.getNamespace(); - KnowledgeBuilderImpl kbuilderImpl = (KnowledgeBuilderImpl) kbuilder; PackageRegistry pkgReg = kbuilderImpl.getPackageRegistry( namespace ); if ( pkgReg == null ) { pkgReg = kbuilderImpl.newPackage( new PackageDescr( namespace ) ); @@ -77,47 +77,41 @@ public void addResource(KnowledgeBuilder kbuilder, Resource resource, ResourceTy rpkg.put(ResourceType.DMN, dmnpkg); } else { if ( dmnpkg.getModel( model.getName() ) != null ) { - ((KnowledgeBuilderImpl) kbuilder).addBuilderResult(new DMNKnowledgeBuilderError(ResultSeverity.ERROR, resource, namespace, "Duplicate model name " + model.getName() + " in namespace " + namespace)); + kbuilderImpl.addBuilderResult(new DMNKnowledgeBuilderError(ResultSeverity.ERROR, resource, namespace, "Duplicate model name " + model.getName() + " in namespace " + namespace)); logger.error( "Duplicate model name {} in namespace {}", model.getName(), namespace ); } } dmnpkg.addModel( model.getName(), model ); } else { - ((KnowledgeBuilderImpl) kbuilder).addBuilderResult(new DMNKnowledgeBuilderError(ResultSeverity.ERROR, resource, "Unable to compile DMN model for the resource")); + kbuilderImpl.addBuilderResult(new DMNKnowledgeBuilderError(ResultSeverity.ERROR, resource, "Unable to compile DMN model for the resource")); logger.error( "Unable to compile DMN model for resource {}", resource.getSourcePath() ); } } - private DMNCompiler getCompiler(KnowledgeBuilder kbuilder) { - // TODO currently because KieAssembler is a singleton it is not possible to cache the compiler inside this KieAssembler - DMNCompiler dmnCompiler; - + private DMNCompiler getCompiler(KnowledgeBuilderImpl kbuilderImpl) { Map extensionProperties = new HashMap<>(); - ( (KnowledgeBuilderImpl) kbuilder ).getBuilderConfiguration().getChainedProperties() + kbuilderImpl.getBuilderConfiguration().getChainedProperties() .mapStartsWith(extensionProperties, DMN_EXTENSION_REGISTER_PREFIX, false); if( !extensionProperties.isEmpty() ) { List extensionRegisters = new ArrayList<>(); try { for (Map.Entry extensionProperty : extensionProperties.entrySet()) { String extRegClassName = extensionProperty.getValue(); - DMNExtensionRegister extRegister = (DMNExtensionRegister) ((KnowledgeBuilderImpl) kbuilder).getRootClassLoader() + DMNExtensionRegister extRegister = (DMNExtensionRegister) kbuilderImpl.getRootClassLoader() .loadClass(extRegClassName).newInstance(); extensionRegisters.add(extRegister); } DMNCompilerConfiguration compilerConfig = DMNFactory.newCompilerConfiguration(); compilerConfig.addExtensions(extensionRegisters); - dmnCompiler = DMNFactory.newCompiler(compilerConfig); + return DMNFactory.newCompiler(compilerConfig); } catch(Exception e) { - ((KnowledgeBuilderImpl) kbuilder).addBuilderResult(new DMNKnowledgeBuilderError(ResultSeverity.WARNING, "Trying to load a non-existing extension element register "+e.getLocalizedMessage())); + kbuilderImpl.addBuilderResult(new DMNKnowledgeBuilderError(ResultSeverity.WARNING, "Trying to load a non-existing extension element register "+e.getLocalizedMessage())); logger.error( "Trying to load a non-existing extension element register {}", e.getLocalizedMessage(), e); - ((KnowledgeBuilderImpl) kbuilder).addBuilderResult(new DMNKnowledgeBuilderError(ResultSeverity.WARNING, "DMN Compiler configuration contained errors, fall-back using empty-configuration compiler.")); + kbuilderImpl.addBuilderResult(new DMNKnowledgeBuilderError(ResultSeverity.WARNING, "DMN Compiler configuration contained errors, fall-back using empty-configuration compiler.")); logger.warn( "DMN Compiler configuration contained errors, fall-back using empty-configuration compiler." ); - dmnCompiler = DMNFactory.newCompiler(); } - } else { - dmnCompiler = DMNFactory.newCompiler(); } - return dmnCompiler; + return DMNFactory.newCompiler(); } @Override