Coverage Report - org.boretti.drools.integration.drools5.DroolsClassVisitor
 
Classes in this File Line Coverage Branch Coverage Complexity
DroolsClassVisitor
0 %
0/109
0 %
0/42
3.273
 
 1  
 /*
 2  
     Drools5 Integration Helper
 3  
     Copyright (C) 2009  Mathieu Boretti mathieu.boretti@gmail.com
 4  
 
 5  
     This program is free software: you can redistribute it and/or modify
 6  
     it under the terms of the GNU General Public License as published by
 7  
     the Free Software Foundation, either version 3 of the License, or
 8  
     (at your option) any later version.
 9  
 
 10  
     This program is distributed in the hope that it will be useful,
 11  
     but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13  
     GNU General Public License for more details.
 14  
 
 15  
     You should have received a copy of the GNU General Public License
 16  
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 17  
 
 18  
  */
 19  
 package org.boretti.drools.integration.drools5;
 20  
 
 21  
 import java.text.SimpleDateFormat;
 22  
 import java.util.Date;
 23  
 import java.util.HashMap;
 24  
 import java.util.Map;
 25  
 
 26  
 import javax.annotation.Generated;
 27  
 
 28  
 import org.apache.maven.plugin.logging.Log;
 29  
 import org.boretti.drools.integration.drools5.annotations.DroolsService;
 30  
 import org.drools.RuleBase;
 31  
 import org.drools.StatelessSession;
 32  
 import org.objectweb.asm.Label;
 33  
 import org.objectweb.asm.Opcodes;
 34  
 import org.objectweb.asm.AnnotationVisitor;
 35  
 import org.objectweb.asm.ClassAdapter;
 36  
 import org.objectweb.asm.ClassVisitor;
 37  
 import org.objectweb.asm.FieldVisitor;
 38  
 import org.objectweb.asm.MethodVisitor;
 39  
 import org.objectweb.asm.Type;
 40  
 
 41  
 /**
 42  
  * @author mbo
 43  
  * @since 1.0.0
 44  
  *
 45  
  */
 46  
 class DroolsClassVisitor extends ClassAdapter {
 47  
                 
 48  
         private Log logger;
 49  
         
 50  
         private String me;
 51  
         
 52  
         @Override
 53  
         public void visit(int version, int access, String name, String signature,
 54  
                         String superName, String[] interfaces) {
 55  0
                 if (version<Opcodes.V1_6) {
 56  0
                         allowed=false;
 57  0
                         logger.warn("Version of the class "+name+" is not enough to be supported");
 58  
                 }
 59  0
                 else if ((access & Opcodes.ACC_INTERFACE)>0) {
 60  0
                         allowed=false;
 61  
                 }
 62  0
                 me = name;
 63  0
                 super.visit(version, access, name, signature, superName, interfaces);
 64  0
         }
 65  
         
 66  
         @Override
 67  
         public AnnotationVisitor visitAnnotation(String desc, boolean arg1) {
 68  0
                 if (allowed){ 
 69  0
                         if (Type.getType(desc).getClassName().equals(Type.getType(DroolsService.class).getClassName())) {
 70  0
                                 annotation_ok=true;
 71  
                         }
 72  
                 }
 73  0
                 return super.visitAnnotation(desc, arg1);
 74  
         }
 75  
 
 76  
         @Override
 77  
         public FieldVisitor visitField(int access, String name, String desc,
 78  
                         String signature, Object value) {
 79  0
                 if (isNeedChange()) {
 80  0
                         if (name.equals(DROOLS_FIELD_NAME)) allowed=false;
 81  
                         //fieldType
 82  0
                         return new DroolsCheckFieldVisitor(logger, super.visitField(access, name, desc, signature, value),this,name);
 83  
                 }
 84  0
                 return super.visitField(access, name, desc, signature, value);
 85  
         }
 86  
 
 87  
         @Override
 88  
         public MethodVisitor visitMethod(int access, String name, String desc,
 89  
                         String signature, String[] value) {
 90  0
                 MethodVisitor mv = super.visitMethod(access, name, desc, signature, value);
 91  0
                 if (isNeedChange()) {
 92  0
                         if (name.equals("<init>")) {
 93  0
                                 return new DroolsAddConstructorMethodVisitor(mv, access, name, desc,me,DROOLS_FIELD_NAME,DROOLS_FIELD_RULE);
 94  0
                         } else if (name.startsWith("get")){
 95  0
                                 String fieldName = name.substring(3).toUpperCase();
 96  0
                                 if (fieldType.containsKey(fieldName)) {
 97  0
                                         byte b = fieldType.get(fieldName);
 98  0
                                         if (b==0) {
 99  0
                                                 return new DroolsAddGeneratedGetMethodVisitor(mv, access, name, desc, me, DROOLS_FIELD_NAME, DROOLS_FIELD_RULE,DROOLS_METHOD_RUN);
 100  
                                         }
 101  
                                 }
 102  0
                         } else if (name.startsWith("set")){
 103  0
                                 String fieldName = name.substring(3).toUpperCase();
 104  0
                                 if (!fieldType.containsKey(fieldName)) {
 105  0
                                         return new DroolsAddGeneratedSetMethodVisitor(mv, access, name, desc, me, DROOLS_FIELD_NAME);
 106  
                                 }
 107  0
                         } else if (name.startsWith("is")){
 108  0
                                 String fieldName = name.substring(2).toUpperCase();
 109  0
                                 if (fieldType.containsKey(fieldName)) {
 110  0
                                         byte b = fieldType.get(fieldName);
 111  0
                                         if (b==0) {
 112  0
                                                 return new DroolsAddGeneratedGetMethodVisitor(mv, access, name, desc, me, DROOLS_FIELD_NAME, DROOLS_FIELD_RULE,DROOLS_METHOD_RUN);
 113  
                                         }
 114  
                                 }
 115  
                         }
 116  
                 }
 117  0
                 return mv;
 118  
         }
 119  
 
 120  
         @Override
 121  
         public void visitEnd() {
 122  0
                 if (isNeedChange()) {
 123  0
                         FieldVisitor fv = super.visitField(Opcodes.ACC_PRIVATE, DROOLS_FIELD_NAME, Type.BOOLEAN_TYPE.getDescriptor(),null, null);
 124  0
                         if (fv !=null) {
 125  0
                                 AnnotationVisitor av = fv.visitAnnotation(Type.getType(Generated.class).getDescriptor(), true);
 126  0
                                 AnnotationVisitor value = av.visitArray("value");
 127  0
                                 value.visit("","Generated by Drools5IntegrationHelper Maven plugin");
 128  0
                                 value.visitEnd();
 129  0
                                 av.visit("date", new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz").format(current));
 130  
                                 //TODO comments String
 131  0
                                 av.visitEnd();
 132  0
                                 fv.visitEnd();
 133  
                         }
 134  0
                         fv = super.visitField(Opcodes.ACC_PRIVATE, DROOLS_FIELD_RULE, Type.getType(RuleBase.class).getDescriptor(),null, null);
 135  0
                         if (fv !=null) {
 136  0
                                 AnnotationVisitor av = fv.visitAnnotation(Type.getType(Generated.class).getDescriptor(), true);
 137  0
                                 AnnotationVisitor value = av.visitArray("value");
 138  0
                                 value.visit("","Generated by Drools5IntegrationHelper Maven plugin");
 139  0
                                 value.visitEnd();
 140  0
                                 av.visit("date", new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz").format(current));
 141  
                                 //TODO comments String
 142  0
                                 av.visitEnd();
 143  0
                                 fv.visitEnd();
 144  
                         }
 145  0
                         MethodVisitor mv= super.visitMethod(Opcodes.ACC_PRIVATE, DROOLS_METHOD_RUN, "()V", null, null);
 146  0
                         AnnotationVisitor av = mv.visitAnnotation(Type.getType(Generated.class).getDescriptor(), true);
 147  0
                         AnnotationVisitor value = av.visitArray("value");
 148  0
                         value.visit("","Generated by Drools5IntegrationHelper Maven plugin");
 149  0
                         value.visitEnd();
 150  0
                         av.visit("date", new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz").format(current));
 151  
                         //TODO comments String
 152  0
                         av.visitEnd();
 153  0
                         mv.visitCode();
 154  0
                         Label start = new Label();
 155  0
                         mv.visitLabel(start);
 156  0
                         Label doIt = new Label();
 157  0
                         mv.visitVarInsn(Opcodes.ALOAD, 0);
 158  0
                         mv.visitFieldInsn(Opcodes.GETFIELD, Type.getObjectType(me).getInternalName(), DROOLS_FIELD_NAME, Type.BOOLEAN_TYPE.getDescriptor());
 159  0
                         mv.visitJumpInsn(Opcodes.IFEQ, doIt);
 160  0
                         mv.visitInsn(Opcodes.RETURN);
 161  0
                         mv.visitLabel(doIt);
 162  0
                         mv.visitFrame(Opcodes.F_SAME, 1,new Object[]{Type.getObjectType(me).getInternalName()}, 0, new Object[]{});
 163  0
                         mv.visitVarInsn(Opcodes.ALOAD, 0);
 164  0
                         mv.visitFieldInsn(Opcodes.GETFIELD, Type.getObjectType(me).getInternalName(), DROOLS_FIELD_RULE, Type.getType(RuleBase.class).getDescriptor());
 165  0
                         mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getType(RuleBase.class).getInternalName(), "newStatelessSession", "()Lorg/drools/StatelessSession;");
 166  0
                         mv.visitInsn(Opcodes.DUP);
 167  0
                         mv.visitLdcInsn(FIELD_NAME_LOGGER);
 168  0
                         mv.visitVarInsn(Opcodes.ALOAD, 0);
 169  0
                         mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getType(Object.class).getInternalName(), "getClass", "()Ljava/lang/Class;");
 170  0
                         mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getType(org.apache.log4j.Logger.class).getInternalName(), "getLogger", "(Ljava/lang/Class;)Lorg/apache/log4j/Logger;");
 171  0
                         mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getType(StatelessSession.class).getInternalName(), "setGlobal", "(Ljava/lang/String;Ljava/lang/Object;)V");
 172  0
                         mv.visitVarInsn(Opcodes.ALOAD, 0);
 173  0
                         mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getType(StatelessSession.class).getInternalName(), "execute", "(Ljava/lang/Object;)V");
 174  0
                         mv.visitVarInsn(Opcodes.ALOAD, 0);                        
 175  0
                         mv.visitInsn(Opcodes.ICONST_1);
 176  0
                         mv.visitFieldInsn(Opcodes.PUTFIELD, Type.getObjectType(me).getInternalName(), DROOLS_FIELD_NAME, Type.BOOLEAN_TYPE.getDescriptor());
 177  0
                         mv.visitInsn(Opcodes.RETURN);
 178  0
                         Label end = new Label();
 179  0
                         mv.visitLabel(end);
 180  0
                         mv.visitLocalVariable("this", Type.getObjectType(me).getDescriptor(), null, start, end, 0);
 181  0
                         mv.visitMaxs(4, 1);
 182  0
                         mv.visitEnd();
 183  
                 }
 184  0
                 super.visitEnd();
 185  0
         }
 186  
         
 187  
         private static final String FIELD_NAME_LOGGER = "droolsLogger";
 188  
         
 189  
         private static final String DROOLS_FIELD_NAME="$drools";
 190  
         
 191  
         private static final String DROOLS_FIELD_RULE="$drools_rule";
 192  
         
 193  
         private static final String DROOLS_METHOD_RUN="$drools_run";
 194  
                                 
 195  0
         private boolean allowed = true;
 196  
         
 197  0
         private boolean annotation_ok=false;
 198  
         
 199  0
         private Map<String,Byte> fieldType = new HashMap<String,Byte>();
 200  
         
 201  0
         private Date current = new Date();
 202  
 
 203  
         public DroolsClassVisitor(Log logger,ClassVisitor arg0) {
 204  0
                 super(arg0);
 205  0
                 this.logger=logger;
 206  0
         }
 207  
 
 208  
         public boolean isNeedChange() {
 209  0
                 return allowed && annotation_ok;
 210  
         }
 211  
 
 212  
         public boolean isAllowed() {
 213  0
                 return allowed;
 214  
         }
 215  
 
 216  
         public void setAllowed(boolean allowed) {
 217  0
                 this.allowed = allowed;
 218  0
         }
 219  
 
 220  
         /**
 221  
          * @return the fieldType
 222  
          */
 223  
         public Map<String, Byte> getFieldType() {
 224  0
                 return fieldType;
 225  
         }
 226  
 
 227  
         /**
 228  
          * @param fieldType the fieldType to set
 229  
          */
 230  
         public void setFieldType(Map<String, Byte> fieldType) {
 231  0
                 this.fieldType = fieldType;
 232  0
         }
 233  
 
 234  
 }