@@ -303,39 +303,116 @@ default List<ApiDoc> handleTagsApiDoc(List<ApiDoc> apiDocList) {
303303 return apiDocs ;
304304 }
305305
306+ /**
307+ * Retrieves the annotations of the specified class, including those inherited from its superclasses
308+ * and interfaces, but only considering mapping annotations for inheritance.
309+ *
310+ * <p>This method first checks if the specified class has both entry and mapping annotations. If it does,
311+ * it returns the annotations of the class directly. If not, it recursively retrieves the mapping annotations
312+ * from its superclasses and interfaces.</p>
313+ *
314+ * @param cls the class whose annotations are to be retrieved
315+ * @param frameworkAnnotations the framework annotations to be used for filtering
316+ * @return a list of annotations for the specified class, including inherited mapping annotations
317+ */
306318 default List <JavaAnnotation > getClassAnnotations (JavaClass cls , FrameworkAnnotations frameworkAnnotations ) {
319+ // Retrieve the annotations of the specified class
307320 List <JavaAnnotation > annotationsList = new ArrayList <>(cls .getAnnotations ());
308- boolean flag = annotationsList .stream ().anyMatch (item -> {
321+
322+ // Get entry annotations from framework annotations
323+ Map <String , EntryAnnotation > entryAnnotationMap = Objects .isNull (frameworkAnnotations .getEntryAnnotations ())
324+ ? Collections .emptyMap ()
325+ : frameworkAnnotations .getEntryAnnotations ();
326+
327+ // Get mapping annotations from framework annotations
328+ Map <String , MappingAnnotation > mappingAnnotationMap = Objects .isNull (frameworkAnnotations .getMappingAnnotations ())
329+ ? Collections .emptyMap ()
330+ : frameworkAnnotations .getMappingAnnotations ();
331+
332+ // Check if the class has both entry and mapping annotations
333+ boolean hasEntryAndMappingAnnotation = annotationsList .stream ().anyMatch (item -> {
309334 String annotationName = item .getType ().getValue ();
310335 String fullyName = item .getType ().getFullyQualifiedName ();
311- Map <String , EntryAnnotation > entryAnnotationMap = frameworkAnnotations .getEntryAnnotations ();
312- if (Objects .isNull (entryAnnotationMap )) {
313- entryAnnotationMap = Collections .emptyMap ();
314- }
315- Map <String , MappingAnnotation > mappingAnnotationMap = frameworkAnnotations .getMappingAnnotations ();
316- if (Objects .isNull (mappingAnnotationMap )) {
317- mappingAnnotationMap = Collections .emptyMap ();
318- }
319336 return (entryAnnotationMap .containsKey (annotationName ) || entryAnnotationMap .containsKey (fullyName )) &&
320337 (mappingAnnotationMap .containsKey (annotationName ) || mappingAnnotationMap .containsKey (fullyName ));
321338 });
322- // child override parent set
323- if (flag ) {
339+
340+ // If the class has both entry and mapping annotations, return its annotations directly
341+ if (hasEntryAndMappingAnnotation ) {
342+ return annotationsList ;
343+ }
344+
345+ // Inherit mapping annotations from superclass, if any
346+ JavaClass superJavaClass = cls .getSuperJavaClass ();
347+ if (Objects .nonNull (superJavaClass ) && !"Object" .equals (superJavaClass .getSimpleName ())) {
348+ List <JavaAnnotation > superAnnotations = this .getClassAnnotations (superJavaClass , frameworkAnnotations );
349+ annotationsList .addAll (superAnnotations );
350+ }
351+
352+ // Inherit mapping annotations from interfaces, if any
353+ List <JavaClass > interfaceList = cls .getInterfaces ();
354+ if (CollectionUtil .isNotEmpty (interfaceList )) {
355+ for (JavaClass javaInterface : interfaceList ) {
356+ List <JavaAnnotation > interfaceAnnotations = this .getClassAnnotations (javaInterface , frameworkAnnotations );
357+ annotationsList .addAll (interfaceAnnotations );
358+ }
359+ }
360+ return annotationsList ;
361+ }
362+
363+
364+ /**
365+ * Retrieves the annotations of the specified class, including those inherited from its superclasses
366+ * and interfaces, but only considering mapping annotations for inheritance.
367+ *
368+ * <p>This method retrieves the annotations of the specified class and recursively collects
369+ * mapping annotations from its superclasses and interfaces.</p>
370+ *
371+ * @param cls the class whose annotations are to be retrieved
372+ * @param mappingAnnotationMap the map of mapping annotations used to filter and inherit annotations
373+ * @return a list of annotations for the specified class, including inherited mapping annotations
374+ */
375+ default List <JavaAnnotation > getClassAnnotations (JavaClass cls , Map <String , MappingAnnotation > mappingAnnotationMap ) {
376+ // Retrieve the annotations of the specified class
377+ List <JavaAnnotation > annotationsList = new ArrayList <>(cls .getAnnotations ());
378+
379+
380+ // Check if the class has both mapping annotations
381+ boolean hasMappingAnnotation = annotationsList .stream ().anyMatch (item -> {
382+ String annotationName = item .getType ().getValue ();
383+ String fullyName = item .getType ().getFullyQualifiedName ();
384+ return (mappingAnnotationMap .containsKey (annotationName ) || mappingAnnotationMap .containsKey (fullyName ));
385+ });
386+
387+ // If the class has both mapping annotations, return its annotations directly
388+ if (hasMappingAnnotation ) {
324389 return annotationsList ;
325390 }
391+
392+ // Inherit mapping annotations from superclass, if any
326393 JavaClass superJavaClass = cls .getSuperJavaClass ();
327394 if (Objects .nonNull (superJavaClass ) && !"Object" .equals (superJavaClass .getSimpleName ())) {
328- annotationsList .addAll (getClassAnnotations (superJavaClass , frameworkAnnotations ));
395+ annotationsList .addAll (this .getClassAnnotations (superJavaClass , mappingAnnotationMap ).stream ()
396+ .filter (annotation -> mappingAnnotationMap .containsKey (annotation .getType ().getValue ()) ||
397+ mappingAnnotationMap .containsKey (annotation .getType ().getFullyQualifiedName ()))
398+ .collect (Collectors .toList ()));
329399 }
330- List <JavaClass > interfaseList = cls .getInterfaces ();
331- if (CollectionUtil .isNotEmpty (interfaseList )) {
332- for (JavaClass javaInterface : interfaseList ) {
333- annotationsList .addAll (getClassAnnotations (javaInterface , frameworkAnnotations ));
400+
401+ // Inherit mapping annotations from interfaces, if any
402+ List <JavaClass > interfaceList = cls .getInterfaces ();
403+ if (CollectionUtil .isNotEmpty (interfaceList )) {
404+ for (JavaClass javaInterface : interfaceList ) {
405+ annotationsList .addAll (this .getClassAnnotations (javaInterface , mappingAnnotationMap ).stream ()
406+ .filter (annotation -> mappingAnnotationMap .containsKey (annotation .getType ().getValue ()) ||
407+ mappingAnnotationMap .containsKey (annotation .getType ().getFullyQualifiedName ()))
408+ .collect (Collectors .toList ()));
334409 }
335410 }
411+
336412 return annotationsList ;
337413 }
338414
415+
339416 default List <ApiExceptionStatus > buildExceptionStatus (ProjectDocConfigBuilder projectBuilder ,
340417 Collection <JavaClass > javaClasses ,
341418 FrameworkAnnotations frameworkAnnotations ) {
@@ -418,9 +495,14 @@ default List<ApiMethodDoc> buildEntryPointMethod(
418495 boolean paramsDataToTree = projectBuilder .getApiConfig ().isParamsDataToTree ();
419496 ClassLoader classLoader = projectBuilder .getApiConfig ().getClassLoader ();
420497 String group = JavaClassUtil .getClassTagsValue (cls , DocTags .GROUP , Boolean .TRUE );
421- List <JavaAnnotation > classAnnotations = this .getClassAnnotations (cls , frameworkAnnotations );
498+ // Get mapping annotations
499+ Map <String , MappingAnnotation > mappingAnnotations = Objects .isNull (frameworkAnnotations .getMappingAnnotations ())
500+ ? Collections .emptyMap () : frameworkAnnotations .getMappingAnnotations ();
501+ // Get class mappingAnnotations from class and its parent class or interface
502+ List <JavaAnnotation > classAnnotations = this .getClassAnnotations (cls , mappingAnnotations );
503+
422504 String baseUrl = "" ;
423- // the requestMapping annotation's consumes value on class
505+ // The requestMapping annotation's consumes value on class
424506 String classMediaType = null ;
425507 Map <String , MappingAnnotation > mappingAnnotationMap = frameworkAnnotations .getMappingAnnotations ();
426508 for (JavaAnnotation annotation : classAnnotations ) {
@@ -1153,16 +1235,36 @@ default ApiRequestExample buildReqJson(DocJavaMethod javaMethod, ApiMethodDoc ap
11531235 return requestExample ;
11541236 }
11551237
1238+ /**
1239+ * Determines if the given Java class is a default entry point based on its annotations and the provided framework annotations.
1240+ *
1241+ * @param cls the Java class to check
1242+ * @param frameworkAnnotations the framework annotations to use for the check
1243+ * @return {@code true} if the class is a default entry point, {@code false} otherwise
1244+ */
11561245 default boolean defaultEntryPoint (JavaClass cls , FrameworkAnnotations frameworkAnnotations ) {
1246+ // Check if the class is an annotation or an enum, return false if it is
11571247 if (cls .isAnnotation () || cls .isEnum ()) {
11581248 return false ;
11591249 }
1250+
1251+ // Check if frameworkAnnotations is null, return false if it is
11601252 if (Objects .isNull (frameworkAnnotations )) {
11611253 return false ;
11621254 }
1163- List <JavaAnnotation > classAnnotations = DocClassUtil .getAnnotations (cls );
1255+
1256+ // Get framework entry annotations
11641257 Map <String , EntryAnnotation > entryAnnotationMap = frameworkAnnotations .getEntryAnnotations ();
11651258
1259+ // Check if entry annotations are null, return false if they are
1260+ if (Objects .isNull (frameworkAnnotations .getEntryAnnotations ())) {
1261+ return false ;
1262+ }
1263+
1264+ // Get class annotations; Note: Spring Entry Annotation is not supported for superclass inheritance
1265+ List <JavaAnnotation > classAnnotations = cls .getAnnotations ();
1266+
1267+ // Check if any of the class annotations match the entry annotations
11661268 return classAnnotations .stream ().anyMatch (annotation -> {
11671269 String name = annotation .getType ().getValue ();
11681270 return entryAnnotationMap .containsKey (name );
0 commit comments