Skip to content

Commit

Permalink
rebased
Browse files Browse the repository at this point in the history
  • Loading branch information
evacchi committed Mar 27, 2019
1 parent 994fbea commit 6aef805
Show file tree
Hide file tree
Showing 20 changed files with 831 additions and 223 deletions.
26 changes: 26 additions & 0 deletions api/kie-api/src/main/java/org/kie/submarine/rules/DataSource.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.kie.submarine.rules;

import org.kie.api.runtime.rule.FactHandle;

public interface DataSource<T> {

FactHandle add(T object );

/**
* Updates the fact for which the given FactHandle was assigned with the new
* fact set as the second parameter in this method.
* It is also possible to optionally specify the set of properties that have been modified.
*
* @param handle the FactHandle for the fact to be updated.
* @param object the new value for the fact being updated.
*/
void update(FactHandle handle, T object);

/**
* Deletes the fact for which the given FactHandle was assigned
*
* @param handle the handle whose fact is to be retracted.
*/
void remove(FactHandle handle);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package org.kie.submarine.rules;

public interface RuleUnit<T> {
RuleUnitInstance<T> createInstance(T workingMemory);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.kie.submarine.rules;

public interface RuleUnitInstance<T> {
RuleUnit<T> unit();
void fire();
}
5 changes: 5 additions & 0 deletions api/kie-api/src/main/java/org/kie/submarine/rules/Unit.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package org.kie.submarine.rules;

public @interface Unit {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.kie.submarine.rules.impl;

import org.kie.submarine.rules.RuleUnit;

public abstract class AbstractRuleUnit<T> implements RuleUnit<T> {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package org.kie.submarine.rules.impl;

import java.lang.reflect.Field;

import org.kie.api.runtime.KieSession;
import org.kie.submarine.rules.RuleUnit;
import org.kie.submarine.rules.RuleUnitInstance;

public class AbstractRuleUnitInstance<T> implements RuleUnitInstance<T> {

private final T workingMemory;
private final RuleUnit<T> unit;
private final KieSession rt;

public AbstractRuleUnitInstance(RuleUnit<T> unit, T workingMemory, KieSession rt) {
this.unit = unit;
this.rt = rt;
this.workingMemory = workingMemory;
}

public void fire() {
magicReflectionThingie(rt, workingMemory);
rt.fireAllRules();
}

@Override
public RuleUnit<T> unit() {
return unit;
}

public T workingMemory() {
return workingMemory;
}

private void magicReflectionThingie(KieSession rt, T workingMemory) {
try {
for (Field f : workingMemory.getClass().getDeclaredFields()) {
f.setAccessible(true);
Object v = null;
v = f.get(workingMemory);
if (v instanceof ListDataSource) {
ListDataSource o = (ListDataSource) v;
o.drainInto(rt::insert);
}
}
} catch (IllegalAccessException e) {
throw new Error(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.kie.submarine.rules.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.function.Consumer;

import org.kie.api.runtime.rule.FactHandle;
import org.kie.submarine.rules.DataSource;

public class ListDataSource<T> implements DataSource<T> {
ArrayList<T> values = new ArrayList<>();

public FactHandle add(T t) {
values.add(t);
return null;
}

@Override
public void update(FactHandle handle, T object) {

}

@Override
public void remove(FactHandle handle) {

}

public void addAll(Collection<? extends T> ts) {
values.addAll(ts);
}

public void drainInto(Consumer<Object> sink) {
Iterator<T> iter = values.iterator();
while(iter.hasNext()) {
T t = iter.next();
sink.accept(t);
iter.remove();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,16 @@
import org.drools.compiler.kie.builder.impl.InternalKieModule;
import org.drools.compiler.kie.builder.impl.KieModuleKieProject;
import org.drools.compiler.kie.builder.impl.ResultsImpl;
import org.drools.compiler.kproject.ReleaseIdImpl;
import org.drools.compiler.kproject.models.KieBaseModelImpl;
import org.drools.core.util.Drools;
import org.drools.model.Model;
import org.drools.modelcompiler.CanonicalKieModule;
import org.kie.api.KieBase;
import org.kie.api.builder.Message;
import org.kie.api.builder.ReleaseId;
import org.kie.api.builder.model.KieBaseModel;
import org.kie.api.runtime.KieSession;
import org.kie.internal.builder.KnowledgeBuilder;
import org.kie.internal.jci.CompilationProblem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.joining;

import static org.drools.modelcompiler.CanonicalKieModule.MODEL_FILE;
import static org.drools.modelcompiler.CanonicalKieModule.MODEL_VERSION;
import static org.drools.modelcompiler.CanonicalKieModule.createFromClassLoader;
Expand All @@ -57,12 +49,12 @@ public class CanonicalModelKieProject extends KieModuleKieProject {
Logger logger = LoggerFactory.getLogger(CanonicalModelKieProject.class);

public static final String PROJECT_RUNTIME_CLASS = "org.drools.project.model.ProjectRuntime";
public static final String PROJECT_RUNTIME_RESOURCE_CLASS = PROJECT_RUNTIME_CLASS.replace( '.', '/' ) + ".class";
protected static final String PROJECT_RUNTIME_SOURCE = "src/main/java/" + PROJECT_RUNTIME_CLASS.replace( '.', '/' ) + ".java";
public static final String PROJECT_RUNTIME_RESOURCE_CLASS = PROJECT_RUNTIME_CLASS.replace('.', '/') + ".class";
protected static final String PROJECT_RUNTIME_SOURCE = "src/main/java/" + PROJECT_RUNTIME_CLASS.replace('.', '/') + ".java";

public static final String PROJECT_MODEL_CLASS = "org.drools.project.model.ProjectModel";
public static final String PROJECT_MODEL_RESOURCE_CLASS = PROJECT_MODEL_CLASS.replace( '.', '/' ) + ".class";
protected static final String PROJECT_MODEL_SOURCE = "src/main/java/" + PROJECT_MODEL_CLASS.replace( '.', '/' ) + ".java";
public static final String PROJECT_MODEL_RESOURCE_CLASS = PROJECT_MODEL_CLASS.replace('.', '/') + ".class";
protected static final String PROJECT_MODEL_SOURCE = "src/main/java/" + PROJECT_MODEL_CLASS.replace('.', '/') + ".java";

private final boolean isPattern;

Expand All @@ -73,13 +65,13 @@ public static BiFunction<InternalKieModule, ClassLoader, KieModuleKieProject> cr
protected List<ModelBuilderImpl> modelBuilders = new ArrayList<>();

public CanonicalModelKieProject(boolean isPattern, InternalKieModule kieModule, ClassLoader classLoader) {
super(kieModule instanceof CanonicalKieModule ? kieModule : createFromClassLoader( classLoader, kieModule ), classLoader);
super(kieModule instanceof CanonicalKieModule ? kieModule : createFromClassLoader(classLoader, kieModule), classLoader);
this.isPattern = isPattern;
}

@Override
protected KnowledgeBuilder createKnowledgeBuilder(KieBaseModelImpl kBaseModel, InternalKieModule kModule) {
ModelBuilderImpl modelBuilder = new ModelBuilderImpl(getBuilderConfiguration( kBaseModel, kModule ), isPattern);
ModelBuilderImpl modelBuilder = new ModelBuilderImpl(getBuilderConfiguration(kBaseModel, kModule), isPattern);
modelBuilders.add(modelBuilder);
return modelBuilder;
}
Expand All @@ -92,131 +84,58 @@ public void writeProjectOutput(MemoryFileSystem trgMfs, ResultsImpl messages) {
List<String> sourceFiles = new ArrayList<>();

for (ModelBuilderImpl modelBuilder : modelBuilders) {
final ModelWriter.Result result = modelWriter.writeModel( srcMfs, modelBuilder.getPackageModels() );
final ModelWriter.Result result = modelWriter.writeModel(srcMfs, modelBuilder.getPackageModels());
modelFiles.addAll(result.getModelFiles());
sourceFiles.addAll(result.getSources());
}

KieModuleModelMethod modelMethod = new KieModuleModelMethod(kBaseModels);
if (!sourceFiles.isEmpty()) {
String[] sources = sourceFiles.toArray( new String[sourceFiles.size()+2] );
String[] sources = sourceFiles.toArray(new String[sourceFiles.size() + 2]);

new ModelSourceClass(
getInternalKieModule().getReleaseId(),
modelMethod,
modelFiles)
.write(srcMfs);

String modelSourceClass = buildModelSourceClass(modelMethod, modelFiles);
logger.debug(modelSourceClass);
srcMfs.write(PROJECT_MODEL_SOURCE, modelSourceClass.getBytes());
sources[sources.length-2] = PROJECT_MODEL_SOURCE;
sources[sources.length - 2] = PROJECT_MODEL_SOURCE;

String projectSourceClass = buildProjectSourceClass(modelMethod);
String projectSourceClass = new ProjectSourceClass(modelMethod).generate();
logger.debug(projectSourceClass);
srcMfs.write( PROJECT_RUNTIME_SOURCE, projectSourceClass.getBytes());
sources[sources.length-1] = PROJECT_RUNTIME_SOURCE;
srcMfs.write(PROJECT_RUNTIME_SOURCE, projectSourceClass.getBytes());
sources[sources.length - 1] = PROJECT_RUNTIME_SOURCE;

CompilationResult res = getCompiler().compile(sources, srcMfs, trgMfs, getClassLoader());

Stream.of(res.getErrors()).collect(groupingBy( CompilationProblem::getFileName))
.forEach( (name, errors) -> {
errors.forEach( messages::addMessage );
File srcFile = srcMfs.getFile( name );
if ( srcFile instanceof MemoryFile ) {
String src = new String ( srcMfs.getFileContents( ( MemoryFile ) srcFile ) );
messages.addMessage( Message.Level.ERROR, name, "Java source of " + name + " in error:\n" + src);
Stream.of(res.getErrors()).collect(groupingBy(CompilationProblem::getFileName))
.forEach((name, errors) -> {
errors.forEach(messages::addMessage);
File srcFile = srcMfs.getFile(name);
if (srcFile instanceof MemoryFile) {
String src = new String(srcMfs.getFileContents((MemoryFile) srcFile));
messages.addMessage(Message.Level.ERROR, name, "Java source of " + name + " in error:\n" + src);
}
} );
});

for (CompilationProblem problem : res.getWarnings()) {
messages.addMessage(problem);
}
} else {
srcMfs.write(PROJECT_MODEL_SOURCE, buildModelSourceClass( modelMethod, modelFiles ).getBytes());
CompilationResult res = getCompiler().compile(new String[] { PROJECT_MODEL_SOURCE }, srcMfs, trgMfs, getClassLoader());
new ModelSourceClass(getInternalKieModule().getReleaseId(), modelMethod, modelFiles)
.write(srcMfs);
CompilationResult res = getCompiler().compile(new String[]{PROJECT_MODEL_SOURCE}, srcMfs, trgMfs, getClassLoader());
System.out.println(res.getErrors());
}

writeModelFile(modelFiles, trgMfs);
}

protected void writeModelFile( List<String> modelSources, MemoryFileSystem trgMfs) {
protected void writeModelFile(List<String> modelSources, MemoryFileSystem trgMfs) {
String pkgNames = MODEL_VERSION + Drools.getFullVersion() + "\n";
if(!modelSources.isEmpty()) {
pkgNames += modelSources.stream().collect( Collectors.joining("\n"));
if (!modelSources.isEmpty()) {
pkgNames += modelSources.stream().collect(Collectors.joining("\n"));
}
trgMfs.write( MODEL_FILE, pkgNames.getBytes() );
}

protected String buildModelSourceClass( KieModuleModelMethod modelMethod, List<String> modelSources ) {
ReleaseId releaseId = getInternalKieModule().getReleaseId();

StringBuilder sb = new StringBuilder();
sb.append(
"package org.drools.project.model;\n" +
"\n" +
"import " + Model.class.getCanonicalName() + ";\n" +
"import " + ReleaseId.class.getCanonicalName() + ";\n" +
"import " + ReleaseIdImpl.class.getCanonicalName() + ";\n" +
"\n" +
"public class ProjectModel implements org.drools.modelcompiler.CanonicalKieModuleModel {\n" +
"\n");
sb.append(
" @Override\n" +
" public String getVersion() {\n" +
" return \"" );
sb.append( Drools.getFullVersion() );
sb.append(
"\";\n" +
" }\n" +
"\n" +
" @Override\n" +
" public java.util.List<Model> getModels() {\n" +
" return java.util.Arrays.asList(" );
sb.append( modelSources.isEmpty() ? "" : modelSources.stream().collect( joining("(), new ", "new ", "()") ) );
sb.append(
");\n" +
" }\n" +
"\n" +
" @Override\n" +
" public ReleaseId getReleaseId() {\n" +
" return new ReleaseIdImpl(\"" );
sb.append( releaseId.getGroupId() ).append( "\", \"" );
sb.append( releaseId.getArtifactId() ).append( "\", \"" );
sb.append( releaseId.getVersion() ).append( "\"" );
sb.append(
");\n" +
" }\n");
sb.append("\n");
sb.append(modelMethod.toGetKieModuleModelMethod());
sb.append("\n}" );
return sb.toString();
}

protected String buildProjectSourceClass( KieModuleModelMethod modelMethod ) {
StringBuilder sb = new StringBuilder();
sb.append(
"package org.drools.project.model;\n" +
"\n" +
"import " + Model.class.getCanonicalName() + ";\n" +
"import " + KieBase.class.getCanonicalName() + ";\n" +
"import " + KieBaseModel.class.getCanonicalName() + ";\n" +
"import " + KieSession.class.getCanonicalName() + ";\n" +
"\n" +
( hasCdi() ? "@javax.enterprise.context.ApplicationScoped\n" : "" ) +
"public class ProjectRuntime implements org.drools.modelcompiler.KieRuntimeBuilder {\n" +
"\n");
sb.append(modelMethod.getConstructor());
sb.append("\n");
sb.append(modelMethod.toNewKieSessionMethod());
sb.append("\n");
sb.append(modelMethod.toGetKieBaseForSessionMethod());
sb.append("\n");
sb.append(modelMethod.toKieSessionConfMethod());
sb.append("\n}" );
return sb.toString();
}

private boolean hasCdi() {
try {
Class.forName( "javax.enterprise.context.ApplicationScoped", false, getClassLoader() );
return true;
} catch (ClassNotFoundException cnfe) { }
return false;
trgMfs.write(MODEL_FILE, pkgNames.getBytes());
}
}
Loading

0 comments on commit 6aef805

Please sign in to comment.