[maven plugin] Use configurator for maven plugin

see swagger-api/swagger-codegen#2104
This commit is contained in:
Jim Schubert 2016-02-17 22:33:39 -05:00
parent c4d799a4a7
commit 702d019bf8
4 changed files with 229 additions and 177 deletions

View File

@ -5,18 +5,11 @@ import io.airlift.airline.Option;
import io.swagger.codegen.ClientOptInput;
import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.DefaultGenerator;
import io.swagger.codegen.utils.OptionUtils;
import io.swagger.codegen.config.CodegenConfigurator;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static io.swagger.codegen.config.CodegenConfiguratorUtils.*;
import static org.apache.commons.lang3.StringUtils.isNotEmpty;
/**
@ -176,74 +169,15 @@ public class Generate implements Runnable {
configurator.setLibrary(library);
}
setSystemProperties(configurator);
setInstantiationTypes(configurator);
setImportMappings(configurator);
setTypeMappings(configurator);
setAdditionalProperties(configurator);
setLanguageSpecificPrimitives(configurator);
applySystemPropertiesKvp(systemProperties, configurator);
applyInstantiationTypesKvp(instantiationTypes, configurator);
applyImportMappingsKvp(importMappings, configurator);
applyTypeMappingsKvp(typeMappings, configurator);
applyAdditionalPropertiesKvp(additionalProperties, configurator);
applyLanguageSpecificPrimitivesCsv(languageSpecificPrimitives, configurator);
final ClientOptInput clientOptInput = configurator.toClientOptInput();
new DefaultGenerator().opts(clientOptInput).generate();
}
private void setSystemProperties(CodegenConfigurator configurator) {
final Map<String, String> map = createMapFromKeyValuePairs(systemProperties);
for (Map.Entry<String, String> entry : map.entrySet()) {
configurator.addSystemProperty(entry.getKey(), entry.getValue());
}
}
private void setInstantiationTypes(CodegenConfigurator configurator) {
final Map<String, String> map = createMapFromKeyValuePairs(instantiationTypes);
for (Map.Entry<String, String> entry : map.entrySet()) {
configurator.addInstantiationType(entry.getKey(), entry.getValue());
}
}
private void setImportMappings(CodegenConfigurator configurator) {
final Map<String, String> map = createMapFromKeyValuePairs(importMappings);
for (Map.Entry<String, String> entry : map.entrySet()) {
configurator.addImportMapping(entry.getKey(), entry.getValue());
}
}
private void setTypeMappings(CodegenConfigurator configurator) {
final Map<String, String> map = createMapFromKeyValuePairs(typeMappings);
for (Map.Entry<String, String> entry : map.entrySet()) {
configurator.addTypeMapping(entry.getKey(), entry.getValue());
}
}
private void setAdditionalProperties(CodegenConfigurator configurator) {
final Map<String, String> map = createMapFromKeyValuePairs(additionalProperties);
for (Map.Entry<String, String> entry : map.entrySet()) {
configurator.addAdditionalProperty(entry.getKey(), entry.getValue());
}
}
private void setLanguageSpecificPrimitives(CodegenConfigurator configurator) {
final Set<String> set = createSetFromCsvList(languageSpecificPrimitives);
for (String item : set) {
configurator.addLanguageSpecificPrimitive(item);
}
}
private static Set<String> createSetFromCsvList(String csvProperty) {
final List<String> values = OptionUtils.splitCommaSeparatedList(csvProperty);
return new HashSet<String>(values);
}
private static Map<String, String> createMapFromKeyValuePairs(String commaSeparatedKVPairs) {
final List<Pair<String, String>> pairs = OptionUtils.parseCommaSeparatedTuples(commaSeparatedKVPairs);
Map<String, String> result = new HashMap<String, String>();
for (Pair<String, String> pair : pairs) {
result.put(pair.getLeft(), pair.getRight());
}
return result;
}
}

View File

@ -1,16 +0,0 @@
package io.swagger.codegen.plugin;
/**
* User: lanwen
* Date: 24.03.15
* Time: 14:47
*/
public final class AdditionalParams {
public static final String TEMPLATE_DIR_PARAM = "templateDir";
public static final String MODEL_PACKAGE_PARAM = "modelPackage";
public static final String API_PACKAGE_PARAM = "apiPackage";
public static final String INVOKER_PACKAGE_PARAM = "invokerPackage";
public static final String LIBRARY_PARAM = "library";
private AdditionalParams() {}
}

View File

@ -16,13 +16,13 @@ package io.swagger.codegen.plugin;
* limitations under the License.
*/
import config.Config;
import config.ConfigParser;
import io.swagger.codegen.*;
import io.swagger.codegen.utils.OptionUtils;
import io.swagger.codegen.CliOption;
import io.swagger.codegen.ClientOptInput;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.DefaultGenerator;
import io.swagger.codegen.config.CodegenConfigurator;
import io.swagger.models.Swagger;
import io.swagger.parser.SwaggerParser;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
@ -33,17 +33,27 @@ import org.apache.maven.project.MavenProject;
import java.io.File;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static io.swagger.codegen.plugin.AdditionalParams.*;
import static io.swagger.codegen.config.CodegenConfiguratorUtils.*;
import static org.apache.commons.lang3.StringUtils.isNotEmpty;
/**
* Goal which generates client/server code from a swagger json/yaml definition.
*/
@Mojo(name = "generate", defaultPhase = LifecyclePhase.GENERATE_SOURCES)
public class CodeGenMojo extends AbstractMojo {
@Parameter(name="verbose", required = false, defaultValue = "false")
private boolean verbose;
/**
* Client language to generate.
*/
@Parameter(name = "language", required = true)
private String language;
/**
* Location of the output directory.
*/
@ -65,10 +75,23 @@ public class CodeGenMojo extends AbstractMojo {
private File templateDirectory;
/**
* The package to use for generated model objects/classes
* Adds authorization headers when fetching the swagger definitions remotely.
" Pass in a URL-encoded string of name:header with a comma separating multiple values
*/
@Parameter(name = "modelPackage")
private String modelPackage;
@Parameter(name="auth")
private String auth;
/**
* Path to separate json configuration file.
*/
@Parameter(name = "configurationFile", required = false)
private String configurationFile;
/**
* Specifies if the existing files should be overwritten during the generation.
*/
@Parameter(name="skipOverwrite", required=false)
private Boolean skipOverwrite;
/**
* The package to use for generated api objects/classes
@ -76,6 +99,12 @@ public class CodeGenMojo extends AbstractMojo {
@Parameter(name = "apiPackage")
private String apiPackage;
/**
* The package to use for generated model objects/classes
*/
@Parameter(name = "modelPackage")
private String modelPackage;
/**
* The package to use for the generated invoker objects
*/
@ -83,16 +112,22 @@ public class CodeGenMojo extends AbstractMojo {
private String invokerPackage;
/**
* Client language to generate.
* groupId in generated pom.xml
*/
@Parameter(name = "language", required = true)
private String language;
@Parameter(name = "groupId")
private String groupId;
/**
* Path to separate json configuration file.
* artifactId in generated pom.xml
*/
@Parameter(name = "configurationFile", required = false)
private String configurationFile;
@Parameter(name = "artifactId")
private String artifactId;
/**
* artifact version in generated pom.xml
*/
@Parameter(name = "artifactVersion")
private String artifactVersion;
/**
* Sets the library
@ -127,12 +162,92 @@ public class CodeGenMojo extends AbstractMojo {
@Override
public void execute() throws MojoExecutionException {
Swagger swagger = new SwaggerParser().read(inputSpec);
CodegenConfig config = CodegenConfigLoader.forName(language);
config.setOutputDir(output.getAbsolutePath());
//attempt to read from config file
CodegenConfigurator configurator = CodegenConfigurator.fromFile(configurationFile);
//if a config file wasn't specified or we were unable to read it
if(configurator == null) {
configurator = new CodegenConfigurator();
}
configurator.setVerbose(verbose);
if(skipOverwrite != null) {
configurator.setSkipOverwrite(skipOverwrite);
}
if(isNotEmpty(inputSpec)) {
configurator.setInputSpec(inputSpec);
}
configurator.setLang(language);
configurator.setOutputDir(output.getAbsolutePath());
if(isNotEmpty(auth)) {
configurator.setAuth(auth);
}
if(isNotEmpty(apiPackage)) {
configurator.setApiPackage(apiPackage);
}
if(isNotEmpty(modelPackage)) {
configurator.setModelPackage(modelPackage);
}
if(isNotEmpty(invokerPackage)) {
configurator.setInvokerPackage(invokerPackage);
}
if(isNotEmpty(groupId)) {
configurator.setGroupId(groupId);
}
if(isNotEmpty(artifactId)) {
configurator.setArtifactId(artifactId);
}
if(isNotEmpty(artifactVersion)) {
configurator.setArtifactVersion(artifactVersion);
}
if(isNotEmpty(library)) {
configurator.setLibrary(library);
}
if (null != templateDirectory) {
configurator.setTemplateDir(templateDirectory.getAbsolutePath());
}
if (configOptions != null) {
if(configOptions.containsKey("instantiation-types")) {
applyInstantiationTypesKvp(configOptions.get("instantiation-types").toString(), configurator);
}
if(configOptions.containsKey("import-mappings")) {
applyImportMappingsKvp(configOptions.get("import-mappings").toString(), configurator);
}
if(configOptions.containsKey("type-mappings")) {
applyTypeMappingsKvp(configOptions.get("type-mappings").toString(), configurator);
}
if(configOptions.containsKey("language-specific-primitives")) {
applyLanguageSpecificPrimitivesCsv(configOptions.get("language-specific-primitives").toString(), configurator);
}
if(configOptions.containsKey("additional-properties")) {
applyAdditionalPropertiesKvp(configOptions.get("additional-properties").toString(), configurator);
}
}
if (environmentVariables != null) {
for(String key : environmentVariables.keySet()) {
String value = environmentVariables.get(key);
if(value == null) {
@ -140,58 +255,21 @@ public class CodeGenMojo extends AbstractMojo {
value = "";
}
System.setProperty(key, value);
}
}
if (null != library) {
config.setLibrary(library);
}
if (null != templateDirectory) {
config.additionalProperties().put(TEMPLATE_DIR_PARAM, templateDirectory.getAbsolutePath());
}
if (null != modelPackage) {
config.additionalProperties().put(MODEL_PACKAGE_PARAM, modelPackage);
}
if (null != apiPackage) {
config.additionalProperties().put(API_PACKAGE_PARAM, apiPackage);
}
if (null != invokerPackage) {
config.additionalProperties().put(INVOKER_PACKAGE_PARAM, invokerPackage);
}
Set<String> definedOptions = new HashSet<String>();
for (CliOption langCliOption : config.cliOptions()) {
definedOptions.add(langCliOption.getOpt());
}
if (configOptions != null) {
if(configOptions.containsKey("import-mappings")) {
Map<String, String> mappings = createMapFromKeyValuePairs(configOptions.remove("import-mappings").toString());
config.importMapping().putAll(mappings);
}
if(configOptions.containsKey("type-mappings")) {
Map<String, String> mappings = createMapFromKeyValuePairs(configOptions.remove("type-mappings").toString());
config.typeMapping().putAll(mappings);
}
if(configOptions.containsKey("instantiation-types")) {
Map<String, String> mappings = createMapFromKeyValuePairs(configOptions.remove("instantiation-types").toString());
config.instantiationTypes().putAll(mappings);
}
addAdditionalProperties(config, definedOptions, configOptions);
}
if (null != configurationFile) {
Config genConfig = ConfigParser.read(configurationFile);
if (null != genConfig) {
addAdditionalProperties(config, definedOptions, genConfig.getOptions());
} else {
throw new RuntimeException("Unable to read configuration file");
configurator.addSystemProperty(key, value);
}
}
ClientOptInput input = new ClientOptInput().opts(new ClientOpts()).swagger(swagger);
input.setConfig(config);
final ClientOptInput input = configurator.toClientOptInput();
final CodegenConfig config = input.getConfig();
if(configOptions != null) {
for (CliOption langCliOption : config.cliOptions()) {
if (configOptions.containsKey(langCliOption.getOpt())) {
input.getConfig().additionalProperties().put(langCliOption.getOpt(),
configOptions.get(langCliOption.getOpt()));
}
}
}
if(configHelp) {
for (CliOption langCliOption : config.cliOptions()) {
@ -215,25 +293,4 @@ public class CodeGenMojo extends AbstractMojo {
project.addCompileSourceRoot(output.toString());
}
}
private void addAdditionalProperties(CodegenConfig config, Set<String> definedOptions, Map<?,?> configOptions) {
for(Map.Entry<?, ?> configEntry : configOptions.entrySet()) {
config.additionalProperties().put(configEntry.getKey().toString(), configEntry.getValue());
if(!definedOptions.contains(configEntry.getKey())) {
getLog().warn("Additional property: " + configEntry.getKey() + " is not defined for this language.");
}
}
}
private static Map<String, String> createMapFromKeyValuePairs(String commaSeparatedKVPairs) {
final List<Pair<String, String>> pairs = OptionUtils.parseCommaSeparatedTuples(commaSeparatedKVPairs);
Map<String, String> result = new HashMap<String, String>();
for (Pair<String, String> pair : pairs) {
result.put(pair.getLeft(), pair.getRight());
}
return result;
}
}

View File

@ -0,0 +1,77 @@
package io.swagger.codegen.config;
import io.swagger.codegen.utils.OptionUtils;
import org.apache.commons.lang3.tuple.Pair;
import java.util.*;
/**
* Contains shared logic for applying key-value pairs and CSV strings
* to specific settings in CodegenConfigurator.
*
* <p>
* This class exists to facility in testing. These methods could be applied
* to CodegenConfigurator, but this complicates things when mocking CodegenConfigurator.
* </p>
*/
public final class CodegenConfiguratorUtils {
public static void applySystemPropertiesKvp(String systemProperties, CodegenConfigurator configurator) {
final Map<String, String> map = createMapFromKeyValuePairs(systemProperties);
for (Map.Entry<String, String> entry : map.entrySet()) {
configurator.addSystemProperty(entry.getKey(), entry.getValue());
}
}
public static void applyInstantiationTypesKvp(String instantiationTypes, CodegenConfigurator configurator) {
final Map<String, String> map = createMapFromKeyValuePairs(instantiationTypes);
for (Map.Entry<String, String> entry : map.entrySet()) {
configurator.addInstantiationType(entry.getKey(), entry.getValue());
}
}
public static void applyImportMappingsKvp(String importMappings, CodegenConfigurator configurator) {
final Map<String, String> map = createMapFromKeyValuePairs(importMappings);
for (Map.Entry<String, String> entry : map.entrySet()) {
configurator.addImportMapping(entry.getKey(), entry.getValue());
}
}
public static void applyTypeMappingsKvp(String typeMappings, CodegenConfigurator configurator) {
final Map<String, String> map = createMapFromKeyValuePairs(typeMappings);
for (Map.Entry<String, String> entry : map.entrySet()) {
configurator.addTypeMapping(entry.getKey(), entry.getValue());
}
}
public static void applyAdditionalPropertiesKvp(String additionalProperties, CodegenConfigurator configurator) {
final Map<String, String> map = createMapFromKeyValuePairs(additionalProperties);
for (Map.Entry<String, String> entry : map.entrySet()) {
configurator.addAdditionalProperty(entry.getKey(), entry.getValue());
}
}
public static void applyLanguageSpecificPrimitivesCsv(String languageSpecificPrimitives, CodegenConfigurator configurator) {
final Set<String> set = createSetFromCsvList(languageSpecificPrimitives);
for (String item : set) {
configurator.addLanguageSpecificPrimitive(item);
}
}
private static Set<String> createSetFromCsvList(String csvProperty) {
final List<String> values = OptionUtils.splitCommaSeparatedList(csvProperty);
return new HashSet<String>(values);
}
private static Map<String, String> createMapFromKeyValuePairs(String commaSeparatedKVPairs) {
final List<Pair<String, String>> pairs = OptionUtils.parseCommaSeparatedTuples(commaSeparatedKVPairs);
Map<String, String> result = new HashMap<String, String>();
for (Pair<String, String> pair : pairs) {
result.put(pair.getLeft(), pair.getRight());
}
return result;
}
}