Package cn.org.rapid_framework.generator.provider.java.model

Source Code of cn.org.rapid_framework.generator.provider.java.model.JavaMethod$JavaMethodInvokeSequencesParser

/**
* project:pomer
*
* Copyright 2008 [pomer], Inc. All rights reserved.
* Website: http://www.pomer.org.cn/
*
*/
package cn.org.rapid_framework.generator.provider.java.model;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import cn.org.rapid_framework.generator.provider.java.model.MethodParameter.JavaSourceFileMethodParametersParser;
import cn.org.rapid_framework.generator.util.GLogger;
import cn.org.rapid_framework.generator.util.StringHelper;
import cn.org.rapid_framework.generator.util.typemapping.JavaImport;

/**
*
* @author badqiu,Linlin Yu
*/
public class JavaMethod {
  Method method;
  private JavaClass clazz; //与method相关联的class
 
 
  public JavaMethod(Method method, JavaClass clazz) {
    super();
    if(method == null) throw new IllegalArgumentException("method must be not null");
    if(clazz == null) throw new IllegalArgumentException("clazz must be not null");
    this.method = method;
    this.clazz = clazz;
  }

  public JavaClass getClazz() {
    return clazz;
  }

  public String getMethodName() {
    return method.getName();
  }

  public JavaClass getReturnType() {
    return new JavaClass(method.getReturnType());
  }
 
  public Annotation[] getAnnotations() {
    return method.getAnnotations();
  }

  public boolean isBridge() {
    return method.isBridge();
  }

    public List<JavaClass> getExceptionTypes() {
        List<JavaClass> result = new ArrayList();
        for(Class c : method.getExceptionTypes()) {
            result.add(new JavaClass(c));
        }
        return result;
    }

    public boolean isSynthetic() {
    return method.isSynthetic();
  }

  public boolean isVarArgs() {
    return method.isVarArgs();
  }

  public Set<JavaClass> getImportClasses() {
    Set<JavaClass> set = new LinkedHashSet<JavaClass>();
        JavaImport.addImportClass(set,method.getParameterTypes());
        JavaImport.addImportClass(set,method.getExceptionTypes());
        JavaImport.addImportClass(set, method.getReturnType());
        return set;
  }
 
  public List<MethodParameter> getParameters() {
    Class[] parameters  = method.getParameterTypes();
    List<MethodParameter> results = new ArrayList<MethodParameter>();
    for(int i = 0; i < parameters.length; i++) {
      results.add(new MethodParameter(i+1,this,new JavaClass(parameters[i])));
    }
    return results;
  }
 
  public String getMethodNameUpper() {
    return StringHelper.capitalize(getMethodName());
  }
 
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((method == null) ? 0 : method.hashCode());
        return result;
    }

    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        JavaMethod other = (JavaMethod) obj;
        if (method == null) {
            if (other.method != null)
                return false;
        } else if (!method.equals(other.method))
            return false;
        return true;
    }
   
    public boolean isPropertyMethod() {
      if(getMethodName().startsWith("set") || getMethodName().startsWith("get") || (getMethodName().startsWith("is") && getReturnType().isBooleanType())) {
        return true;
      }
      return false;
    }

    /**
     * 解析java源代码的方法,将一个方法中调用field的所有方法全部提取出来.
     * @return
     */
    public List<FieldMethodInvocation> getFieldMethodInvocationSequences() {
      if(StringHelper.isNotBlank(clazz.getMavenJavaSourceFileContent())) {
          try {
            JavaMethodInvokeSequencesParser cmd = new JavaMethodInvokeSequencesParser(this,clazz.getMavenJavaSourceFileContent());
            cmd.execute();
            return cmd.getMethodInvokeSequences();
          }catch(Exception e) {
              GLogger.warn("getFieldMethodInvocationSequences() occer error on method:"+method.toString(),e);
              return new ArrayList<FieldMethodInvocation>(0);
          }
      }else {
        return new ArrayList<FieldMethodInvocation>(0);
      }
    }
   
    public String toString() {
    return clazz.getJavaType()+"."+getMethodName()+"()";
  }
   
    public static class FieldMethodInvocation {
      JavaField field;
      JavaMethod method;
    public FieldMethodInvocation(JavaField field, JavaMethod method) {
      super();
      this.field = field;
      this.method = method;
    }
    public JavaField getField() {
      return field;
    }
    public void setField(JavaField field) {
      this.field = field;
    }
    public JavaMethod getMethod() {
      return method;
    }
    public void setMethod(JavaMethod method) {
      this.method = method;
    }
    public boolean equals(Object obj) {
        if(obj == null) return false;
        if(! (obj instanceof FieldMethodInvocation)) return false;
        FieldMethodInvocation other = (FieldMethodInvocation)obj;
        return field.equals(other.field) && method.equals(other.method);
    }
    public int hashCode() {
        return field.hashCode() + method.hashCode();
    }
    public String toString() {
        return field.getFieldName()+"."+method.getMethodName()+"()";
    }
    }
   
    /**
     * 解析java源代码的方法,将一个方法中调用field的所有方法全部提取出来.
     **/
    public static class JavaMethodInvokeSequencesParser {
      //匹配一个field的方法调用,如  generator.deleteBy() method.getClass()
      public static String fieldMethodInvokeRegex = "(\\w+)\\.(\\w+)\\(";
     
      private JavaMethod method;
      private String javaSourceContent;
      private JavaClass clazz;
     
      boolean executed = false;
      public JavaMethodInvokeSequencesParser(JavaMethod method, String javaSourceContent) {
      super();
        if(StringHelper.isBlank(javaSourceContent)) {
          throw new IllegalArgumentException("'javaSourceContent' must be not blank");
        }
       
      this.method = method;
      this.javaSourceContent = javaSourceContent;
      this.clazz = method.getClazz();
    }

    private List<FieldMethodInvocation> methodInvokeFlows = new ArrayList<FieldMethodInvocation>();
   
      public List<FieldMethodInvocation> getMethodInvokeSequences() {
        if(executed) {
          return methodInvokeFlows;
        }else {
          throw new IllegalStateException("please invoke execute() method before getMethodInvokeFlows()");
        }
      }
     
      public void execute() {
        executed = true;
        //本类是否有声明
        if(!declaredMethodsContains()) {
            return;
        }
        //是否是匿名方法
        if(method.getMethodName().indexOf("$") >= 0) {
            return;
        }
       
        String javaSourceContent = removeSomeThings();
        String methodBody = getMethodBody(javaSourceContent);
       
        Pattern p = Pattern.compile(fieldMethodInvokeRegex);
        Matcher m = p.matcher(methodBody);
        while(m.find()) {
          String field = m.group(1);
          String methodName= m.group(2);
          addFieldMethodInvocation(field, methodName);
        }
      }

        private boolean declaredMethodsContains() {
            for(Method m : clazz.getClazz().getDeclaredMethods()) {
            if(m.equals(method.method)) {
                return true;
            }
        }
            return false;
        }

    private void addFieldMethodInvocation(String field, String methodName) {
      try {
        JavaField javaField = clazz.getField(field);
        JavaClass fieldType = javaField.getType();
        JavaMethod method = fieldType.getMethod(methodName);
        if(method != null) {
          methodInvokeFlows.add(new FieldMethodInvocation(javaField,method));
        }
      } catch (NoSuchFieldException e) {
        //ignore
      }
    }
   
    public static String modifierToString(int mod) {
        if ((mod & Modifier.PUBLIC) != 0)    return "public";
        if ((mod & Modifier.PROTECTED) != 0) return "protected";
        if ((mod & Modifier.PRIVATE) != 0)   return "private";
        return "";
    }
   
    private String getMethodBody(String javaSourceContent) {
       
        String methodStartPattern = "(?s)\\s+"+method.getMethodName()+"\\s*\\("+JavaSourceFileMethodParametersParser.getSimpleParamsPattern(method.method)+"\\)\\s*";
           
          int methodStart = StringHelper.indexOfByRegex(javaSourceContent,methodStartPattern);
          if(methodStart == -1) throw new IllegalArgumentException("cannot get method body by pattern:"+methodStartPattern+" methodName:"+method.getMethodName() +"\n javaSource:"+javaSourceContent);
         
          try {
            String methodEnd = javaSourceContent.substring(methodStart);
            int[] beginAndEnd = findWrapCharEndLocation(methodEnd,'{','}');
            if(beginAndEnd == null) return "";
           
            String methodBody = methodEnd.substring(beginAndEnd[0], beginAndEnd[1]);
          return methodBody;
        }catch(RuntimeException e) {
            throw new IllegalArgumentException("cannot get method body by pattern:"+methodStartPattern+"\n javaSource:"+javaSourceContent,e);
        }
    }

    private String removeSomeThings() {
      String javaSourceContent = removeJavaComments(this.javaSourceContent);
//        javaSourceContent = removeJavaImports(javaSourceContent);
//        javaSourceContent = removeJavaPackage(javaSourceContent);
        javaSourceContent = replaceString2EmptyString(javaSourceContent);
      return javaSourceContent;
    }
     
      public static  String replaceString2EmptyString(String str) {
        if(str == null) return null;
        str = str.replaceAll("\".*?\"", ""); // replace string from "234 " => ""
      return str;
    }
    // getName\s*\(.*?\)\s*\{.*?\;\s*}
    public static String removeJavaComments(String str) {
      if(str == null) return null;
      str = str.replaceAll("//.*", ""); // remove line comment: //
      str = str.replaceAll("(?s)/\\*.*?\\*/", ""); // remove block comment: /* */
      return str;
    }
//    public static String removeJavaImports(String str) {
//        if(str == null) return null;
//        str = str.replaceAll("\\s*import\\s.*", ""); // remove java import
//      return str;
//    }
//    public static String removeJavaPackage(String str) {
//        if(str == null) return null;
//        str = str.replaceAll("\\s*package\\s.*", ""); // remove java package
//      return str;
//    }
   
    /**
     * 找到对称的一条括号所处的位置,
     * 如 findWrapCharEndLocation("0123{{67}}}",'{','}'), 将返回 [4,9]
     * 如果没有将到,将返回null
     **/
    public static int[] findWrapCharEndLocation(String str,char begin,char end) {
      int count = 0;
      boolean foundEnd = false;
      boolean foundBegin = false;
      int[] beginAndEnd = new int[2];
      for(int i = 0; i < str.length(); i++) {
        char c = str.charAt(i);
        if(c == begin) {
          if(!foundBegin) {
            beginAndEnd[0] = i;
          }
          foundBegin = true;
          count ++;
        }
        if(c == end) {
          foundEnd = true;
          count--;
        }
        if(count == 0 && foundBegin && foundEnd) {
          beginAndEnd[1] = i;
          return beginAndEnd;
        }
      }
      return null;
    }
    }
   
}
TOP

Related Classes of cn.org.rapid_framework.generator.provider.java.model.JavaMethod$JavaMethodInvokeSequencesParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.