Skip to content

Commit

Permalink
[DROOLS-1536] allow to cache compiler subcomponents into the Knowledg…
Browse files Browse the repository at this point in the history
…eBuilderImpl (apache#1229)
  • Loading branch information
mariofusco committed Apr 27, 2017
1 parent 92cdb06 commit 4ae9c55
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 23 deletions.
Expand Up @@ -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;
Expand Down Expand Up @@ -210,6 +211,8 @@ public class KnowledgeBuilderImpl implements KnowledgeBuilder {

private final TypeDeclarationBuilder typeBuilder;

private Map<String, Object> builderCache;

/**
* Use this when package is starting from scratch.
*/
Expand Down Expand Up @@ -2441,4 +2444,15 @@ private void normalizeStrictAnnotation(TypeResolver typeResolver, AnnotationDesc
"Unknown annotation: " + annotationDescr.getName()));
}
}

private Map<String, Object> getBuilderCache() {
if (builderCache == null) {
builderCache = new HashMap<>();
}
return builderCache;
}

public <T> T getCachedOrCreate( String key, Supplier<T> creator ) {
return (T) getBuilderCache().computeIfAbsent( key, k -> creator.get() );
}
}
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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() {
Expand All @@ -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 ) );
Expand All @@ -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<String, String> extensionProperties = new HashMap<>();
( (KnowledgeBuilderImpl) kbuilder ).getBuilderConfiguration().getChainedProperties()
kbuilderImpl.getBuilderConfiguration().getChainedProperties()
.mapStartsWith(extensionProperties, DMN_EXTENSION_REGISTER_PREFIX, false);
if( !extensionProperties.isEmpty() ) {
List<DMNExtensionRegister> extensionRegisters = new ArrayList<>();
try {
for (Map.Entry<String, String> 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
Expand Down

0 comments on commit 4ae9c55

Please sign in to comment.