1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package io.wcm.caravan.maven.plugins.haldocs;
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.net.URLClassLoader;
25 import java.util.Set;
26
27 import org.apache.maven.plugin.MojoExecutionException;
28 import org.apache.maven.plugin.MojoFailureException;
29 import org.apache.maven.plugins.annotations.LifecyclePhase;
30 import org.apache.maven.plugins.annotations.Mojo;
31 import org.apache.maven.plugins.annotations.Parameter;
32 import org.codehaus.plexus.util.SelectorUtils;
33
34 import com.fasterxml.jackson.databind.ObjectMapper;
35 import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
36 import com.fasterxml.jackson.module.jsonSchema.factories.SchemaFactoryWrapper;
37 import com.google.common.reflect.ClassPath;
38
39
40
41
42
43 @Mojo(name = "generate-json-schema", defaultPhase = LifecyclePhase.PROCESS_CLASSES, requiresProject = true, threadSafe = true)
44 public class GenerateJsonSchemaMojo extends AbstractBaseMojo {
45
46
47
48
49 @Parameter(defaultValue = "${project.build.directory}/classes")
50 private String source;
51
52
53
54
55 @Parameter(required = true)
56 private Set<String> includes;
57
58
59
60
61 @Parameter
62 private Set<String> excludes;
63
64
65
66
67 @Parameter(defaultValue = "JSON-SCHEMA-INF")
68 private String target;
69
70 @Parameter(defaultValue = "generated-json-schema-resources")
71 private String generatedResourcesDirectory;
72
73 private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
74
75 @Override
76 public void execute() throws MojoExecutionException, MojoFailureException {
77 try {
78 File classesDirectory = getSourceDirectory();
79 if (!classesDirectory.exists()) {
80 return;
81 }
82
83
84
85 ClassLoader compileClassLoader = URLClassLoader.newInstance(getCompileClasspathElementURLs(), getClass().getClassLoader());
86
87
88 ClassPath.from(compileClassLoader).getTopLevelClasses().stream()
89 .filter(info -> isIncluded(info.getName()) && !isExcluded(info.getName()))
90 .map(info -> info.load())
91 .forEach(this::generateSchema);
92
93
94 addResource(getGeneratedResourcesDirectory().getPath(), target);
95 }
96 catch (Throwable ex) {
97 throw new MojoExecutionException("Generating JSON Schema files failed: " + ex.getMessage(), ex);
98 }
99 }
100
101
102
103
104
105
106 private boolean isIncluded(String className) {
107 if (includes == null || includes.size() == 0) {
108
109 return false;
110 }
111 return includes.stream()
112 .filter(pattern -> SelectorUtils.matchPath(pattern, className, ".", true))
113 .count() > 0;
114 }
115
116
117
118
119
120
121 private boolean isExcluded(String className) {
122 if (excludes == null || excludes.size() == 0) {
123 return false;
124 }
125 return excludes.stream()
126 .filter(pattern -> SelectorUtils.matchPath(pattern, className, ".", true))
127 .count() == 0;
128 }
129
130
131
132
133
134 private void generateSchema(Class clazz) {
135 try {
136 File targetFile = new File(getGeneratedResourcesDirectory(), clazz.getName() + ".json");
137 getLog().info("Generate JSON schema: " + targetFile.getName());
138 SchemaFactoryWrapper schemaFactory = new SchemaFactoryWrapper();
139 OBJECT_MAPPER.acceptJsonFormatVisitor(OBJECT_MAPPER.constructType(clazz), schemaFactory);
140 JsonSchema jsonSchema = schemaFactory.finalSchema();
141 OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValue(targetFile, jsonSchema);
142 }
143 catch (IOException ex) {
144 throw new RuntimeException(ex);
145 }
146 }
147
148
149
150
151
152
153 private File getSourceDirectory() throws IOException {
154 File file = new File(source);
155 if (!file.isDirectory()) {
156 getLog().debug("Could not find directory at '" + source + "'");
157 }
158 return file.getCanonicalFile();
159 }
160
161 @Override
162 protected String getGeneratedResourcesDirectoryPath() {
163 return generatedResourcesDirectory;
164 }
165
166 }