Home / Class/ TypeExtractor Class — spring-boot Architecture

TypeExtractor Class — spring-boot Architecture

Architecture documentation for the TypeExtractor class in TypeUtils.java from the spring-boot codebase.

Entity Profile

Source Code

configuration-metadata/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/TypeUtils.java lines 289–389

	private static class TypeExtractor extends SimpleTypeVisitor8<String, TypeDescriptor> {

		private final Types types;

		TypeExtractor(Types types) {
			this.types = types;
		}

		@Override
		public String visitDeclared(DeclaredType type, TypeDescriptor descriptor) {
			TypeElement enclosingElement = getEnclosingTypeElement(type);
			String qualifiedName = determineQualifiedName(type, enclosingElement);
			if (type.getTypeArguments().isEmpty()) {
				return qualifiedName;
			}
			StringBuilder name = new StringBuilder();
			name.append(qualifiedName);
			name.append("<")
				.append(type.getTypeArguments()
					.stream()
					.map((t) -> visit(t, descriptor))
					.collect(Collectors.joining(",")))
				.append(">");
			return name.toString();
		}

		private String determineQualifiedName(DeclaredType type, TypeElement enclosingElement) {
			if (enclosingElement != null) {
				return getQualifiedName(enclosingElement) + "$" + type.asElement().getSimpleName();
			}
			return getQualifiedName(type.asElement());
		}

		@Override
		public String visitTypeVariable(TypeVariable typeVariable, TypeDescriptor descriptor) {
			TypeMirror resolvedGeneric = descriptor.resolveGeneric(typeVariable);
			if (resolvedGeneric != null) {
				if (resolvedGeneric instanceof TypeVariable resolveTypeVariable) {
					// Still unresolved, let's use the upper bound, checking first if
					// a cycle may exist
					if (!hasCycle(resolveTypeVariable)) {
						return visit(resolveTypeVariable.getUpperBound(), descriptor);
					}
				}
				else {
					return visit(resolvedGeneric, descriptor);
				}
			}
			// Fallback to simple representation of the upper bound
			return defaultAction(typeVariable.getUpperBound(), descriptor);
		}

		private boolean hasCycle(TypeVariable variable) {
			TypeMirror upperBound = variable.getUpperBound();
			if (upperBound instanceof DeclaredType declaredType) {
				return declaredType.getTypeArguments().stream().anyMatch((candidate) -> candidate.equals(variable));
			}
			return false;
		}

		@Override
		public String visitArray(ArrayType t, TypeDescriptor descriptor) {
			return t.getComponentType().accept(this, descriptor) + "[]";
		}

		@Override
		public String visitPrimitive(PrimitiveType t, TypeDescriptor descriptor) {
			return this.types.boxedClass(t).getQualifiedName().toString();
		}

		@Override
		protected String defaultAction(TypeMirror t, TypeDescriptor descriptor) {
			return t.toString();
		}

		String getQualifiedName(Element element) {
			if (element == null) {
				return null;
			}
			TypeElement enclosingElement = getEnclosingTypeElement(element.asType());
			if (enclosingElement != null) {
				return getQualifiedName(enclosingElement) + "$"
						+ ((DeclaredType) element.asType()).asElement().getSimpleName();
			}
			if (element instanceof TypeElement typeElement) {
				return typeElement.getQualifiedName().toString();
			}
			throw new IllegalStateException("Could not extract qualified name from " + element);
		}

		private TypeElement getEnclosingTypeElement(TypeMirror type) {
			if (type instanceof DeclaredType declaredType) {
				Element enclosingElement = declaredType.asElement().getEnclosingElement();
				if (enclosingElement instanceof TypeElement typeElement) {
					return typeElement;
				}
			}
			return null;
		}

	}

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free