use of org.drools.core.util.bitmask.BitMask in project drools by kiegroup.
the class JavaConsequenceBuilderPRAlwaysTest method testForBlocks.
@Test
public void testForBlocks() throws Exception {
String consequence = " System.out.println(\"this is a test\");\n " + "int i = 0;\n" + " for ( Cheese c1 = $cheese; i < 10;i++ ) { \r\n" + " modify( c1 ) { setPrice( 10 ), \n" + " setOldPrice( age ) }\n " + " Cheese c4 = $cheese;\n" + " for ( Cheese item : new ArrayList<Cheese>() ) {" + " modify( $cheese ) { setPrice( 10 ), setOldPrice( age ) }\n " + " }\n" + " } \n " + // <<< TODO in the original test here was a cast to (Cheese) $cheese, but this ad-hoc test is missing the kBuilder to properly populate the CompositePackageDescr which contains the import declaration.
" for ( ; ; ) modify( $cheese ) { setPrice( 10 ), setOldPrice( age ) }\n " + // the more correct way would be to change completely the ad-hoc build logic of this test contained in setupTest() and intercept the DialectUtils transformation on a *real* compilation process.
" for ( Cheese item : new ArrayList<Cheese>() ) modify( $cheese ) { setPrice( 10 ), setOldPrice( age ) }\n " + " modify( $cheese ) { setPrice( 10 ), setOldPrice( age ) }\n " + " System.out.println(\"we are done\");\n ";
setupTest("", new HashMap<String, Object>());
ruleDescr.setConsequence(consequence);
JavaExprAnalyzer analyzer = new JavaExprAnalyzer();
Map<String, Class<?>> declrCls = new HashMap<String, Class<?>>();
declrCls.put("$cheese", Cheese.class);
JavaAnalysisResult analysis = (JavaAnalysisResult) analyzer.analyzeBlock((String) ruleDescr.getConsequence(), new BoundIdentifiers(declrCls, null));
BoundIdentifiers bindings = new BoundIdentifiers(new HashMap(), null);
bindings.getDeclrClasses().put("$cheese", Cheese.class);
bindings.getDeclrClasses().put("age", int.class);
// Set the inputs for each container, this is needed for modifes when the target context is the result of an expression
List<JavaBlockDescr> descrs = new ArrayList<JavaBlockDescr>();
setContainerBlockInputs(context, descrs, analysis.getBlockDescrs(), consequence, bindings, new HashMap(), 0);
String fixed = fixBlockDescr(context, analysis, context.getDeclarationResolver().getDeclarations(context.getRule()));
List<String> cheeseAccessibleProperties = ClassUtils.getAccessibleProperties(Cheese.class);
BitMask priceOldPrice = PropertySpecificUtil.calculatePositiveMask(Cheese.class, Arrays.asList("price", "oldPrice"), cheeseAccessibleProperties);
String expected = " System.out.println(\"this is a test\");\r\n" + " int i = 0;\r\n" + " for ( Cheese c1 = $cheese; i < 10;i++ ) { \r\n" + " { org.drools.compiler.Cheese __obj__ = ( c1 ); org.kie.api.runtime.rule.FactHandle __obj____Handle2__ = drools.getFactHandle(__obj__);__obj__.setPrice( 10 ); \r\n" + "__obj__.setOldPrice( age ); drools.update( __obj____Handle2__, " + priceOldPrice.getInstancingStatement() + ", org.drools.compiler.Cheese.class ); }\r\n" + " Cheese c4 = $cheese;\r\n" + " for ( Cheese item : new ArrayList<Cheese>() ) { { $cheese.setPrice( 10 ); $cheese.setOldPrice( age ); drools.update( $cheese__Handle__, " + priceOldPrice.getInstancingStatement() + ", org.drools.compiler.Cheese.class ); }\r\n" + " }\r\n" + " } \r\n" + " for ( ; ; ) { $cheese.setPrice( 10 ); $cheese.setOldPrice( age ); drools.update( $cheese__Handle__, " + priceOldPrice.getInstancingStatement() + ", org.drools.compiler.Cheese.class ); }\r\n" + " for ( Cheese item : new ArrayList<Cheese>() ) { $cheese.setPrice( 10 ); $cheese.setOldPrice( age ); drools.update( $cheese__Handle__, " + priceOldPrice.getInstancingStatement() + ", org.drools.compiler.Cheese.class ); }\r\n" + " { $cheese.setPrice( 10 ); $cheese.setOldPrice( age ); drools.update( $cheese__Handle__, " + priceOldPrice.getInstancingStatement() + ", org.drools.compiler.Cheese.class ); }\r\n" + " System.out.println(\"we are done\");\r\n" + " \r\n" + "";
System.out.println(expected);
System.out.println(fixed);
assertNotNull(context.getErrors().toString(), fixed);
assertEqualsIgnoreSpaces(expected, fixed);
}
use of org.drools.core.util.bitmask.BitMask in project drools by kiegroup.
the class DialectUtil method rewriteModifyDescr.
private static void rewriteModifyDescr(RuleBuildContext context, JavaBlockDescr d, String originalBlock, StringBuilder consequence, Declaration declr, String obj) {
List<String> settableProperties = null;
Class<?> typeClass = findModifiedClass(context, d, declr);
TypeDeclaration typeDeclaration = typeClass == null ? null : context.getKnowledgeBuilder().getTypeDeclaration(typeClass);
boolean isPropertyReactive = typeDeclaration != null && typeDeclaration.isPropertyReactive();
if (isPropertyReactive) {
typeDeclaration.setTypeClass(typeClass);
settableProperties = typeDeclaration.getAccessibleProperties();
}
ConsequenceMetaData.Statement statement = null;
if (typeDeclaration != null) {
statement = new ConsequenceMetaData.Statement(ConsequenceMetaData.Statement.Type.MODIFY, typeClass);
context.getRule().getConsequenceMetaData().addStatement(statement);
}
BitMask modificationMask = isPropertyReactive ? getEmptyPropertyReactiveMask(settableProperties.size()) : allSetButTraitBitMask();
int end = originalBlock.indexOf("{");
if (end == -1) {
// no block
context.addError(new DescrBuildError(context.getParentDescr(), context.getRuleDescr(), null, "Block missing after modify" + d.getTargetExpression() + " ?\n"));
return;
}
addLineBreaks(consequence, originalBlock.substring(0, end));
int start = end + 1;
// adding each of the expressions:
for (String exprStr : ((JavaModifyBlockDescr) d).getExpressions()) {
end = originalBlock.indexOf(exprStr, start);
addLineBreaks(consequence, originalBlock.substring(start, end));
consequence.append(obj).append(".");
consequence.append(exprStr);
consequence.append("; ");
start = end + exprStr.length();
if (typeDeclaration != null) {
modificationMask = parseModifiedProperties(statement, settableProperties, typeDeclaration, isPropertyReactive, modificationMask, exprStr);
}
}
addLineBreaks(consequence, originalBlock.substring(end));
appendUpdateStatement(consequence, declr, obj, modificationMask, typeClass);
}
use of org.drools.core.util.bitmask.BitMask in project drools by kiegroup.
the class MvelConstraint method calculateMaskFromExpression.
private BitMask calculateMaskFromExpression(List<String> settableProperties) {
BitMask mask = getEmptyPropertyReactiveMask(settableProperties.size());
String[] simpleExpressions = expression.split("\\Q&&\\E|\\Q||\\E");
for (String simpleExpression : simpleExpressions) {
String propertyName = getPropertyNameFromSimpleExpression(simpleExpression);
if (propertyName == null || propertyName.equals("this") || propertyName.length() == 0) {
return allSetButTraitBitMask();
}
int pos = settableProperties.indexOf(propertyName);
if (pos < 0 && Character.isUpperCase(propertyName.charAt(0))) {
propertyName = propertyName.substring(0, 1).toLowerCase() + propertyName.substring(1);
pos = settableProperties.indexOf(propertyName);
}
if (pos >= 0) {
// Ignore not settable properties
mask = mask.set(pos + PropertySpecificUtil.CUSTOM_BITS_OFFSET);
}
}
return mask;
}
use of org.drools.core.util.bitmask.BitMask in project drools by kiegroup.
the class DialectUtil method rewriteUpdateDescr.
private static void rewriteUpdateDescr(RuleBuildContext context, JavaBlockDescr d, StringBuilder consequence, Declaration declr, String obj) {
BitMask modificationMask = AllSetBitMask.get();
Class<?> typeClass = findModifiedClass(context, d, declr);
TypeDeclaration typeDeclaration = typeClass == null ? null : context.getKnowledgeBuilder().getTypeDeclaration(typeClass);
if (typeDeclaration != null) {
boolean isPropertyReactive = typeDeclaration.isPropertyReactive();
List<String> settableProperties = null;
if (isPropertyReactive) {
typeDeclaration.setTypeClass(typeClass);
settableProperties = typeDeclaration.getAccessibleProperties();
modificationMask = getEmptyPropertyReactiveMask(settableProperties.size());
}
ConsequenceMetaData.Statement statement = new ConsequenceMetaData.Statement(ConsequenceMetaData.Statement.Type.MODIFY, typeClass);
context.getRule().getConsequenceMetaData().addStatement(statement);
if (isPropertyReactive) {
boolean parsedExprOnce = false;
// a late optimization to include this for-loop within this if
for (String expr : splitStatements(consequence)) {
String updateExpr = expr.replaceFirst("^\\Q" + obj + "\\E\\s*\\.", "");
if (!updateExpr.equals(expr)) {
parsedExprOnce = true;
modificationMask = parseModifiedProperties(statement, settableProperties, typeDeclaration, isPropertyReactive, modificationMask, updateExpr);
if (modificationMask == allSetButTraitBitMask()) {
// opt: if we were unable to detect the property in the mask is all set, so avoid the rest of the cycle
break;
}
}
}
if (!parsedExprOnce) {
// never called parseModifiedProperties(), hence never had the opportunity to "miss" the property and set mask to All-set; doing so here:
modificationMask = allSetButTraitBitMask();
}
}
}
appendUpdateStatement(consequence, declr, obj, modificationMask, typeClass);
}
use of org.drools.core.util.bitmask.BitMask in project drools by kiegroup.
the class PhreakPropagationContext method adaptModificationMaskForObjectType.
public PropagationContext adaptModificationMaskForObjectType(ObjectType type, InternalWorkingMemory workingMemory) {
if (isAllSetPropertyReactiveMask(originalMask) || originalMask.isSet(PropertySpecificUtil.TRAITABLE_BIT) || !(type instanceof ClassObjectType)) {
return this;
}
ClassObjectType classObjectType = (ClassObjectType) type;
BitMask cachedMask = classObjectType.getTransformedMask(modifiedClass, originalMask);
if (cachedMask != null) {
modificationMask = cachedMask;
return this;
}
modificationMask = originalMask;
boolean typeBit = modificationMask.isSet(PropertySpecificUtil.TRAITABLE_BIT);
modificationMask = modificationMask.reset(PropertySpecificUtil.TRAITABLE_BIT);
Class<?> classType = classObjectType.getClassType();
String pkgName = classType.getPackage().getName();
if (classType == modifiedClass || "java.lang".equals(pkgName) || !(classType.isInterface() || modifiedClass.isInterface())) {
if (typeBit) {
modificationMask = modificationMask.set(PropertySpecificUtil.TRAITABLE_BIT);
}
return this;
}
List<String> typeClassProps = getAccessibleProperties(workingMemory, classType, pkgName);
List<String> modifiedClassProps = getAccessibleProperties(workingMemory, modifiedClass);
modificationMask = getEmptyPropertyReactiveMask(typeClassProps.size());
for (int i = 0; i < modifiedClassProps.size(); i++) {
if (isPropertySetOnMask(originalMask, i)) {
int posInType = typeClassProps.indexOf(modifiedClassProps.get(i));
if (posInType >= 0) {
modificationMask = setPropertyOnMask(modificationMask, posInType);
}
}
}
if (typeBit) {
modificationMask = modificationMask.set(PropertySpecificUtil.TRAITABLE_BIT);
}
classObjectType.storeTransformedMask(modifiedClass, originalMask, modificationMask);
return this;
}
Aggregations