static void extractJpaClasses(
      final URLClassLoader classLoader,
      final List<String> classes,
      final JpaDependencyDiagramModel dependencyModel,
      final String includePatternString,
      final String excludePatternString)
      throws ClassNotFoundException, IllegalAccessException, IllegalArgumentException,
          InvocationTargetException, NoSuchMethodException, SecurityException {
    String[] includePatterns = includePatternString.split(",");
    String[] excludePatterns = excludePatternString.split(",");
    boolean hasAnyPatterns =
        !(includePatterns.length == 1 && includePatterns[0].isEmpty())
            || !(excludePatterns.length == 1 && excludePatterns[0].isEmpty());
    Map<String, Map<String, JpaDependencyType>> jpaDependencyCache =
        new HashMap<String, Map<String, JpaDependencyType>>();
    for (String className : classes) {
      if (UmlGeneratorUtility.isIncluded(
          className, hasAnyPatterns, includePatterns, excludePatterns)) {
        Class<?> loadClass = classLoader.loadClass(className);
        // check if its an persistent entity
        if (isPersistentEntity(loadClass)) {
          System.out.println("Parsing persistent class  " + loadClass.getSimpleName());
          // extract class info
          JpaClassModel classModel = new JpaClassModel(loadClass.getName());

          // determine class types
          extractJpaClassAnnotations(loadClass, classModel);

          // extract fields
          extractColumnsAndEntityDependencies(
              dependencyModel,
              loadClass,
              classModel,
              jpaDependencyCache,
              hasAnyPatterns,
              includePatterns,
              excludePatterns);

          // extract interfaces
          extractInterfaces(
              loadClass, classModel, hasAnyPatterns, includePatterns, excludePatterns);

          // extract parent class
          Class<?> superclass = loadClass.getSuperclass();
          if (superclass != null
              && !superclass.equals(Object.class)
              && UmlGeneratorUtility.isIncluded(
                  superclass.getName(), hasAnyPatterns, includePatterns, excludePatterns)) {
            classModel.setParent(superclass.getName());
          }

          // add prepared class model to class diagram
          dependencyModel.addClass(classModel);
        }
      }
    }
  }
 private static void extractInterfaces(
     final Class<?> loadClass,
     final JpaClassModel classModel,
     final boolean hasAnyPatterns,
     final String[] includePatterns,
     final String[] excludePatterns) {
   for (Class interfaceClass : loadClass.getInterfaces()) {
     if (UmlGeneratorUtility.isIncluded(
         interfaceClass.getName(), hasAnyPatterns, includePatterns, excludePatterns)) {
       classModel.addInterface(interfaceClass.getName());
     }
   }
 }
 private static void extractColumnsAndEntityDependencies(
     final JpaDependencyDiagramModel dependencyModel,
     final Class<?> loadClass,
     final JpaClassModel classModel,
     final Map<String, Map<String, JpaDependencyType>> jpaDependencyCache,
     final boolean hasAnyPatterns,
     final String[] includePatterns,
     final String[] excludePatterns) {
   for (Field field : loadClass.getDeclaredFields()) {
     try {
       Class<?> fieldType = field.getType();
       if (UmlGeneratorUtility.isIncluded(
           fieldType.getName(), hasAnyPatterns, includePatterns, excludePatterns)) {
         // check for spring dependencies
         if (field.isAnnotationPresent(Column.class)) {
           extractColumn(classModel, field.getAnnotation(Column.class));
         } else if (field.isAnnotationPresent(OneToMany.class)) {
           for (Type type :
               ((ParameterizedType) field.getGenericType()).getActualTypeArguments()) {
             if (type instanceof Class) {
               updateDependencyCache(
                   dependencyModel,
                   jpaDependencyCache,
                   classModel,
                   ((Class<?>) type).getName(),
                   JpaDependencyType.ONE_TO_MANY);
             }
           }
         } else if (field.isAnnotationPresent(ManyToOne.class)) {
           updateDependencyCache(
               dependencyModel,
               jpaDependencyCache,
               classModel,
               fieldType.getName(),
               JpaDependencyType.MANY_TO_ONE);
         } else if (field.isAnnotationPresent(OneToOne.class)) {
           updateDependencyCache(
               dependencyModel,
               jpaDependencyCache,
               classModel,
               fieldType.getName(),
               JpaDependencyType.ONE_TO_ONE);
         } else if (field.isAnnotationPresent(ManyToMany.class)) {
           updateDependencyCache(
               dependencyModel,
               jpaDependencyCache,
               classModel,
               fieldType.getName(),
               JpaDependencyType.MANY_TO_MANY);
         } else if (field.isAnnotationPresent(Id.class)) {
           classModel.addIdColumn(field.getName());
         }
       }
     } catch (Exception e) {
       // no need to do anything
       continue;
     } catch (NoClassDefFoundError error) {
       // no need to do anything
       continue;
     }
   }
 }