private JavaClass readJavaType()

in tooling/camel-spring-boot-generator-maven-plugin/src/main/java/org/apache/camel/springboot/maven/SpringBootAutoConfigurationMojo.java [895:1009]


    private JavaClass readJavaType(String type) {
        if (!type.startsWith("java.lang.") && (!type.contains("<") || !type.contains(">"))) {
            String sourceCode = "";
            try {
                Class<?> clazz = getProjectClassLoader().loadClass(type);
                URL url = clazz != null
                        ? getProjectClassLoader().getResource(clazz.getName().replace('.', '/') + ".class") : null;
                Artifact mainDep = project.getArtifactMap().get(getMainDepGroupId() + ":" + getMainDepArtifactId());
                if (url == null || mainDep == null || !url.toString().contains(mainDep.getFile().toURI().toString())) {
                    return null;
                }
                JavaClass nestedType = new JavaClass(getProjectClassLoader()).setPackage(clazz.getPackage().getName())
                        .setName(clazz.getSimpleName()).setEnum(clazz.isEnum()).setClass(!clazz.isInterface())
                        .setAbstract((clazz.getModifiers() & Modifier.ABSTRACT) != 0)
                        .setStatic((clazz.getModifiers() & Modifier.STATIC) != 0)
                        .extendSuperType(clazz.getGenericSuperclass() != null
                                ? new GenericType(clazz.getGenericSuperclass()).toString() : null);

                List<java.lang.reflect.Method> publicMethods = Stream.of(clazz.getDeclaredMethods())
                        .filter(m -> Modifier.isPublic(m.getModifiers())).collect(Collectors.toList());
                List<java.lang.reflect.Method> allSetters = publicMethods.stream()
                        .filter(m -> m.getReturnType() == void.class || m.getReturnType() == clazz)
                        .filter(m -> m.getParameterCount() == 1)
                        .filter(m -> m.getName().matches("set[A-Z][a-zA-Z0-9]*")).collect(Collectors.toList());
                List<java.lang.reflect.Method> allGetters = publicMethods.stream()
                        .filter(m -> m.getReturnType() != void.class).filter(m -> m.getParameterCount() == 0)
                        .filter(m -> m.getName().matches("(get|is)[A-Z][a-zA-Z0-9]*")).collect(Collectors.toList());
                allSetters.stream()
                        .sorted(Comparator.<java.lang.reflect.Method> comparingInt(
                                m -> getSetterPosition(sourceCode, m)).thenComparing(java.lang.reflect.Method::getName))
                        .map(m -> StringUtils.uncapitalize(m.getName().substring(3))).forEach(fn -> {
                            Class<?> ft;
                            Type wft;
                            boolean isBoolean;
                            java.lang.reflect.Field field = Stream.of(clazz.getDeclaredFields())
                                    .filter(f -> f.getName().equals(fn)).findAny().orElse(null);
                            List<java.lang.reflect.Method> setters = allSetters.stream()
                                    .filter(m -> m.getName().equals("set" + StringUtils.capitalize(fn)))
                                    .collect(Collectors.toList());
                            List<java.lang.reflect.Method> getters = allGetters.stream()
                                    .filter(m -> m.getName().equals("get" + StringUtils.capitalize(fn))
                                            || m.getName().equals("is" + StringUtils.capitalize(fn)))
                                    .collect(Collectors.toList());
                            java.lang.reflect.Method mutator;
                            java.lang.reflect.Method accessor;
                            if (setters.size() == 1) {
                                mutator = setters.get(0);
                                ft = mutator.getParameterTypes()[0];
                                wft = PRIMITIVE_CLASSES.getOrDefault(ft, ft);
                                isBoolean = ft == boolean.class || ft == Boolean.class;
                                accessor = allGetters.stream()
                                        .filter(m -> m.getName().equals("get" + StringUtils.capitalize(fn))
                                                || isBoolean && m.getName().equals("is" + StringUtils.capitalize(fn)))
                                        .filter(m -> PRIMITIVE_CLASSES.getOrDefault(m.getReturnType(),
                                                m.getReturnType()) == wft)
                                        .findAny().orElse(null);
                            } else if (field != null) {
                                ft = field.getType();
                                wft = PRIMITIVE_CLASSES.getOrDefault(ft, ft);
                                isBoolean = ft == boolean.class || ft == Boolean.class;
                                mutator = allSetters.stream()
                                        .filter(m -> m.getName().equals("set" + StringUtils.capitalize(fn)))
                                        .filter(m -> PRIMITIVE_CLASSES.getOrDefault(m.getParameterTypes()[0],
                                                m.getParameterTypes()[0]) == wft)
                                        .findAny().orElse(null);
                                accessor = allGetters.stream()
                                        .filter(m -> m.getName().equals("get" + StringUtils.capitalize(fn))
                                                || isBoolean && m.getName().equals("is" + StringUtils.capitalize(fn)))
                                        .filter(m -> PRIMITIVE_CLASSES.getOrDefault(m.getReturnType(),
                                                m.getReturnType()) == wft)
                                        .findAny().orElse(null);
                            } else {
                                if (getters.size() == 1) {
                                    ft = getters.get(0).getReturnType();
                                } else {
                                    throw new IllegalStateException("Unable to determine type for property " + fn);
                                }
                                wft = PRIMITIVE_CLASSES.getOrDefault(ft, ft);
                                mutator = setters.stream().filter(m -> PRIMITIVE_CLASSES
                                        .getOrDefault(m.getParameterTypes()[0], m.getParameterTypes()[0]) == wft)
                                        .findAny().orElse(null);
                                accessor = getters.stream().filter(m -> PRIMITIVE_CLASSES
                                        .getOrDefault(m.getReturnType(), m.getReturnType()) == wft).findAny()
                                        .orElse(null);
                            }
                            if (mutator == null) {
                                throw new IllegalStateException("Could not find mutator for property " + fn);
                            }
                            Property property = nestedType.addProperty(new GenericType(wft), fn);
                            property.getMutator().getJavaDoc().setText(getSetterJavaDoc(sourceCode, fn));
                            for (java.lang.annotation.Annotation ann : mutator.getAnnotations()) {
                                addAnnotation(ac -> property.getMutator().addAnnotation(ac), ann);
                            }
                            if (accessor != null) {
                                for (java.lang.annotation.Annotation ann : accessor.getAnnotations()) {
                                    addAnnotation(ac -> property.getAccessor().addAnnotation(ac), ann);
                                }
                            } else {
                                property.removeAccessor();
                            }
                            if (field != null) {
                                for (java.lang.annotation.Annotation ann : field.getAnnotations()) {
                                    addAnnotation(ac -> property.getField().addAnnotation(ac), ann);
                                }
                            } else {
                                property.removeField();
                            }
                        });
                return nestedType;
            } catch (ClassNotFoundException e) {
                return null;
            }
        }
        return null;
    }