3
3
import java .io .File ;
4
4
import java .io .IOException ;
5
5
import java .io .InputStream ;
6
+ import java .lang .annotation .Annotation ;
6
7
import java .lang .reflect .Field ;
8
+ import java .lang .reflect .InvocationTargetException ;
7
9
import java .net .MalformedURLException ;
8
10
import java .net .URL ;
9
11
import java .net .URLClassLoader ;
12
14
import java .nio .file .Path ;
13
15
import java .nio .file .StandardCopyOption ;
14
16
import java .nio .file .StandardOpenOption ;
15
- import java .util .ArrayList ;
16
17
import java .util .Collection ;
17
18
import java .util .Comparator ;
18
19
import java .util .List ;
38
39
import org .slf4j .LoggerFactory ;
39
40
import org .springframework .beans .factory .annotation .Value ;
40
41
41
- import dev .dsf .common .documentation .Documentation ;
42
-
43
42
public class ConfigDocGenerator
44
43
{
45
44
private static final Logger logger = LoggerFactory .getLogger (ConfigDocGenerator .class );
@@ -55,16 +54,55 @@ private static record DocumentationEntry(String propertyName, String value)
55
54
}
56
55
57
56
private final Path projectBuildDirectory ;
58
- private final List <String > compileClasspathElements = new ArrayList <>();
57
+ private final URLClassLoader classLoader ;
58
+ private final Class <? extends Annotation > coreDocumentationAnnotationClass ;
59
59
60
60
public ConfigDocGenerator (Path projectBuildDirectory , List <String > compileClasspathElements )
61
61
{
62
62
Objects .requireNonNull (projectBuildDirectory , "projectBuildDirectory" );
63
63
64
64
this .projectBuildDirectory = projectBuildDirectory ;
65
+ classLoader = classLoader (compileClasspathElements );
66
+ coreDocumentationAnnotationClass = loadCoreDocumentationAnnotation (classLoader );
67
+ }
65
68
66
- if (compileClasspathElements != null )
67
- this .compileClasspathElements .addAll (compileClasspathElements );
69
+ private static URLClassLoader classLoader (List <String > compileClasspathElements )
70
+ {
71
+ URL [] classpathElements = compileClasspathElements .stream ().map (ConfigDocGenerator ::toUrl )
72
+ .filter (Objects ::nonNull ).toArray (URL []::new );
73
+
74
+ return new URLClassLoader (classpathElements , Thread .currentThread ().getContextClassLoader ());
75
+ }
76
+
77
+ private static URL toUrl (String path )
78
+ {
79
+ try
80
+ {
81
+ return new File (path ).toURI ().toURL ();
82
+ }
83
+ catch (MalformedURLException exception )
84
+ {
85
+ logger .warn ("Could not transform path '{}' to url, returning null - {}" , path , exception .getMessage ());
86
+ return null ;
87
+ }
88
+ }
89
+
90
+ @ SuppressWarnings ("unchecked" )
91
+ private static Class <? extends Annotation > loadCoreDocumentationAnnotation (URLClassLoader classLoader )
92
+ {
93
+ try
94
+ {
95
+ Class <?> clazz = classLoader .loadClass ("dev.dsf.common.documentation.Documentation" );
96
+ if (clazz .isAnnotation ())
97
+ return (Class <? extends Annotation >) clazz ;
98
+ }
99
+ catch (ClassNotFoundException e )
100
+ {
101
+ logger .info (
102
+ "DSF core documentation annotation not found on classpath, for process plugins this is not an error" );
103
+ }
104
+
105
+ return null ;
68
106
}
69
107
70
108
public void generateDocumentation (List <String > configDocPackages )
@@ -79,12 +117,14 @@ private void generateDocumentation(String configDocPackage)
79
117
80
118
moveExistingToBackup (file );
81
119
82
- URLClassLoader classLoader = classLoader ();
83
120
Reflections reflections = createReflections (classLoader , configDocPackage );
84
121
85
- Set <Field > dsfFields = reflections .getFieldsAnnotatedWith (Documentation .class );
86
- if (!dsfFields .isEmpty ())
87
- writeFields (dsfFields , dsfDocumentationGenerator (), file , configDocPackage );
122
+ if (coreDocumentationAnnotationClass != null )
123
+ {
124
+ Set <Field > dsfFields = reflections .getFieldsAnnotatedWith (coreDocumentationAnnotationClass );
125
+ if (!dsfFields .isEmpty ())
126
+ writeFields (dsfFields , dsfDocumentationGenerator (), file , configDocPackage );
127
+ }
88
128
89
129
// v1
90
130
Set <Field > processFieldsV1 = reflections
@@ -117,27 +157,6 @@ private Reflections createReflections(ClassLoader classLoader, String workingPac
117
157
return new Reflections (configurationBuilder );
118
158
}
119
159
120
- private URLClassLoader classLoader ()
121
- {
122
- URL [] classpathElements = compileClasspathElements .stream ().map (this ::toUrl ).filter (Objects ::nonNull )
123
- .toArray (URL []::new );
124
-
125
- return new URLClassLoader (classpathElements , Thread .currentThread ().getContextClassLoader ());
126
- }
127
-
128
- private URL toUrl (String path )
129
- {
130
- try
131
- {
132
- return new File (path ).toURI ().toURL ();
133
- }
134
- catch (MalformedURLException exception )
135
- {
136
- logger .warn ("Could not transform path '{}' to url, returning null - {}" , path , exception .getMessage ());
137
- return null ;
138
- }
139
- }
140
-
141
160
private <D > List <String > getPluginProcessNames (Class <D > processPluginDefinitionType , ClassLoader classLoader ,
142
161
String workingPackage , BiFunction <D , ClassLoader , List <String >> definitionToProcessNames )
143
162
{
@@ -338,7 +357,7 @@ private Function<Field, DocumentationEntry> dsfDocumentationGenerator()
338
357
{
339
358
return field ->
340
359
{
341
- Documentation documentation = field .getAnnotation (Documentation . class );
360
+ Object documentation = field .getAnnotation (coreDocumentationAnnotationClass );
342
361
Value value = field .getAnnotation (Value .class );
343
362
344
363
PropertyNameAndDefaultValue propertyNameAndDefaultValue = getPropertyNameAndDefaultValue (value );
@@ -352,11 +371,12 @@ private Function<Field, DocumentationEntry> dsfDocumentationGenerator()
352
371
? String .format ("%s or %s_FILE" , initialEnvironment , initialEnvironment )
353
372
: initialEnvironment ;
354
373
355
- String required = getDocumentationString ("Required" , documentation . required ( ) ? "Yes" : "No" );
374
+ String required = getDocumentationString ("Required" , getBoolean ( documentation , " required" ) ? "Yes" : "No" );
356
375
357
- String description = getDocumentationString ("Description" , documentation .description ());
358
- String recommendation = getDocumentationString ("Recommendation" , documentation .recommendation ());
359
- String example = getDocumentationStringMonospace ("Example" , documentation .example ());
376
+ String description = getDocumentationString ("Description" , getString (documentation , "description" ));
377
+ String recommendation = getDocumentationString ("Recommendation" ,
378
+ getString (documentation , "recommendation" ));
379
+ String example = getDocumentationStringMonospace ("Example" , getString (documentation , "example" ));
360
380
361
381
String defaultValueString = devalueValue != null && devalueValue .length () > 1
362
382
&& !"#{null}" .equals (devalueValue ) ? getDocumentationStringMonospace ("Default" , devalueValue ) : "" ;
@@ -369,6 +389,32 @@ private Function<Field, DocumentationEntry> dsfDocumentationGenerator()
369
389
};
370
390
}
371
391
392
+ private boolean getBoolean (Object coreDocumentationAnnotation , String methodName )
393
+ {
394
+ try
395
+ {
396
+ return Boolean .TRUE .equals (
397
+ coreDocumentationAnnotationClass .getDeclaredMethod (methodName ).invoke (coreDocumentationAnnotation ));
398
+ }
399
+ catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | SecurityException e )
400
+ {
401
+ throw new IllegalArgumentException (e );
402
+ }
403
+ }
404
+
405
+ private String getString (Object coreDocumentationAnnotation , String methodName )
406
+ {
407
+ try
408
+ {
409
+ return (String ) coreDocumentationAnnotationClass .getDeclaredMethod (methodName )
410
+ .invoke (coreDocumentationAnnotation );
411
+ }
412
+ catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | SecurityException e )
413
+ {
414
+ throw new IllegalArgumentException (e );
415
+ }
416
+ }
417
+
372
418
private String getDocumentationStringMonospace (String title , String value )
373
419
{
374
420
if (title == null || title .isBlank () || value == null || value .isBlank ())
0 commit comments