@Override
 protected List<MethodMatcher> getMethodInvocationMatchers() {
   return ImmutableList.of(
       MethodMatcher.create()
           .typeDefinition(TypeCriteria.subtypeOf("java.lang.Class"))
           .name("forName")
           .withNoParameterConstraint(),
       MethodMatcher.create()
           .typeDefinition(TypeCriteria.subtypeOf("java.lang.ClassLoader"))
           .name("loadClass")
           .withNoParameterConstraint());
 }
 private static MethodMatcherCollection unboxingInvocationMatchers() {
   MethodMatcherCollection matchers = MethodMatcherCollection.create();
   for (Entry<String, String> type : PRIMITIVE_TYPES_BY_WRAPPER.entrySet()) {
     String primitiveType = type.getValue();
     TypeCriteria typeCriteria;
     if ("char".equals(primitiveType) || "boolean".equals(primitiveType)) {
       typeCriteria = TypeCriteria.is(type.getKey());
     } else {
       typeCriteria = TypeCriteria.subtypeOf("java.lang.Number");
     }
     matchers.add(MethodMatcher.create().callSite(typeCriteria).name(primitiveType + "Value"));
   }
   return matchers;
 }
@Rule(key = "S1217")
public class ThreadRunCheck extends AbstractMethodDetection {
  private static final MethodMatcher THREAD_RUN_METHOD_MATCHER =
      MethodMatcher.create()
          .typeDefinition(TypeCriteria.subtypeOf("java.lang.Thread"))
          .name("run")
          .withNoParameterConstraint();

  @Override
  protected List<MethodMatcher> getMethodInvocationMatchers() {
    return ImmutableList.of(THREAD_RUN_METHOD_MATCHER);
  }

  @Override
  protected void onMethodInvocationFound(MethodInvocationTree mit) {
    Tree parent = mit.parent();
    while (parent != null && !parent.is(Tree.Kind.METHOD)) {
      parent = parent.parent();
    }
    if (parent != null && THREAD_RUN_METHOD_MATCHER.matches((MethodTree) parent)) {
      return;
    }
    reportIssue(
        MethodsHelper.methodName(mit),
        "Call the method Thread.start() to execute the content of the run() method in a dedicated thread.");
  }
}
 private static MethodMatcherCollection getToStringMatchers(String... typeFullyQualifiedNames) {
   MethodMatcherCollection matchers = MethodMatcherCollection.create();
   for (String fullyQualifiedName : typeFullyQualifiedNames) {
     matchers.add(
         MethodMatcher.create()
             .typeDefinition(TypeCriteria.subtypeOf(fullyQualifiedName))
             .name("toString")
             .withoutParameter());
   }
   return matchers;
 }
@Rule(key = "S2077")
public class SQLInjectionCheck extends AbstractInjectionChecker {

  private static final MethodMatcher HIBERNATE_SESSION_CREATE_QUERY_MATCHER =
      MethodMatcher.create()
          // method from the interface org.hibernate.SharedSessionContract, implemented by
          // org.hibernate.Session
          .callSite(TypeCriteria.subtypeOf("org.hibernate.Session"))
          .name("createQuery")
          .withAnyParameters();

  private static final MethodMatcher STATEMENT_EXECUTE_QUERY_MATCHER =
      MethodMatcher.create()
          .typeDefinition(TypeCriteria.subtypeOf("java.sql.Statement"))
          .name("executeQuery")
          .withAnyParameters();

  private static final MethodMatcherCollection CONNECTION_MATCHERS =
      MethodMatcherCollection.create(
          MethodMatcher.create()
              .typeDefinition(TypeCriteria.subtypeOf("java.sql.Connection"))
              .name("prepareStatement")
              .withAnyParameters(),
          MethodMatcher.create()
              .typeDefinition(TypeCriteria.subtypeOf("java.sql.Connection"))
              .name("prepareCall")
              .withAnyParameters());

  private static final MethodMatcher ENTITY_MANAGER_CREATE_NATIVE_QUERY_MATCHER =
      MethodMatcher.create()
          .typeDefinition("javax.persistence.EntityManager")
          .name("createNativeQuery")
          .withAnyParameters();

  @Override
  public void visitNode(Tree tree) {
    MethodInvocationTree methodTree = (MethodInvocationTree) tree;
    boolean isHibernateCall = isHibernateCall(methodTree);
    if (isHibernateCall
        || isExecuteQueryOrPrepareStatement(methodTree)
        || isEntityManagerCreateNativeQuery(methodTree)) {
      // We want to check the argument for the three methods.
      ExpressionTree arg = methodTree.arguments().get(0);
      parameterName = "";
      if (isDynamicString(methodTree, arg, null, true)) {
        String message =
            "\""
                + parameterName
                + "\" is provided externally to the method and not sanitized before use.";
        if (isHibernateCall) {
          message = "Use Hibernate's parameter binding instead of concatenation.";
        }
        reportIssue(MethodsHelper.methodName(methodTree), message);
      }
    }
  }

  private static boolean isExecuteQueryOrPrepareStatement(MethodInvocationTree methodTree) {
    return !methodTree.arguments().isEmpty()
        && (STATEMENT_EXECUTE_QUERY_MATCHER.matches(methodTree)
            || CONNECTION_MATCHERS.anyMatch(methodTree));
  }

  private static boolean isHibernateCall(MethodInvocationTree methodTree) {
    return HIBERNATE_SESSION_CREATE_QUERY_MATCHER.matches(methodTree);
  }

  private static boolean isEntityManagerCreateNativeQuery(MethodInvocationTree methodTree) {
    return ENTITY_MANAGER_CREATE_NATIVE_QUERY_MATCHER.matches(methodTree);
  }
}