in code-generation/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/GenerateMojo.java [98:197]
public void execute()
throws MojoExecutionException {
if(skip) {
getLog().info("Skipping code-generation as 'skip' was set to 'true'.");
return;
}
// Make sure the output directory exists.
if (!outputDir.exists()) {
if (!outputDir.mkdirs()) {
throw new MojoExecutionException("Could not generate output directory " + outputDir.getAbsolutePath());
}
}
// Build a classloader that can access the projects classpath (read from dependencies)
ClassLoader moduleClassloader;
try {
Set<Artifact> artifacts = project.getArtifacts();
List<URL> classpathElements = new ArrayList<>(artifacts.size() + 1);
// Add the normal class output (needed for embedded schemas)
classpathElements.add(new File(project.getBuild().getOutputDirectory()).toURI().toURL());
// Add all the other artifacts (no matter what scope)
for (Artifact artifact : artifacts) {
classpathElements.add(artifact.getFile().toURI().toURL());
}
moduleClassloader = new URLClassLoader(
classpathElements.toArray(new URL[0]), GenerateMojo.class.getClassLoader());
} catch (MalformedURLException e) {
throw new MojoExecutionException(
"Error creating classloader for loading message format schema from module dependencies", e);
}
// Load the protocol module.
Protocol protocol = null;
ServiceLoader<Protocol> protocols = ServiceLoader.load(Protocol.class, moduleClassloader);
for (Protocol curProtocol : protocols) {
if (curProtocol.getName().equalsIgnoreCase(protocolName)) {
final boolean pluginExecutionWithoutVersion = protocolVersion == null;
final boolean noVersionAtAll = pluginExecutionWithoutVersion && curProtocol.getVersion().isEmpty();
final boolean versionMatches = !pluginExecutionWithoutVersion && curProtocol.getVersion().map(s -> s.equals(protocolVersion)).orElse(false);
if (noVersionAtAll || versionMatches) {
protocol = curProtocol;
break;
}
}
}
if (protocol == null) {
String version = (protocolVersion == null) ? "undefined" : protocolVersion;
throw new MojoExecutionException(
"Unable to find protocol specification module '" + protocolName + "' with version '" + version + "' on modules classpath");
}
// Load the language module.
LanguageOutput language = null;
ServiceLoader<LanguageOutput> languages = ServiceLoader.load(LanguageOutput.class, moduleClassloader);
for (LanguageOutput curLanguage : languages) {
if (curLanguage.getName().equalsIgnoreCase(languageName)) {
language = curLanguage;
break;
}
}
if (language == null) {
throw new MojoExecutionException(
"Unable to find language output module '" + languageName + "' on modules classpath");
}
// Check if the selected language flavor is supported by the selected language module.
if (!language.supportedOutputFlavors().contains(outputFlavor)) {
throw new MojoExecutionException(
"The selected language output module: " + languageName +
" doesn't support the output flavor: " + outputFlavor + "." +
" Supported output flavors are: " + String.join(", ", language.supportedOutputFlavors()));
}
try {
// Parse the type definitions.
TypeContext typeContext = protocol.getTypeContext();
Map<String, TypeDefinition> types = typeContext.getTypeDefinitions();
// Parse and validate the options.
Set<String> supportedOptions = language.supportedOptions();
Map<String, Object> optionsMap = new HashMap<>();
if (options != null) {
optionsMap = parseOptions(options);
for (String optionName : optionsMap.keySet()) {
if (!supportedOptions.contains(optionName)) {
throw new MojoExecutionException("Unsupported option '" + optionName + "' for language " + languageName);
}
}
}
// Generate output for the type definitions.
language.generate(outputDir, project.getVersion(), languageName, protocolName, outputFlavor, types, optionsMap);
} catch (GenerationException e) {
throw new MojoExecutionException("Error generating sources", e);
}
// Add the generated sources to the project internally.
project.addCompileSourceRoot(outputDir.getPath());
}