org.drools.compiler.builder.impl.DeclaredClassBuilder 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.PackageRegistry;
import org.drools.compiler.compiler.TypeDeclarationError;
import org.drools.compiler.lang.descr.AbstractClassTypeDeclarationDescr;
import org.drools.compiler.lang.descr.TypeDeclarationDescr;
import org.drools.core.base.TypeResolver;
import org.drools.core.common.ProjectClassLoader;
import org.drools.core.factmodel.ClassBuilder;
import org.drools.core.factmodel.ClassDefinition;
import org.drools.core.rule.JavaDialectRuntimeData;
import org.drools.core.rule.TypeDeclaration;
import static org.drools.core.util.ClassUtils.convertClassToResourcePath;
public class DeclaredClassBuilder {
protected final KnowledgeBuilderImpl kbuilder;
public DeclaredClassBuilder( KnowledgeBuilderImpl kbuilder ) {
this.kbuilder = kbuilder;
}
public void generateBeanFromDefinition( AbstractClassTypeDeclarationDescr typeDescr,
TypeDeclaration type,
PackageRegistry pkgRegistry,
ClassDefinition def ) {
if ( type.isNovel() ) {
String fullName = typeDescr.getType().getFullName();
JavaDialectRuntimeData dialect = (JavaDialectRuntimeData) pkgRegistry.getDialectRuntimeRegistry().getDialectData("java");
if ( ensureJavaTypeConsistency( typeDescr, def, pkgRegistry.getTypeResolver() ) ) {
switch ( type.getKind() ) {
case TRAIT:
try {
buildClass( def, fullName, dialect, this.kbuilder.getBuilderConfiguration().getClassBuilderFactory().getTraitBuilder(), pkgRegistry );
} catch ( Exception e ) {
e.printStackTrace();
this.kbuilder.addBuilderResult( new TypeDeclarationError( typeDescr,
"Unable to compile declared trait " + fullName +
": " + e.getMessage() + ";" ) );
}
break;
case ENUM:
try {
buildClass( def, fullName, dialect, this.kbuilder.getBuilderConfiguration().getClassBuilderFactory().getEnumClassBuilder(), pkgRegistry );
} catch ( Exception e ) {
e.printStackTrace();
this.kbuilder.addBuilderResult( new TypeDeclarationError( typeDescr,
"Unable to compile declared enum " + fullName +
": " + e.getMessage() + ";" ) );
}
break;
case CLASS:
default:
try {
buildClass( def, fullName, dialect, this.kbuilder.getBuilderConfiguration().getClassBuilderFactory().getBeanClassBuilder(), pkgRegistry );
} catch ( Exception e ) {
e.printStackTrace();
this.kbuilder.addBuilderResult( new TypeDeclarationError( typeDescr,
"Unable to create a class for declared type " + fullName +
": " + e.getMessage() + ";" ) );
}
break;
}
}
}
}
private boolean ensureJavaTypeConsistency( AbstractClassTypeDeclarationDescr typeDescr, ClassDefinition def, TypeResolver typeResolver ) {
try {
if ( typeDescr instanceof TypeDeclarationDescr && ! ( (TypeDeclarationDescr) typeDescr ).isTrait()
&& typeResolver.resolveType( def.getSuperClass() ).isInterface() ) {
kbuilder.addBuilderResult( new TypeDeclarationError( typeDescr, "Interfaces cannot be used as super types of normal classes: " + def.getSuperClass() ) );
return false;
}
for ( String sup : def.getInterfaces() ) {
if ( !typeResolver.resolveType( sup ).isInterface() ) {
kbuilder.addBuilderResult( new TypeDeclarationError( typeDescr, "Non-interface type used as super interface : " + sup ) );
return false;
}
}
} catch ( ClassNotFoundException cnfe ) {
kbuilder.addBuilderResult( new TypeDeclarationError( typeDescr, "Unable to resolve parent type :" + cnfe.getMessage() ) );
return false;
}
return true;
}
protected void buildClass( ClassDefinition def, String fullName, JavaDialectRuntimeData dialect, ClassBuilder cb, PackageRegistry pkgRegistry ) throws Exception {
byte[] bytecode = cb.buildClass(def, kbuilder.getRootClassLoader());
String resourceName = convertClassToResourcePath(fullName);
dialect.putClassDefinition( resourceName, bytecode );
if (kbuilder.getKnowledgeBase() != null) {
Class> clazz = kbuilder.getKnowledgeBase().registerAndLoadTypeDefinition(fullName, bytecode);
pkgRegistry.getTypeResolver().registerClass( fullName, clazz );
} else {
if (kbuilder.getRootClassLoader() instanceof ProjectClassLoader ) {
Class> clazz = ((ProjectClassLoader) kbuilder.getRootClassLoader()).defineClass(fullName, resourceName, bytecode);
pkgRegistry.getTypeResolver().registerClass( fullName, clazz );
} else {
dialect.write(resourceName, bytecode);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy