UNPKG

103 kBJavaScriptView Raw
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3 return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5Object.defineProperty(exports, "__esModule", { value: true });
6/* tslint:disable:variable-name */
7const ExampleGenerator_1 = __importDefault(require("./examples/ExampleGenerator"));
8const CliOption_1 = __importDefault(require("./CliOption"));
9const CodegenConstants_1 = __importDefault(require("./CodegenConstants"));
10const CodegenModelFactory_1 = __importDefault(require("./CodegenModelFactory"));
11const CodegenModelType_1 = __importDefault(require("./CodegenModelType"));
12const camelCase_1 = __importDefault(require("lodash/camelCase"));
13const factory_1 = __importDefault(require("./models/factory"));
14const properties_1 = require("./models/properties");
15const parameters_1 = require("./models/parameters");
16const System_1 = __importDefault(require("./java/System"));
17const LoggerFactory_1 = __importDefault(require("./java/LoggerFactory"));
18const File_1 = __importDefault(require("./java/File"));
19const StringBuilder_1 = __importDefault(require("./java/StringBuilder"));
20const javaUtil_1 = require("./java/javaUtil");
21const StringUtils_1 = __importDefault(require("./java/StringUtils"));
22const Json_1 = __importDefault(require("./java/Json"));
23const StringEscapeUtils_1 = __importDefault(require("./java/StringEscapeUtils"));
24const ArrayModel_1 = __importDefault(require("./models/ArrayModel"));
25const ComposedModel_1 = __importDefault(require("./models/ComposedModel"));
26const ModelImpl_1 = __importDefault(require("./models/ModelImpl"));
27const RefModel_1 = __importDefault(require("./models/RefModel"));
28const ApiKeyAuthDefinition_1 = __importDefault(require("./models/auth/ApiKeyAuthDefinition"));
29const BasicAuthDefinition_1 = __importDefault(require("./models/auth/BasicAuthDefinition"));
30const In_1 = require("./models/auth/In");
31const PropertyBuilder_1 = __importDefault(require("./models/PropertyBuilder"));
32const path_1 = __importDefault(require("path"));
33const _count2 = (_, i) => ++i;
34const COMMON_PREFIX_RE = new RegExp('[a-zA-Z0-9]+\\z', 'g');
35const sortByFlag = (one, another) => {
36 const oneRequired = one.required == null ? false : one.required;
37 const anotherRequired = another.required == null ? false : another.required;
38 if (oneRequired === anotherRequired) {
39 return 0;
40 }
41 else if (oneRequired) {
42 return -1;
43 }
44 else {
45 return 1;
46 }
47};
48class DefaultCodegen {
49 /**
50 * Default constructor.
51 * This method will map between Swagger type and language-specified type, as well as mapping
52 * between Swagger type and the corresponding import statement for the language. This will
53 * also add some language specified CLI options, if any.
54 *
55 *
56 * returns string presentation of the example path (it's a constructor)
57 */
58 constructor() {
59 this.__outputFolder = '';
60 this.__languageSpecificPrimitives = javaUtil_1.newHashSet();
61 this.__modelPackage = '';
62 this.__apiPackage = '';
63 this.modelNamePrefix = '';
64 this.modelNameSuffix = '';
65 this.__testPackage = '';
66 this.__apiTemplateFiles = javaUtil_1.newHashMap();
67 this.__apiDataTemplateFile = javaUtil_1.newHashMap();
68 this.__modelTemplateFiles = javaUtil_1.newHashMap();
69 this.__apiTestTemplateFiles = javaUtil_1.newHashMap();
70 this.__modelTestTemplateFiles = javaUtil_1.newHashMap();
71 this.__apiDocTemplateFiles = javaUtil_1.newHashMap();
72 this.__modelDocTemplateFiles = javaUtil_1.newHashMap();
73 this.commonTemplateDir = '_common';
74 this.__additionalProperties = javaUtil_1.newHashMap();
75 this.__vendorExtensions = javaUtil_1.newHashMap();
76 this.__supportingFiles = [];
77 this.__cliOptions = [];
78 this.__supportedLibraries = javaUtil_1.newHashMap();
79 this.sortParamsByRequiredFlag = true;
80 this.ensureUniqueParams = true;
81 this.specialCharReplacements = javaUtil_1.newHashMap();
82 this.skipOverwrite = false;
83 this.supportsInheritance = false;
84 this.__defaultIncludes = javaUtil_1.newHashSet('double', 'int', 'long', 'short', 'char', 'float', 'String', 'boolean', 'Boolean', 'Double', 'Void', 'Integer', 'Long', 'Float');
85 this.__typeMapping = javaUtil_1.newHashMap(['array', 'List'], ['map', 'Map'], ['List', 'List'], ['boolean', 'Boolean'], ['string', 'String'], ['int', 'Integer'], ['float', 'Float'], ['number', 'BigDecimal'], ['DateTime', 'Date'], ['long', 'Long'], ['short', 'Short'], ['char', 'String'], ['double', 'Double'], ['object', 'Object'], ['integer', 'Integer'], ['ByteArray', 'byte[]'], ['binary', 'byte[]']);
86 this.__instantiationTypes = javaUtil_1.newHashMap();
87 this.__reservedWords = javaUtil_1.newHashSet();
88 this.__importMapping = javaUtil_1.newHashMap(['BigDecimal', 'java.math.BigDecimal'], ['UUID', 'java.util.UUID'], ['File', 'java.io.File'], ['Date', 'java.util.Date'], ['Timestamp', 'java.sql.Timestamp'], ['Map', 'java.util.Map'], ['HashMap', 'java.util.HashMap'], ['Array', 'java.util.List'], ['ArrayList', 'java.util.ArrayList'], ['List', 'java.util.*'], ['Set', 'java.util.*'], ['DateTime', 'org.joda.time.*'], ['LocalDateTime', 'org.joda.time.*'], ['LocalDate', 'org.joda.time.*'], ['LocalTime', 'org.joda.time.*']);
89 this.initalizeCliOptions();
90 this.initalizeSpecialCharacterMapping();
91 }
92 static addHasMore(objs) {
93 if (objs == null) {
94 return;
95 }
96 if (Array.isArray(objs)) {
97 for (let i = 0, l = objs.length, lm = l - 1; i < l; i++) {
98 if (i > 0) {
99 objs[i].secondaryParam = true;
100 }
101 objs[i].hasMore = i < lm;
102 }
103 return objs;
104 }
105 // what? insanity
106 for (let i = 0; i < objs.size - 1; i++) {
107 if (i > 0) {
108 objs.put('secondaryParam', true);
109 }
110 objs.put('hasMore', i < objs.size - 1);
111 }
112 return objs;
113 }
114 /**
115 * Underscore the given word.
116 * Copied from Twitter elephant bird
117 * https://github.com/twitter/elephant-bird/blob/master/core/src/main/java/com/twitter/elephantbird/util/Strings.java
118 *
119 * @param word The word
120 * @return The underscored version of the word
121 */
122 static underscore(word) {
123 const firstPattern = '([A-Z]+)([A-Z][a-z])';
124 const secondPattern = '([a-z\\d])([A-Z])';
125 const replacementPattern = '$1_$2';
126 word = word.replace(new RegExp('\\.', 'g'), '/');
127 word = word.replace(new RegExp('\\$', 'g'), '__');
128 word = word.replace(new RegExp(firstPattern, 'g'), replacementPattern);
129 word = word.replace(new RegExp(secondPattern, 'g'), replacementPattern);
130 word = word.split('-').join('_');
131 word = word.toLowerCase();
132 return word;
133 }
134 /**
135 * Camelize name (parameter, property, method, etc)
136 *
137 * @param word string to be camelize
138 * @param lowercaseFirstLetter lower case for first letter if set to true
139 * @return camelized string
140 */
141 static camelize(word, lowercaseFirstLetter = false) {
142 word = camelCase_1.default(word);
143 return (word &&
144 word[0][lowercaseFirstLetter ? 'toLowerCase' : 'toUpperCase']() +
145 word.substring(1));
146 }
147 /**
148 * Generate the next name for the given name, i.e. append "2" to the base name if not ending with a number,
149 * otherwise increase the number by 1. For example:
150 * status => status2
151 * status2 => status3
152 * myName100 => myName101
153 *
154 * @param name The base name
155 * @return The next name for the base name
156 */
157 static generateNextName(name) {
158 const re = /(\d{1,})/;
159 if (re.test(name)) {
160 return name.replace(re, _count2);
161 }
162 return name + '2';
163 }
164 initalizeCliOptions() {
165 this.__cliOptions.push(CliOption_1.default.newBoolean(CodegenConstants_1.default.SORT_PARAMS_BY_REQUIRED_FLAG, CodegenConstants_1.default.SORT_PARAMS_BY_REQUIRED_FLAG_DESC).defaultValue('true'));
166 this.__cliOptions.push(CliOption_1.default.newBoolean(CodegenConstants_1.default.ENSURE_UNIQUE_PARAMS, CodegenConstants_1.default.ENSURE_UNIQUE_PARAMS_DESC).defaultValue('true'));
167 }
168 cliOptions() {
169 return this.__cliOptions;
170 }
171 processOpts() {
172 if (this.__additionalProperties.containsKey(CodegenConstants_1.default.TEMPLATE_DIR)) {
173 this.setTemplateDir(this.__additionalProperties.get(CodegenConstants_1.default.TEMPLATE_DIR));
174 }
175 if (this.__additionalProperties.containsKey(CodegenConstants_1.default.MODEL_PACKAGE)) {
176 this.setModelPackage(this.__additionalProperties.get(CodegenConstants_1.default.MODEL_PACKAGE));
177 }
178 if (this.__additionalProperties.containsKey(CodegenConstants_1.default.API_PACKAGE)) {
179 this.setApiPackage(this.__additionalProperties.get(CodegenConstants_1.default.API_PACKAGE));
180 }
181 if (this.__additionalProperties.containsKey(CodegenConstants_1.default.SORT_PARAMS_BY_REQUIRED_FLAG)) {
182 this.setSortParamsByRequiredFlag(Boolean(this.__additionalProperties.get(CodegenConstants_1.default.SORT_PARAMS_BY_REQUIRED_FLAG)));
183 }
184 if (this.__additionalProperties.containsKey(CodegenConstants_1.default.ENSURE_UNIQUE_PARAMS)) {
185 this.setEnsureUniqueParams(Boolean(this.__additionalProperties.get(CodegenConstants_1.default.ENSURE_UNIQUE_PARAMS)));
186 }
187 if (this.__additionalProperties.containsKey(CodegenConstants_1.default.MODEL_NAME_PREFIX)) {
188 this.setModelNamePrefix(this.__additionalProperties.get(CodegenConstants_1.default.MODEL_NAME_PREFIX));
189 }
190 if (this.__additionalProperties.containsKey(CodegenConstants_1.default.MODEL_NAME_SUFFIX)) {
191 this.setModelNameSuffix(this.__additionalProperties.get(CodegenConstants_1.default.MODEL_NAME_SUFFIX));
192 }
193 }
194 addLicenseFile() {
195 return true;
196 }
197 addSwaggerIgnoreFile() {
198 return true;
199 }
200 postProcessAllModels(objs) {
201 if (this.supportsInheritance) {
202 const allModels = javaUtil_1.newHashMap();
203 for (const [key, inner] of objs) {
204 const modelName = this.toModelName(key);
205 for (const mo of inner.get('models')) {
206 allModels.put(modelName, mo.get('model'));
207 }
208 }
209 for (const [key, cm] of allModels) {
210 if (cm.parent != null) {
211 cm.parentModel = allModels.get(cm.parent);
212 }
213 if (javaUtil_1.isNotEmptySet(cm.interfaces)) {
214 cm.interfaceModels = [];
215 for (const intf of cm.interfaces) {
216 const intfModel = allModels.get(intf);
217 if (intfModel != null) {
218 cm.interfaceModels.push(intfModel);
219 }
220 }
221 }
222 }
223 }
224 return objs;
225 }
226 postProcessModels(objs) {
227 return objs;
228 }
229 /**
230 * post process enum defined in model's properties
231 *
232 * @param objs Map of models
233 * @return maps of models with better enum support
234 */
235 postProcessModelsEnum(objs) {
236 const models = objs.get('models');
237 for (const mo of models) {
238 const cm = mo.get('model');
239 if (cm.isEnum && cm.allowableValues != null) {
240 const allowableValues = cm.allowableValues;
241 const values = allowableValues.get('values');
242 const enumVars = [];
243 const commonPrefix = this.findCommonPrefixOfVars(values);
244 const truncateIdx = commonPrefix.length;
245 cm.allowableValues.put('enumVars', enumVars);
246 for (const value of values) {
247 let enumName;
248 if (truncateIdx === 0) {
249 enumName = value.toString();
250 }
251 else {
252 enumName = value.toString().substring(truncateIdx);
253 if ('' === enumName) {
254 enumName = value.toString();
255 }
256 }
257 enumVars.push(javaUtil_1.newHashMap(['name', this.toEnumVarName(enumName, cm.dataType)], ['value', this.toEnumValue(value.toString(), cm.dataType)]));
258 }
259 }
260 for (const _var of cm.vars) {
261 this.updateCodegenPropertyEnum(_var);
262 }
263 }
264 return objs;
265 }
266 /**
267 * Returns the common prefix of variables for enum naming
268 *
269 * @param vars List of variable names
270 * @return the common prefix for naming
271 */
272 findCommonPrefixOfVars(listStr) {
273 try {
274 const prefix = StringUtils_1.default.getCommonPrefix(listStr);
275 return prefix.replace(COMMON_PREFIX_RE, '');
276 }
277 catch (e) {
278 Log.trace(e);
279 return '';
280 }
281 }
282 /**
283 * Return the enum default value in the language specifed format
284 *
285 * @param value enum variable name
286 * @param datatype data type
287 * @return the default value for the enum
288 */
289 toEnumDefaultValue(value, datatype) {
290 return datatype + '.' + value;
291 }
292 /**
293 * Return the enum value in the language specifed format
294 * e.g. status becomes "status"
295 *
296 * @param value enum variable name
297 * @param datatype data type
298 * @return the sanitized value for enum
299 */
300 toEnumValue(value, datatype) {
301 if ('number' === '' + datatype.toLowerCase()) {
302 return value;
303 }
304 return '"' + this.escapeText(value) + '"';
305 }
306 /**
307 * Return the sanitized variable name for enum
308 *
309 * @param value enum variable name
310 * @param datatype data type
311 * @return the sanitized variable name for enum
312 */
313 toEnumVarName(value, datatype) {
314 const __var = value.replace(new RegExp('\\W+', 'g'), '_').toUpperCase();
315 if (__var.match('\\d.*')) {
316 return '_' + __var;
317 }
318 else {
319 return __var;
320 }
321 }
322 postProcessOperations(objs) {
323 return objs;
324 }
325 postProcessSupportingFileData(objs) {
326 return objs;
327 }
328 postProcessModelProperty(model, property) {
329 // Empty
330 }
331 postProcessParameter(parameter) {
332 // Empty
333 }
334 preprocessSwagger(swagger) {
335 // Empty
336 }
337 processSwagger(swagger) {
338 // Empty
339 }
340 escapeText(input) {
341 if (input == null) {
342 return input;
343 }
344 return this.escapeUnsafeCharacters(StringEscapeUtils_1.default.unescapeJava(StringEscapeUtils_1.default.escapeJava(input)
345 .split('\\/')
346 .join('/'))
347 .replace(new RegExp('[\\t\\n\\r]', 'g'), ' ')
348 .split('\\')
349 .join('\\\\')
350 .split('"')
351 .join('\\"'));
352 }
353 /**
354 * override with any special text escaping logic to handle unsafe
355 * characters so as to avoid code injection
356 * @param input String to be cleaned up
357 * @return string with unsafe characters removed or escaped
358 */
359 escapeUnsafeCharacters(input) {
360 Log.warn('escapeUnsafeCharacters should be overriden in the code generator with proper logic to escape unsafe characters');
361 return input;
362 }
363 /**
364 * Escape single and/or double quote to avoid code injection
365 * @param input String to be cleaned up
366 * @return string with quotation mark removed or escaped
367 */
368 escapeQuotationMark(input) {
369 Log.warn('escapeQuotationMark should be overriden in the code generator with proper logic to escape single/double quote');
370 return input.split('"').join('\\"');
371 }
372 defaultIncludes() {
373 return this.__defaultIncludes;
374 }
375 typeMapping() {
376 return this.__typeMapping;
377 }
378 instantiationTypes() {
379 return this.__instantiationTypes;
380 }
381 reservedWords() {
382 return this.__reservedWords;
383 }
384 languageSpecificPrimitives() {
385 return this.__languageSpecificPrimitives;
386 }
387 importMapping() {
388 return this.__importMapping;
389 }
390 testPackage() {
391 return this.__testPackage;
392 }
393 modelPackage() {
394 return this.__modelPackage;
395 }
396 apiPackage() {
397 return this.__apiPackage;
398 }
399 fileSuffix() {
400 return this.__fileSuffix;
401 }
402 templateDir() {
403 return this.__templateDir;
404 }
405 embeddedTemplateDir() {
406 if (this.__embeddedTemplateDir != null) {
407 return this.__embeddedTemplateDir;
408 }
409 else {
410 return this.__templateDir;
411 }
412 }
413 getCommonTemplateDir() {
414 return this.commonTemplateDir;
415 }
416 etCommonTemplateDir(commonTemplateDir) {
417 this.commonTemplateDir = commonTemplateDir;
418 }
419 apiDocTemplateFiles() {
420 return this.__apiDocTemplateFiles;
421 }
422 modelDocTemplateFiles() {
423 return this.__modelDocTemplateFiles;
424 }
425 apiTestTemplateFiles() {
426 return this.__apiTestTemplateFiles;
427 }
428 modelTestTemplateFiles() {
429 return this.__modelTestTemplateFiles;
430 }
431 apiTemplateFiles() {
432 return this.__apiTemplateFiles;
433 }
434 apiDataTemplateFile() {
435 return this.__apiDataTemplateFile;
436 }
437 modelTemplateFiles() {
438 return this.__modelTemplateFiles;
439 }
440 apiFileFolder() {
441 return (this.__outputFolder +
442 path_1.default.sep +
443 this.apiPackage()
444 .split('.')
445 .join(path_1.default.sep));
446 }
447 /**
448 * Checks to see if an API file needs to be generated for this template, helps to apply some logic when you have more than one api file which is condition based.
449 * @param templateName
450 * @param operation
451 * @returns {boolean}
452 */
453 shouldGenerateApiFor(templateName, operation) {
454 return true;
455 }
456 modelFileFolder() {
457 return (this.__outputFolder +
458 path_1.default.sep +
459 this.modelPackage()
460 .split('.')
461 .join(path_1.default.sep));
462 }
463 apiTestFileFolder() {
464 return (this.__outputFolder +
465 path_1.default.sep +
466 this.testPackage()
467 .split('.')
468 .join(path_1.default.sep));
469 }
470 modelTestFileFolder() {
471 return (this.__outputFolder +
472 path_1.default.sep +
473 this.testPackage()
474 .split('.')
475 .join(path_1.default.sep));
476 }
477 apiDocFileFolder() {
478 return this.__outputFolder;
479 }
480 modelDocFileFolder() {
481 return this.__outputFolder;
482 }
483 additionalProperties() {
484 return this.__additionalProperties;
485 }
486 vendorExtensions() {
487 return this.__vendorExtensions;
488 }
489 supportingFiles() {
490 return this.__supportingFiles;
491 }
492 outputFolder() {
493 return this.__outputFolder;
494 }
495 setOutputDir(dir) {
496 this.__outputFolder = dir;
497 }
498 getOutputDir() {
499 return this.outputFolder();
500 }
501 setTemplateDir(templateDir) {
502 this.__templateDir = templateDir;
503 }
504 setModelPackage(modelPackage) {
505 this.__modelPackage = modelPackage;
506 }
507 setModelNamePrefix(modelNamePrefix) {
508 this.modelNamePrefix = modelNamePrefix;
509 }
510 setModelNameSuffix(modelNameSuffix) {
511 this.modelNameSuffix = modelNameSuffix;
512 }
513 setApiPackage(apiPackage) {
514 this.__apiPackage = apiPackage;
515 }
516 setSortParamsByRequiredFlag(sortParamsByRequiredFlag) {
517 this.sortParamsByRequiredFlag = sortParamsByRequiredFlag;
518 }
519 setEnsureUniqueParams(ensureUniqueParams) {
520 this.ensureUniqueParams = ensureUniqueParams;
521 }
522 /**
523 * Return the regular expression/JSON schema pattern (http://json-schema.org/latest/json-schema-validation.html#anchor33)
524 *
525 * @param pattern the pattern (regular expression)
526 * @return properly-escaped pattern
527 */
528 toRegularExpression(pattern) {
529 return this.escapeText(pattern);
530 }
531 /**
532 * Return the file name of the Api Test
533 *
534 * @param name the file name of the Api
535 * @return the file name of the Api
536 */
537 toApiFilename(name) {
538 return this.toApiName(name);
539 }
540 /**
541 * Return the file name of the Api Documentation
542 *
543 * @param name the file name of the Api
544 * @return the file name of the Api
545 */
546 toApiDocFilename(name) {
547 return this.toApiName(name);
548 }
549 /**
550 * Return the file name of the Api Test
551 *
552 * @param name the file name of the Api
553 * @return the file name of the Api
554 */
555 toApiTestFilename(name) {
556 return this.toApiName(name) + 'Test';
557 }
558 /**
559 * Return the variable name in the Api
560 *
561 * @param name the varible name of the Api
562 * @return the snake-cased variable name
563 */
564 toApiVarName(name) {
565 return this.snakeCase(name);
566 }
567 /**
568 * Return the capitalized file name of the model
569 *
570 * @param name the model name
571 * @return the file name of the model
572 */
573 toModelFilename(name) {
574 return this.initialCaps(name);
575 }
576 /**
577 * Return the capitalized file name of the model test
578 *
579 * @param name the model name
580 * @return the file name of the model
581 */
582 toModelTestFilename(name) {
583 return this.initialCaps(name) + 'Test';
584 }
585 /**
586 * Return the capitalized file name of the model documentation
587 *
588 * @param name the model name
589 * @return the file name of the model
590 */
591 toModelDocFilename(name) {
592 return this.initialCaps(name);
593 }
594 /**
595 * Return the operation ID (method name)
596 *
597 * @param operationId operation ID
598 * @return the sanitized method name
599 */
600 toOperationId(operationId) {
601 if (StringUtils_1.default.isEmpty(operationId)) {
602 throw new Error('Empty method name (operationId) not allowed');
603 }
604 return operationId;
605 }
606 /**
607 * Return the variable name by removing invalid characters and proper escaping if
608 * it's a reserved word.
609 *
610 * @param name the variable name
611 * @return the sanitized variable name
612 */
613 toVarName(name) {
614 if (this.__reservedWords.contains(name)) {
615 return this.escapeReservedWord(name);
616 }
617 else {
618 return name;
619 }
620 }
621 /**
622 * Return the parameter name by removing invalid characters and proper escaping if
623 * it's a reserved word.
624 *
625 * @param name Codegen property object
626 * @return the sanitized parameter name
627 */
628 toParamName(name) {
629 name = this.removeNonNameElementToCamelCase(name);
630 if (this.__reservedWords.contains(name)) {
631 return this.escapeReservedWord(name);
632 }
633 return name;
634 }
635 /**
636 * Return the Enum name (e.g. StatusEnum given 'status')
637 *
638 * @param property Codegen property
639 * @return the Enum name
640 */
641 toEnumName(property) {
642 return StringUtils_1.default.capitalize(property.name) + 'Enum';
643 }
644 /**
645 * Return the escaped name of the reserved word
646 *
647 * @param name the name to be escaped
648 * @return the escaped reserved word
649 *
650 * throws Runtime exception as reserved word is not allowed (default behavior)
651 */
652 escapeReservedWord(name) {
653 throw new Error('reserved word ' + name + ' not allowed');
654 }
655 /**
656 * Return the fully-qualified "Model" name for import
657 *
658 * @param name the name of the "Model"
659 * @return the fully-qualified "Model" name for import
660 */
661 toModelImport(name) {
662 if ('' === this.modelPackage()) {
663 return name;
664 }
665 else {
666 return this.modelPackage() + '.' + name;
667 }
668 }
669 /**
670 * Return the fully-qualified "Api" name for import
671 *
672 * @param name the name of the "Api"
673 * @return the fully-qualified "Api" name for import
674 */
675 toApiImport(name) {
676 return this.apiPackage() + '.' + name;
677 }
678 /**
679 * Initalize special character mapping
680 */
681 initalizeSpecialCharacterMapping() {
682 this.specialCharReplacements.put('$', 'Dollar');
683 this.specialCharReplacements.put('^', 'Caret');
684 this.specialCharReplacements.put('|', 'Pipe');
685 this.specialCharReplacements.put('=', 'Equal');
686 this.specialCharReplacements.put('*', 'Star');
687 this.specialCharReplacements.put('-', 'Minus');
688 this.specialCharReplacements.put('&', 'Ampersand');
689 this.specialCharReplacements.put('%', 'Percent');
690 this.specialCharReplacements.put('#', 'Hash');
691 this.specialCharReplacements.put('@', 'At');
692 this.specialCharReplacements.put('!', 'Exclamation');
693 this.specialCharReplacements.put('+', 'Plus');
694 this.specialCharReplacements.put(':', 'Colon');
695 this.specialCharReplacements.put('>', 'Greater_Than');
696 this.specialCharReplacements.put('<', 'Less_Than');
697 this.specialCharReplacements.put('.', 'Period');
698 this.specialCharReplacements.put('_', 'Underscore');
699 this.specialCharReplacements.put('<=', 'Less_Than_Or_Equal_To');
700 this.specialCharReplacements.put('>=', 'Greater_Than_Or_Equal_To');
701 this.specialCharReplacements.put('!=', 'Not_Equal');
702 }
703 /**
704 * Return the symbol name of a symbol
705 *
706 * @param input Symbol (e.g. $)
707 * @return Symbol name (e.g. Dollar)
708 */
709 getSymbolName(input) {
710 return this.specialCharReplacements.get(input);
711 }
712 /**
713 * Return the instantiation type of the property, especially for map and array
714 *
715 * @param p Swagger property object
716 * @return string presentation of the instantiation type of the property
717 */
718 toInstantiationType(p) {
719 if (p != null && p instanceof properties_1.MapProperty) {
720 const ap = p;
721 const additionalProperties2 = ap.getAdditionalProperties();
722 const type = additionalProperties2.getType();
723 if (null == type) {
724 Log.error('No Type defined for Additional Property ' +
725 additionalProperties2 +
726 '\n\tIn Property: ' +
727 p);
728 }
729 const inner = this.getSwaggerType(additionalProperties2);
730 return this.__instantiationTypes.get('map') + '<String, ' + inner + '>';
731 }
732 else if (p != null && p instanceof properties_1.ArrayProperty) {
733 const ap = p;
734 const inner = this.getSwaggerType(ap.getItems());
735 return this.__instantiationTypes.get('array') + '<' + inner + '>';
736 }
737 else {
738 return null;
739 }
740 }
741 /**
742 * Return the example value of the parameter.
743 *
744 * @param p Swagger property object
745 */
746 setParameterExampleValue(p) {
747 // Empty
748 }
749 /**
750 * Return the example value of the property
751 *
752 * @param p Swagger property object
753 * @return string presentation of the example value of the property
754 */
755 toExampleValue(p) {
756 if (p.getExample() != null) {
757 return p.getExample().toString();
758 }
759 if (p instanceof properties_1.StringProperty) {
760 return 'null';
761 }
762 else if (p instanceof properties_1.BooleanProperty) {
763 return 'null';
764 }
765 else if (p instanceof properties_1.DateProperty) {
766 return 'null';
767 }
768 else if (p instanceof properties_1.DateTimeProperty) {
769 return 'null';
770 }
771 else if (p instanceof properties_1.DoubleProperty) {
772 const dp = p;
773 if (dp.getExample() != null) {
774 return dp.getExample().toString();
775 }
776 return 'null';
777 }
778 else if (p instanceof properties_1.FloatProperty) {
779 const dp = p;
780 if (dp.getExample() != null) {
781 return dp.getExample().toString();
782 }
783 return 'null';
784 }
785 else if (p instanceof properties_1.IntegerProperty) {
786 const dp = p;
787 if (dp.getExample() != null) {
788 return dp.getExample().toString();
789 }
790 return 'null';
791 }
792 else if (p instanceof properties_1.LongProperty) {
793 const dp = p;
794 if (dp.getExample() != null) {
795 return dp.getExample().toString();
796 }
797 return 'null';
798 }
799 else {
800 return 'null';
801 }
802 }
803 /**
804 * Return the default value of the property
805 *
806 * @param p Swagger property object
807 * @return string presentation of the default value of the property
808 */
809 toDefaultValue(p) {
810 if (p != null && p instanceof properties_1.StringProperty) {
811 return 'null';
812 }
813 else if (p != null && p instanceof properties_1.BooleanProperty) {
814 return 'null';
815 }
816 else if (p != null && p instanceof properties_1.DateProperty) {
817 return 'null';
818 }
819 else if (p != null && p instanceof properties_1.DateTimeProperty) {
820 return 'null';
821 }
822 else if (p != null && p instanceof properties_1.DoubleProperty) {
823 const dp = p;
824 if (dp.getDefault() != null) {
825 return dp.getDefault().toString();
826 }
827 return 'null';
828 }
829 else if (p != null && p instanceof properties_1.FloatProperty) {
830 const dp = p;
831 if (dp.getDefault() != null) {
832 return dp.getDefault().toString();
833 }
834 return 'null';
835 }
836 else if (p != null && p instanceof properties_1.IntegerProperty) {
837 const dp = p;
838 if (dp.getDefault() != null) {
839 return dp.getDefault().toString();
840 }
841 return 'null';
842 }
843 else if (p != null && p instanceof properties_1.LongProperty) {
844 const dp = p;
845 if (dp.getDefault() != null) {
846 return dp.getDefault().toString();
847 }
848 return 'null';
849 }
850 else {
851 return 'null';
852 }
853 }
854 /**
855 * Return the property initialized from a data object
856 * Useful for initialization with a plain object in JavaScript
857 *
858 * @param name Name of the property object
859 * @param p Swagger property object
860 * @return string presentation of the default value of the property
861 */
862 toDefaultValueWithParam(name, p) {
863 return ' = data.' + name + ';';
864 }
865 /**
866 * returns the swagger type for the property
867 * @param p Swagger property object
868 * @return string presentation of the type
869 */
870 getSwaggerType(p) {
871 let datatype = null;
872 if (p != null &&
873 p instanceof properties_1.StringProperty &&
874 'number' === p.getFormat()) {
875 datatype = 'BigDecimal';
876 }
877 else if (p != null && p instanceof properties_1.StringProperty) {
878 datatype = 'string';
879 }
880 else if (p != null && p instanceof properties_1.ByteArrayProperty) {
881 datatype = 'ByteArray';
882 }
883 else if (p != null && p instanceof properties_1.BinaryProperty) {
884 datatype = 'binary';
885 }
886 else if (p != null && p instanceof properties_1.BooleanProperty) {
887 datatype = 'boolean';
888 }
889 else if (p != null && p instanceof properties_1.DateProperty) {
890 datatype = 'date';
891 }
892 else if (p != null && p instanceof properties_1.DateTimeProperty) {
893 datatype = 'DateTime';
894 }
895 else if (p != null && p instanceof properties_1.DoubleProperty) {
896 datatype = 'double';
897 }
898 else if (p != null && p instanceof properties_1.FloatProperty) {
899 datatype = 'float';
900 }
901 else if (p != null && p instanceof properties_1.IntegerProperty) {
902 datatype = 'integer';
903 }
904 else if (p != null && p instanceof properties_1.LongProperty) {
905 datatype = 'long';
906 }
907 else if (p != null && p instanceof properties_1.MapProperty) {
908 datatype = 'map';
909 }
910 else if (p != null && p instanceof properties_1.DecimalProperty) {
911 datatype = 'number';
912 }
913 else if (p != null && p instanceof properties_1.UUIDProperty) {
914 datatype = 'UUID';
915 }
916 else if (p != null && p instanceof properties_1.RefProperty) {
917 try {
918 const r = p;
919 datatype = r.get$ref();
920 if (datatype.indexOf('#/definitions/') === 0) {
921 datatype = datatype.substring('#/definitions/'.length);
922 }
923 }
924 catch (e) {
925 Log.warn('Error obtaining the datatype from RefProperty:' +
926 p +
927 '. Datatype default to Object');
928 Log.trace(e);
929 datatype = 'Object';
930 }
931 }
932 else {
933 if (p != null) {
934 datatype = p.getType();
935 }
936 }
937 return datatype;
938 }
939 /**
940 * Return the snake-case of the string
941 *
942 * @param name string to be snake-cased
943 * @return snake-cased string
944 */
945 snakeCase(name) {
946 return StringUtils_1.default.snakeCase(name);
947 }
948 /**
949 * Capitalize the string
950 *
951 * @param name string to be capitalized
952 * @return capitalized string
953 */
954 initialCaps(name) {
955 return StringUtils_1.default.capitalize(name);
956 }
957 /**
958 * Output the type declaration of a given name
959 *
960 * @param name name
961 * @return a string presentation of the type
962 */
963 getTypeDeclaration(name) {
964 if (name == null || typeof name === 'string') {
965 return name;
966 }
967 let swaggerType = this.getSwaggerType(name);
968 if (this.__typeMapping.containsKey(swaggerType)) {
969 swaggerType = this.__typeMapping.get(swaggerType);
970 }
971 return swaggerType;
972 }
973 /**
974 * Output the API (class) name (capitalized) ending with "Api"
975 * Return DefaultApi if name is empty
976 *
977 * @param name the name of the Api
978 * @return capitalized Api name ending with "Api"
979 */
980 toApiName(name) {
981 if (name.length === 0) {
982 return 'DefaultApi';
983 }
984 return this.initialCaps(name) + 'Api';
985 }
986 /**
987 * Output the proper model name (capitalized)
988 *
989 * @param name the name of the model
990 * @return capitalized model name
991 */
992 toModelName(name) {
993 return this.initialCaps(this.modelNamePrefix + name + this.modelNameSuffix);
994 }
995 /**
996 * Convert Swagger Model object to Codegen Model object
997 *
998 * @param name the name of the model
999 * @param model Swagger Model object
1000 * @param allDefinitions a map of all Swagger models from the spec
1001 * @return Codegen Model object
1002 */
1003 fromModel(name, model, allDefinitions = null) {
1004 const m = CodegenModelFactory_1.default.newInstance(CodegenModelType_1.default.MODEL);
1005 if (this.__reservedWords.contains(name)) {
1006 m.name = this.escapeReservedWord(name);
1007 }
1008 else {
1009 m.name = name;
1010 }
1011 m.description = this.escapeText(model.getDescription());
1012 m.unescapedDescription = model.getDescription();
1013 m.classname = this.toModelName(name);
1014 m.classVarName = this.toVarName(name);
1015 m.classFilename = this.toModelFilename(name);
1016 m.modelJson = Json_1.default.pretty(model);
1017 m.externalDocs = model.getExternalDocs();
1018 m.vendorExtensions = model.getVendorExtensions();
1019 if (model != null && model instanceof ModelImpl_1.default) {
1020 m.discriminator = model.getDiscriminator();
1021 }
1022 if (model != null && model instanceof ArrayModel_1.default) {
1023 const am = model;
1024 const arrayProperty = new properties_1.ArrayProperty().items(am.getItems());
1025 m.hasEnums = false;
1026 m.isArrayModel = true;
1027 m.arrayModelType = this.fromProperty(name, arrayProperty).complexType;
1028 this.addParentContainer(m, name, arrayProperty);
1029 }
1030 else if (model != null && model instanceof RefModel_1.default) {
1031 // Empty
1032 }
1033 else if (model != null && model instanceof ComposedModel_1.default) {
1034 const composed = model;
1035 const properties = javaUtil_1.newHashMap();
1036 const required = [];
1037 let allProperties;
1038 let allRequired;
1039 if (this.supportsInheritance) {
1040 allProperties = javaUtil_1.newHashMap();
1041 allRequired = [];
1042 m.allVars = [];
1043 }
1044 else {
1045 allProperties = null;
1046 allRequired = null;
1047 }
1048 let parent = composed.getParent();
1049 if (composed.getInterfaces() != null) {
1050 if (m.interfaces == null) {
1051 m.interfaces = [];
1052 }
1053 for (const _interface of composed.getInterfaces()) {
1054 let interfaceModel = null;
1055 if (allDefinitions != null) {
1056 interfaceModel = allDefinitions.get(_interface.getSimpleRef());
1057 }
1058 if (parent == null &&
1059 (interfaceModel != null && interfaceModel instanceof ModelImpl_1.default) &&
1060 interfaceModel.getDiscriminator() != null) {
1061 parent = _interface;
1062 }
1063 else {
1064 const interfaceRef = this.toModelName(_interface.getSimpleRef());
1065 m.interfaces.push(interfaceRef);
1066 this.addImport(m, interfaceRef);
1067 if (allDefinitions != null) {
1068 if (this.supportsInheritance) {
1069 this.addProperties(allProperties, allRequired, interfaceModel, allDefinitions);
1070 }
1071 else {
1072 this.addProperties(properties, required, interfaceModel, allDefinitions);
1073 }
1074 }
1075 }
1076 }
1077 }
1078 if (parent != null) {
1079 const parentRef = parent.getSimpleRef();
1080 m.parentSchema = parentRef;
1081 m.parent = this.toModelName(parent.getSimpleRef());
1082 this.addImport(m, m.parent);
1083 if (allDefinitions != null) {
1084 const parentModel = allDefinitions.get(m.parentSchema);
1085 if (this.supportsInheritance) {
1086 this.addProperties(allProperties, allRequired, parentModel, allDefinitions);
1087 }
1088 else {
1089 this.addProperties(properties, required, parentModel, allDefinitions);
1090 }
1091 }
1092 }
1093 let child = composed.getChild();
1094 if (child != null &&
1095 (child != null && child instanceof RefModel_1.default) &&
1096 allDefinitions != null) {
1097 const childRef = child.getSimpleRef();
1098 child = allDefinitions.get(childRef);
1099 }
1100 if (child != null && (child != null && child instanceof ModelImpl_1.default)) {
1101 this.addProperties(properties, required, child, allDefinitions);
1102 if (this.supportsInheritance) {
1103 this.addProperties(allProperties, allRequired, child, allDefinitions);
1104 }
1105 }
1106 this.addVars(m, properties, required, allProperties, allRequired);
1107 }
1108 else {
1109 const impl = model;
1110 if (impl.getEnum() != null && impl.getEnum().length > 0) {
1111 m.isEnum = true;
1112 m.allowableValues = javaUtil_1.newHashMap();
1113 m.allowableValues.put('values', impl.getEnum());
1114 const p = PropertyBuilder_1.default.build(impl.getType(), impl.getFormat(), null);
1115 m.dataType = this.getSwaggerType(p);
1116 }
1117 if (impl.getAdditionalProperties &&
1118 impl.getAdditionalProperties() != null) {
1119 this.addAdditionPropertiesToCodeGenModel(m, impl);
1120 }
1121 this.addVars(m, impl.getProperties(), impl.getRequired());
1122 }
1123 if (m.vars != null) {
1124 for (const prop of m.vars) {
1125 this.postProcessModelProperty(m, prop);
1126 }
1127 }
1128 return m;
1129 }
1130 addAdditionPropertiesToCodeGenModel(codegenModel, swaggerModel) {
1131 const mapProperty = new properties_1.MapProperty(swaggerModel.getAdditionalProperties());
1132 this.addParentContainer(codegenModel, codegenModel.name, mapProperty);
1133 }
1134 addProperties(properties, required, model, allDefinitions) {
1135 if (model != null && model instanceof ModelImpl_1.default) {
1136 const mi = model;
1137 if (mi.getProperties() != null) {
1138 properties.putAll(mi.getProperties());
1139 }
1140 if (mi.getRequired() != null) {
1141 required.push(...mi.getRequired());
1142 }
1143 }
1144 else if (model != null && model instanceof RefModel_1.default) {
1145 const interfaceRef = model.getSimpleRef();
1146 const interfaceModel = allDefinitions.get(interfaceRef);
1147 this.addProperties(properties, required, interfaceModel, allDefinitions);
1148 }
1149 else if (model != null && model instanceof ComposedModel_1.default) {
1150 for (const component of model.getAllOf()) {
1151 this.addProperties(properties, required, component, allDefinitions);
1152 }
1153 }
1154 }
1155 /**
1156 * Camelize the method name of the getter and setter
1157 *
1158 * @param name string to be camelized
1159 * @return Camelized string
1160 */
1161 getterAndSetterCapitalize(name) {
1162 if (name == null || name.length === 0) {
1163 return name;
1164 }
1165 return DefaultCodegen.camelize(this.toVarName(name));
1166 }
1167 /**
1168 * Convert Swagger Property object to Codegen Property object
1169 *
1170 * @param name name of the property
1171 * @param p Swagger property object
1172 * @return Codegen Property object
1173 */
1174 fromProperty(name, p) {
1175 if (p == null) {
1176 Log.error('unexpected missing property for name ' + name);
1177 return null;
1178 }
1179 const property = CodegenModelFactory_1.default.newInstance(CodegenModelType_1.default.PROPERTY);
1180 property.name = this.toVarName(name);
1181 property.baseName = name;
1182 property.nameInCamelCase = DefaultCodegen.camelize(property.name, false);
1183 property.description = this.escapeText(p.getDescription());
1184 property.unescapedDescription = p.getDescription();
1185 property.getter = 'get' + this.getterAndSetterCapitalize(name);
1186 property.setter = 'set' + this.getterAndSetterCapitalize(name);
1187 property.example = this.toExampleValue(p);
1188 property.defaultValue = this.toDefaultValue(p);
1189 property.defaultValueWithParam = this.toDefaultValueWithParam(name, p);
1190 property.jsonSchema = Json_1.default.pretty(p);
1191 property.isReadOnly = p.getReadOnly();
1192 property.vendorExtensions = p.getVendorExtensions();
1193 const type = this.getSwaggerType(p);
1194 const allowableValues = javaUtil_1.newHashMap();
1195 if (p instanceof properties_1.AbstractNumericProperty) {
1196 const np = p;
1197 property.minimum = np.getMinimum();
1198 property.maximum = np.getMaximum();
1199 property.exclusiveMinimum = np.getExclusiveMinimum();
1200 property.exclusiveMaximum = np.getExclusiveMaximum();
1201 if (property.minimum != null ||
1202 property.maximum != null ||
1203 property.exclusiveMinimum != null ||
1204 property.exclusiveMaximum != null) {
1205 property.hasValidation = true;
1206 }
1207 if (np.getMinimum() != null) {
1208 allowableValues.put('min', np.getMinimum());
1209 }
1210 if (np.getMaximum() != null) {
1211 allowableValues.put('max', np.getMaximum());
1212 }
1213 }
1214 if (p instanceof properties_1.StringProperty) {
1215 const sp = p;
1216 property.maxLength = sp.getMaxLength();
1217 property.minLength = sp.getMinLength();
1218 property.datatype = type;
1219 property.isString = true;
1220 property.isPrimitive = true;
1221 property.pattern = this.toRegularExpression(sp.getPattern());
1222 if (property.pattern != null ||
1223 property.minLength != null ||
1224 property.maxLength != null) {
1225 property.hasValidation = true;
1226 }
1227 property.isString = true;
1228 }
1229 else if (p instanceof properties_1.BaseIntegerProperty &&
1230 !(p instanceof properties_1.IntegerProperty) &&
1231 !(p instanceof properties_1.LongProperty)) {
1232 property.isInteger = true;
1233 }
1234 else if (p instanceof properties_1.IntegerProperty) {
1235 property.isInteger = true;
1236 }
1237 else if (p instanceof properties_1.LongProperty) {
1238 property.isLong = true;
1239 }
1240 else if (p instanceof properties_1.BooleanProperty) {
1241 property.isBoolean = true;
1242 }
1243 else if (p instanceof properties_1.BinaryProperty) {
1244 property.isBinary = true;
1245 }
1246 else if (p instanceof properties_1.UUIDProperty) {
1247 property.isString = true;
1248 }
1249 else if (p instanceof properties_1.ByteArrayProperty) {
1250 property.isByteArray = true;
1251 }
1252 else if (p instanceof properties_1.DecimalProperty &&
1253 !(p instanceof properties_1.DoubleProperty) &&
1254 !(p instanceof properties_1.FloatProperty)) {
1255 property.isFloat = true;
1256 }
1257 else if (p instanceof properties_1.DoubleProperty) {
1258 property.isDouble = true;
1259 }
1260 else if (p instanceof properties_1.FloatProperty) {
1261 property.isFloat = true;
1262 }
1263 else if (p instanceof properties_1.DateProperty) {
1264 property.isDate = true;
1265 }
1266 else if (p instanceof properties_1.DateTimeProperty) {
1267 property.isDateTime = true;
1268 }
1269 if (p.getEnum() != null) {
1270 const _enum = p.getEnum();
1271 property._enum = _enum;
1272 property.isEnum = true;
1273 allowableValues.put('values', _enum);
1274 }
1275 if (!allowableValues.isEmpty()) {
1276 property.allowableValues = allowableValues;
1277 }
1278 property.datatype = this.getTypeDeclaration(p);
1279 property.dataFormat = p.getFormat();
1280 if (property.isEnum) {
1281 property.datatypeWithEnum = this.toEnumName(property);
1282 property.enumName = this.toEnumName(property);
1283 }
1284 else {
1285 property.datatypeWithEnum = property.datatype;
1286 }
1287 property.baseType = this.getSwaggerType(p);
1288 if (p != null && p instanceof properties_1.ArrayProperty) {
1289 property.isContainer = true;
1290 property.isListContainer = true;
1291 property.containerType = 'array';
1292 property.baseType = this.getSwaggerType(p);
1293 const cp = this.fromProperty(property.name, p.getItems());
1294 this.updatePropertyForArray(property, cp);
1295 }
1296 else if (p != null && p instanceof properties_1.MapProperty) {
1297 property.isContainer = true;
1298 property.isMapContainer = true;
1299 property.containerType = 'map';
1300 property.baseType = this.getSwaggerType(p);
1301 const cp = this.fromProperty('inner', p.getAdditionalProperties());
1302 this.updatePropertyForMap(property, cp);
1303 }
1304 else {
1305 this.setNonArrayMapProperty(property, type);
1306 }
1307 return property;
1308 }
1309 /**
1310 * Update property for array(list) container
1311 * @param property Codegen property
1312 * @param innerProperty Codegen inner property of map or list
1313 */
1314 updatePropertyForArray(property, innerProperty) {
1315 if (innerProperty == null) {
1316 Log.warn('skipping invalid array property ' + Json_1.default.pretty(property));
1317 }
1318 else {
1319 if (!this.__languageSpecificPrimitives.contains(innerProperty.baseType)) {
1320 property.complexType = innerProperty.baseType;
1321 }
1322 else {
1323 property.isPrimitiveType = true;
1324 property.baseType = innerProperty.baseType;
1325 }
1326 property.items = innerProperty;
1327 if (this.isPropertyInnerMostEnum(property)) {
1328 property.isEnum = true;
1329 this.updateDataTypeWithEnumForArray(property);
1330 property.allowableValues = this.getInnerEnumAllowableValues(property);
1331 }
1332 }
1333 }
1334 /**
1335 * Update property for map container
1336 * @param property Codegen property
1337 * @param innerProperty Codegen inner property of map or list
1338 */
1339 updatePropertyForMap(property, innerProperty) {
1340 if (innerProperty == null) {
1341 Log.warn('skipping invalid map property ' + Json_1.default.pretty(property));
1342 return;
1343 }
1344 else {
1345 if (!this.__languageSpecificPrimitives.contains(innerProperty.baseType)) {
1346 property.complexType = innerProperty.baseType;
1347 }
1348 else {
1349 property.isPrimitiveType = true;
1350 }
1351 property.items = innerProperty;
1352 if (this.isPropertyInnerMostEnum(property)) {
1353 property.isEnum = true;
1354 this.updateDataTypeWithEnumForMap(property);
1355 property.allowableValues = this.getInnerEnumAllowableValues(property);
1356 }
1357 }
1358 }
1359 /**
1360 * Update property for map container
1361 * @param property Codegen property
1362 * @return True if the inner most type is enum
1363 */
1364 isPropertyInnerMostEnum(property) {
1365 let currentProperty = property;
1366 while (currentProperty != null &&
1367 (currentProperty.isMapContainer || currentProperty.isListContainer)) {
1368 currentProperty = currentProperty.items;
1369 }
1370 return currentProperty.isEnum;
1371 }
1372 getInnerEnumAllowableValues(property) {
1373 let currentProperty = property;
1374 while (currentProperty != null &&
1375 (currentProperty.isMapContainer || currentProperty.isListContainer)) {
1376 currentProperty = currentProperty.items;
1377 }
1378 return currentProperty.allowableValues;
1379 }
1380 /**
1381 * Update datatypeWithEnum for array container
1382 * @param property Codegen property
1383 */
1384 updateDataTypeWithEnumForArray(property) {
1385 let baseItem = property.items;
1386 while (baseItem != null &&
1387 (baseItem.isMapContainer || baseItem.isListContainer)) {
1388 baseItem = baseItem.items;
1389 }
1390 property.datatypeWithEnum = property.datatypeWithEnum
1391 .split(baseItem.baseType)
1392 .join(this.toEnumName(baseItem));
1393 property.enumName = this.toEnumName(property);
1394 if (property.defaultValue != null) {
1395 property.defaultValue = property.defaultValue
1396 .split(baseItem.baseType)
1397 .join(this.toEnumName(baseItem));
1398 }
1399 }
1400 /**
1401 * Update datatypeWithEnum for map container
1402 * @param property Codegen property
1403 */
1404 updateDataTypeWithEnumForMap(property) {
1405 let baseItem = property.items;
1406 while (baseItem != null &&
1407 (baseItem.isMapContainer || baseItem.isListContainer)) {
1408 baseItem = baseItem.items;
1409 }
1410 property.datatypeWithEnum = property.datatypeWithEnum
1411 .split(', ' + baseItem.baseType)
1412 .join(', ' + this.toEnumName(baseItem));
1413 property.enumName = this.toEnumName(property);
1414 if (property.defaultValue != null) {
1415 property.defaultValue = property.defaultValue
1416 .split(', ' + property.items.baseType)
1417 .join(', ' + this.toEnumName(property.items));
1418 }
1419 }
1420 setNonArrayMapProperty(property, type) {
1421 property.isNotContainer = true;
1422 if (this.languageSpecificPrimitives().contains(type)) {
1423 property.isPrimitiveType = true;
1424 }
1425 else {
1426 property.complexType = property.baseType;
1427 }
1428 }
1429 /**
1430 * Override with any special handling of response codes
1431 * @param responses Swagger Operation's responses
1432 * @return default method response or <tt>null</tt> if not found
1433 */
1434 findMethodResponse(responses) {
1435 let code = null;
1436 let resp;
1437 for (const [responseCode, response] of responses) {
1438 if (('' + responseCode).startsWith('2') || responseCode === 'default') {
1439 if (code == null || StringUtils_1.default.compareTo(responseCode, code) > 0) {
1440 code = responseCode;
1441 resp = response;
1442 }
1443 }
1444 }
1445 return resp;
1446 }
1447 /**
1448 * Convert Swagger Operation object to Codegen Operation object
1449 *
1450 * @param p the path of the operation
1451 * @param httpMethod HTTP method
1452 * @param operation Swagger operation object
1453 * @param definitions a map of Swagger models
1454 * @param swagger a Swagger object representing the spec
1455 * @return Codegen Operation object
1456 */
1457 fromOperation(p, httpMethod, operation, definitions, swagger = null) {
1458 const op = CodegenModelFactory_1.default.newInstance(CodegenModelType_1.default.OPERATION);
1459 const imports = javaUtil_1.newHashSet();
1460 op.vendorExtensions = operation.getVendorExtensions();
1461 const operationId = this.removeNonNameElementToCamelCase(this.getOrGenerateOperationId(operation, p, httpMethod));
1462 op.operationId = this.toOperationId(operationId);
1463 op.path = p;
1464 op.summary = this.escapeText(operation.getSummary());
1465 op.unescapedNotes = operation.getDescription();
1466 op.notes = this.escapeText(operation.getDescription());
1467 op.tags = operation.getTags();
1468 op.hasConsumes = false;
1469 op.hasProduces = false;
1470 let consumes = [];
1471 if (javaUtil_1.isNotEmptySet(operation.getConsumes())) {
1472 consumes = operation.getConsumes();
1473 }
1474 else if (swagger != null && javaUtil_1.isNotEmptySet(swagger.getConsumes())) {
1475 consumes = swagger.getConsumes();
1476 Log.debug('No consumes defined in operation. Using global consumes (' +
1477 swagger.getConsumes() +
1478 ') for ' +
1479 op.operationId);
1480 }
1481 if (consumes != null && consumes.length) {
1482 const c = [];
1483 let count = 0;
1484 for (const key of consumes) {
1485 const mediaType = javaUtil_1.newHashMap([
1486 'mediaType',
1487 this.escapeText(this.escapeQuotationMark(key)),
1488 ]);
1489 count += 1;
1490 if (count < consumes.length) {
1491 mediaType.put('hasMore', 'true');
1492 }
1493 else {
1494 mediaType.put('hasMore', null);
1495 }
1496 c.push(mediaType);
1497 }
1498 op.consumes = c;
1499 op.hasConsumes = true;
1500 }
1501 let produces = [];
1502 if (operation.getProduces() != null) {
1503 if (operation.getProduces().length > 0) {
1504 produces = operation.getProduces();
1505 }
1506 }
1507 else if (swagger != null &&
1508 swagger.getProduces() != null &&
1509 swagger.getProduces().length > 0) {
1510 produces = swagger.getProduces();
1511 Log.debug('No produces defined in operation. Using global produces (' +
1512 swagger.getProduces() +
1513 ') for ' +
1514 op.operationId);
1515 }
1516 if (produces != null && produces.length > 0) {
1517 const c = [];
1518 let count = 0;
1519 for (const key of produces) {
1520 const mediaType = javaUtil_1.newHashMap([
1521 'mediaType',
1522 this.escapeText(this.escapeQuotationMark(key)),
1523 ]);
1524 count += 1;
1525 if (count < produces.length) {
1526 mediaType.put('hasMore', 'true');
1527 }
1528 else {
1529 mediaType.put('hasMore', null);
1530 }
1531 c.push(mediaType);
1532 }
1533 op.produces = c;
1534 op.hasProduces = true;
1535 }
1536 const responses = operation.getResponses();
1537 if (responses != null && !responses.isEmpty()) {
1538 const methodResponse = this.findMethodResponse(responses);
1539 for (const [key, response] of operation.getResponses()) {
1540 const r = this.fromResponse(key, response);
1541 r.hasMore = true;
1542 if (r.baseType != null &&
1543 !this.__defaultIncludes.contains(r.baseType) &&
1544 !this.__languageSpecificPrimitives.contains(r.baseType)) {
1545 imports.add(r.baseType);
1546 }
1547 r.isDefault = response === methodResponse;
1548 op.responses.push(r);
1549 if (r.isBinary && r.isDefault) {
1550 op.isResponseBinary = true;
1551 }
1552 }
1553 op.responses[op.responses.length - 1].hasMore = false;
1554 if (methodResponse != null) {
1555 if (methodResponse.getSchema() != null) {
1556 const cm = this.fromProperty('response', methodResponse.getSchema());
1557 const responseProperty = methodResponse.getSchema();
1558 if (responseProperty != null &&
1559 responseProperty instanceof properties_1.ArrayProperty) {
1560 const ap = responseProperty;
1561 const innerProperty = this.fromProperty('response', ap.getItems());
1562 op.returnBaseType = innerProperty.baseType;
1563 }
1564 else {
1565 if (cm.complexType != null) {
1566 op.returnBaseType = cm.complexType;
1567 }
1568 else {
1569 op.returnBaseType = cm.baseType;
1570 }
1571 }
1572 op.examples = new ExampleGenerator_1.default(definitions).generate(methodResponse.getExamples(), operation.getProduces(), responseProperty);
1573 op.defaultResponse = this.toDefaultValue(responseProperty);
1574 op.returnType = cm.datatype;
1575 op.hasReference =
1576 definitions != null && definitions.containsKey(op.returnBaseType);
1577 if (definitions != null) {
1578 const m = definitions.get(op.returnBaseType);
1579 if (m != null) {
1580 const cmod = this.fromModel(op.returnBaseType, m, definitions);
1581 op.discriminator = cmod.discriminator;
1582 }
1583 }
1584 if (cm.isContainer != null) {
1585 op.returnContainer = cm.containerType;
1586 if ('map' === cm.containerType) {
1587 op.isMapContainer = true;
1588 }
1589 else if (((o1, o2) => o1.toUpperCase() === (o2 === null ? o2 : o2.toUpperCase()))('list', cm.containerType)) {
1590 op.isListContainer = true;
1591 }
1592 else if (((o1, o2) => o1.toUpperCase() === (o2 === null ? o2 : o2.toUpperCase()))('array', cm.containerType)) {
1593 op.isListContainer = true;
1594 }
1595 }
1596 else {
1597 op.returnSimpleType = true;
1598 }
1599 if (this.languageSpecificPrimitives().contains(op.returnBaseType) ||
1600 op.returnBaseType == null) {
1601 op.returnTypeIsPrimitive = true;
1602 }
1603 }
1604 this.addHeaders(methodResponse, op.responseHeaders);
1605 }
1606 }
1607 const parameters = operation.getParameters();
1608 let bodyParam = null;
1609 const allParams = [];
1610 const bodyParams = [];
1611 const pathParams = [];
1612 const queryParams = [];
1613 const headerParams = [];
1614 const cookieParams = [];
1615 const formParams = [];
1616 if (parameters != null) {
1617 for (const param of parameters) {
1618 const po = this.fromParameter(param, imports);
1619 if (this.ensureUniqueParams) {
1620 while (true) {
1621 let exists = false;
1622 for (const cp of allParams) {
1623 if (po.paramName === cp.paramName) {
1624 exists = true;
1625 break;
1626 }
1627 }
1628 if (exists) {
1629 po.paramName = DefaultCodegen.generateNextName(po.paramName);
1630 }
1631 else {
1632 break;
1633 }
1634 }
1635 }
1636 allParams.push(po);
1637 if (param != null && param instanceof parameters_1.QueryParameter) {
1638 queryParams.push(po.copy());
1639 }
1640 else if (param != null && param instanceof parameters_1.PathParameter) {
1641 pathParams.push(po.copy());
1642 }
1643 else if (param != null && param instanceof parameters_1.HeaderParameter) {
1644 headerParams.push(po.copy());
1645 }
1646 else if (param != null && param instanceof parameters_1.CookieParameter) {
1647 cookieParams.push(po.copy());
1648 }
1649 else if (param != null && param instanceof parameters_1.BodyParameter) {
1650 bodyParam = po.copy();
1651 bodyParams.push(po);
1652 }
1653 else if (param != null && param instanceof parameters_1.FormParameter) {
1654 formParams.push(po);
1655 }
1656 if (po.required == null || !po.required) {
1657 op.hasOptionalParams = true;
1658 }
1659 }
1660 }
1661 for (const i of imports) {
1662 if (this.needToImport(i)) {
1663 op.imports.add(i);
1664 }
1665 }
1666 op.bodyParam = bodyParam;
1667 op.httpMethod = httpMethod.toUpperCase();
1668 if (this.sortParamsByRequiredFlag) {
1669 allParams.sort(sortByFlag);
1670 }
1671 op.allParams = DefaultCodegen.addHasMore(allParams);
1672 op.bodyParams = DefaultCodegen.addHasMore(bodyParams);
1673 op.pathParams = DefaultCodegen.addHasMore(pathParams);
1674 op.queryParams = DefaultCodegen.addHasMore(queryParams);
1675 op.headerParams = DefaultCodegen.addHasMore(headerParams);
1676 op.formParams = DefaultCodegen.addHasMore(formParams);
1677 op.nickname = op.operationId;
1678 if (op.allParams.length > 0) {
1679 // op.allParams
1680 op.hasParams = true;
1681 }
1682 op.externalDocs = operation.getExternalDocs();
1683 op.__isRestfulShow = op.isRestfulShow();
1684 op.__isRestfulIndex = op.isRestfulIndex();
1685 op.__isRestfulCreate = op.isRestfulCreate();
1686 op.__isRestfulUpdate = op.isRestfulUpdate();
1687 op.__isRestfulDestroy = op.isRestfulDestroy();
1688 op.__isRestful = op.isRestful();
1689 return op;
1690 }
1691 /**
1692 * Convert Swagger Response object to Codegen Response object
1693 *
1694 * @param responseCode HTTP response code
1695 * @param response Swagger Response object
1696 * @return Codegen Response object
1697 */
1698 fromResponse(responseCode, response) {
1699 const r = CodegenModelFactory_1.default.newInstance(CodegenModelType_1.default.RESPONSE);
1700 if ('default' === responseCode) {
1701 r.code = '0';
1702 }
1703 else {
1704 r.code = responseCode;
1705 }
1706 r.message = this.escapeText(response.getDescription());
1707 r.schema = response.getSchema();
1708 r.examples = this.toExamples(response.getExamples());
1709 r.jsonSchema = Json_1.default.pretty(response);
1710 this.addHeaders(response, r.headers);
1711 if (r.schema != null) {
1712 const responseProperty = response.getSchema();
1713 responseProperty.setRequired(true);
1714 const cm = this.fromProperty('response', responseProperty);
1715 if (responseProperty != null &&
1716 responseProperty instanceof properties_1.ArrayProperty) {
1717 const innerProperty = this.fromProperty('response', responseProperty.getItems());
1718 r.baseType = innerProperty.baseType;
1719 // r.isListContainer = true;
1720 }
1721 else {
1722 if (cm.complexType != null) {
1723 r.baseType = cm.complexType;
1724 }
1725 else {
1726 r.baseType = cm.baseType;
1727 }
1728 }
1729 r.dataType = cm.datatype;
1730 r.isBinary = this.isDataTypeBinary(cm.datatype);
1731 if (cm.isContainer != null) {
1732 r.simpleType = false;
1733 r.containerType = cm.containerType;
1734 r.isMapContainer = 'map' === cm.containerType;
1735 r.isListContainer =
1736 'list' === cm.containerType || 'array' === this.containerType;
1737 }
1738 else {
1739 r.simpleType = true;
1740 }
1741 r.primitiveType =
1742 r.baseType == null ||
1743 this.languageSpecificPrimitives().contains(r.baseType);
1744 }
1745 if (r.baseType == null) {
1746 r.isMapContainer = false;
1747 r.isListContainer = false;
1748 r.primitiveType = true;
1749 r.simpleType = true;
1750 }
1751 return r;
1752 }
1753 /**
1754 * Convert Swagger Parameter object to Codegen Parameter object
1755 *
1756 * @param param Swagger parameter object
1757 * @param imports set of imports for library/package/module
1758 * @return Codegen Parameter object
1759 */
1760 fromParameter(param, imports) {
1761 const p = CodegenModelFactory_1.default.newInstance(CodegenModelType_1.default.PARAMETER);
1762 p.baseName = param.getName();
1763 p.description = this.escapeText(param.getDescription());
1764 p.unescapedDescription = param.getDescription();
1765 if (param.getRequired()) {
1766 p.required = param.getRequired();
1767 }
1768 p.jsonSchema = Json_1.default.pretty(param);
1769 if (System_1.default.getProperty('debugParser') != null) {
1770 Log.info('working on Parameter ' + param);
1771 }
1772 if (param != null && param instanceof parameters_1.QueryParameter) {
1773 p.defaultValue = param.getDefaultValue();
1774 }
1775 else if (param != null && param instanceof parameters_1.HeaderParameter) {
1776 p.defaultValue = param.getDefaultValue();
1777 }
1778 else if (param != null && param instanceof parameters_1.FormParameter) {
1779 p.defaultValue = param.getDefaultValue();
1780 }
1781 p.vendorExtensions = param.getVendorExtensions();
1782 // if (param != null && (param["__interfaces"] != null && param["__interfaces"].indexOf("io.swagger.models.parameters.SerializableParameter") >= 0 || param.constructor != null && param.constructor["__interfaces"] != null && param.constructor["__interfaces"].indexOf("io.swagger.models.parameters.SerializableParameter") >= 0)) {
1783 if (param && param instanceof parameters_1.SerializableParameter) {
1784 const qp = param;
1785 let property = null;
1786 let collectionFormat = null;
1787 const type = qp.getType();
1788 if (null == type) {
1789 Log.warn('Type is NULL for Serializable Parameter: ' + param);
1790 }
1791 if ('array' === type) {
1792 let inner = qp.getItems();
1793 if (inner == null) {
1794 Log.warn('warning! No inner type supplied for array parameter "' +
1795 qp.getName() +
1796 '", using String');
1797 inner = new properties_1.StringProperty().description('//TODO automatically added by swagger-codegen');
1798 }
1799 property = new properties_1.ArrayProperty().items(inner);
1800 collectionFormat = qp.getCollectionFormat();
1801 if (collectionFormat == null) {
1802 collectionFormat = 'csv';
1803 }
1804 const pr = this.fromProperty('inner', property);
1805 p.baseType = pr.baseType;
1806 p.isContainer = true;
1807 p.isListContainer = true;
1808 imports.add(pr.baseType);
1809 }
1810 else if ('object' === type) {
1811 let inner = qp.getItems();
1812 if (inner == null) {
1813 Log.warn('warning! No inner type supplied for map parameter "' +
1814 qp.getName() +
1815 '", using String');
1816 inner = new properties_1.StringProperty().description('//TODO automatically added by swagger-codegen');
1817 }
1818 property = new properties_1.MapProperty(inner);
1819 collectionFormat = qp.getCollectionFormat();
1820 const pr = this.fromProperty('inner', inner);
1821 p.baseType = pr.datatype;
1822 p.isContainer = true;
1823 p.isMapContainer = true;
1824 imports.add(pr.baseType);
1825 }
1826 else {
1827 property = PropertyBuilder_1.default.build(type, qp.getFormat(), javaUtil_1.newHashMap(['enum', qp.getEnum()]));
1828 }
1829 if (property == null) {
1830 Log.warn('warning! Property type "' +
1831 type +
1832 '" not found for parameter "' +
1833 param.getName() +
1834 '", using String');
1835 property = new properties_1.StringProperty().description('//TODO automatically added by swagger-codegen. Type was ' +
1836 type +
1837 ' but not supported');
1838 }
1839 property.setRequired(param.getRequired());
1840 const cp = this.fromProperty(qp.getName(), property);
1841 this.setParameterBooleanFlagWithCodegenProperty(p, cp);
1842 p.dataType = cp.datatype;
1843 p.dataFormat = cp.dataFormat;
1844 if (cp.isEnum) {
1845 p.datatypeWithEnum = cp.datatypeWithEnum;
1846 }
1847 this.updateCodegenPropertyEnum(cp);
1848 p.isEnum = cp.isEnum;
1849 p._enum = cp._enum;
1850 p.allowableValues = cp.allowableValues;
1851 if (cp.items != null && cp.items.isEnum) {
1852 p.datatypeWithEnum = cp.datatypeWithEnum;
1853 p.items = cp.items;
1854 }
1855 p.collectionFormat = collectionFormat;
1856 if (collectionFormat != null && collectionFormat === 'multi') {
1857 p.isCollectionFormatMulti = true;
1858 }
1859 p.paramName = this.toParamName(qp.getName());
1860 if (cp.complexType != null) {
1861 imports.add(cp.complexType);
1862 }
1863 p.maximum = qp.getMaximum();
1864 p.exclusiveMaximum = qp.isExclusiveMaximum();
1865 p.minimum = qp.getMinimum();
1866 p.exclusiveMinimum = qp.isExclusiveMinimum();
1867 p.maxLength = qp.getMaxLength();
1868 p.minLength = qp.getMinLength();
1869 p.pattern = this.toRegularExpression(qp.getPattern());
1870 p.maxItems = qp.getMaxItems();
1871 p.minItems = qp.getMinItems();
1872 p.uniqueItems = qp.isUniqueItems();
1873 p.multipleOf = qp.getMultipleOf();
1874 if (p.maximum != null ||
1875 p.exclusiveMaximum != null ||
1876 p.minimum != null ||
1877 p.exclusiveMinimum != null ||
1878 p.maxLength != null ||
1879 p.minLength != null ||
1880 p.maxItems != null ||
1881 p.minItems != null ||
1882 p.pattern != null) {
1883 p.hasValidation = true;
1884 }
1885 }
1886 else {
1887 if (!(param instanceof parameters_1.BodyParameter)) {
1888 Log.error('Cannot use Parameter ' + param + ' as Body Parameter');
1889 }
1890 const bp = param;
1891 const model = bp.getSchema();
1892 if (model != null && model instanceof ModelImpl_1.default) {
1893 const impl = model;
1894 const cm = this.fromModel(bp.getName(), impl);
1895 if (cm.emptyVars != null && cm.emptyVars === false) {
1896 p.dataType = this.getTypeDeclaration(cm.classname);
1897 imports.add(p.dataType);
1898 }
1899 else {
1900 const prop = PropertyBuilder_1.default.build(impl.getType(), impl.getFormat(), null);
1901 prop.setRequired(bp.getRequired());
1902 const cp = this.fromProperty('property', prop);
1903 if (cp != null) {
1904 p.baseType = cp.baseType;
1905 p.dataType = cp.datatype;
1906 p.isPrimitiveType = cp.isPrimitiveType;
1907 p.isBinary = this.isDataTypeBinary(cp.datatype);
1908 }
1909 this.setParameterBooleanFlagWithCodegenProperty(p, cp);
1910 }
1911 }
1912 else if (model != null && model instanceof ArrayModel_1.default) {
1913 const impl = model;
1914 const ap = new properties_1.ArrayProperty().items(impl.getItems());
1915 ap.setRequired(param.getRequired());
1916 const cp = this.fromProperty('inner', ap);
1917 if (cp.complexType != null) {
1918 imports.add(cp.complexType);
1919 }
1920 imports.add(cp.baseType);
1921 p.dataType = cp.datatype;
1922 p.baseType = cp.complexType || cp.baseType;
1923 p.isPrimitiveType = cp.isPrimitiveType;
1924 p.isContainer = true;
1925 p.isListContainer = true;
1926 this.setParameterBooleanFlagWithCodegenProperty(p, cp);
1927 }
1928 else {
1929 const sub = bp.getSchema();
1930 if (sub != null && sub instanceof RefModel_1.default) {
1931 let name = sub.getSimpleRef();
1932 if (this.__typeMapping.containsKey(name)) {
1933 name = this.__typeMapping.get(name);
1934 }
1935 else {
1936 name = this.toModelName(name);
1937 if (this.__defaultIncludes.contains(name)) {
1938 imports.add(name);
1939 }
1940 imports.add(name);
1941 name = this.getTypeDeclaration(name);
1942 }
1943 p.dataType = name;
1944 p.baseType = name;
1945 }
1946 }
1947 p.paramName = this.toParamName(bp.getName());
1948 }
1949 if (p.vendorExtensions && p.vendorExtensions.containsKey('x-example')) {
1950 p.example = p.vendorExtensions.get('x-example') + '';
1951 }
1952 else if (p.isString) {
1953 p.example = p.paramName + '_example';
1954 }
1955 else if (p.isBoolean) {
1956 p.example = 'true';
1957 }
1958 else if (p.isLong) {
1959 p.example = '789';
1960 }
1961 else if (p.isInteger) {
1962 p.example = '56';
1963 }
1964 else if (p.isFloat) {
1965 p.example = '3.4';
1966 }
1967 else if (p.isDouble) {
1968 p.example = '1.2';
1969 }
1970 else if (p.isBinary) {
1971 p.example = 'BINARY_DATA_HERE';
1972 }
1973 else if (p.isByteArray) {
1974 p.example = 'B';
1975 }
1976 else if (p.isDate) {
1977 p.example = '2013-10-20';
1978 }
1979 else if (p.isDateTime) {
1980 p.example = '2013-10-20T19:20:30+01:00';
1981 }
1982 else if (param != null &&
1983 param instanceof parameters_1.FormParameter &&
1984 (((o1, o2) => o1.toUpperCase() === (o2 === null ? o2 : o2.toUpperCase()))('file', param.getType()) ||
1985 'file' === p.baseType)) {
1986 p.isFile = true;
1987 p.example = '/path/to/file.txt';
1988 }
1989 this.setParameterExampleValue(p);
1990 if (param != null && param instanceof parameters_1.QueryParameter) {
1991 p.isQueryParam = true;
1992 }
1993 else if (param != null && param instanceof parameters_1.PathParameter) {
1994 p.required = true;
1995 p.isPathParam = true;
1996 }
1997 else if (param != null && param instanceof parameters_1.HeaderParameter) {
1998 p.isHeaderParam = true;
1999 }
2000 else if (param != null && param instanceof parameters_1.CookieParameter) {
2001 p.isCookieParam = true;
2002 }
2003 else if (param != null && param instanceof parameters_1.BodyParameter) {
2004 p.isBodyParam = true;
2005 p.isBinary = this.isDataTypeBinary(p.dataType);
2006 }
2007 else if (param != null && param instanceof parameters_1.FormParameter) {
2008 if (((o1, o2) => o1.toUpperCase() === (o2 === null ? o2 : o2.toUpperCase()))('file', param.getType())) {
2009 p.isFile = true;
2010 }
2011 else if ('file' === p.baseType) {
2012 p.isFile = true;
2013 }
2014 else {
2015 p.notFile = true;
2016 }
2017 p.isFormParam = true;
2018 }
2019 this.postProcessParameter(p);
2020 return p;
2021 }
2022 isDataTypeBinary(dataType) {
2023 return dataType && dataType.toLowerCase().startsWith('byte');
2024 }
2025 /**
2026 * Convert map of Swagger SecuritySchemeDefinition objects to a list of Codegen Security objects
2027 *
2028 * @param schemes a map of Swagger SecuritySchemeDefinition object
2029 * @return a list of Codegen Security objects
2030 */
2031 fromSecurity(schemes) {
2032 if (schemes == null) {
2033 return javaUtil_1.Collections.emptyList();
2034 }
2035 const secs = [];
2036 let sec;
2037 for (const [name, schemeDefinition] of schemes) {
2038 sec = CodegenModelFactory_1.default.newInstance(CodegenModelType_1.default.SECURITY);
2039 sec.name = name;
2040 sec.type = schemeDefinition.getType();
2041 sec.isCode = sec.isPassword = sec.isApplication = sec.isImplicit = false;
2042 if (schemeDefinition != null &&
2043 schemeDefinition instanceof ApiKeyAuthDefinition_1.default) {
2044 const apiKeyDefinition = schemeDefinition;
2045 sec.isBasic = sec.isOAuth = false;
2046 sec.isApiKey = true;
2047 sec.keyParamName = apiKeyDefinition.getName();
2048 sec.isKeyInHeader = apiKeyDefinition.getIn() === In_1.In.HEADER;
2049 sec.isKeyInQuery = !sec.isKeyInHeader;
2050 }
2051 else if (schemeDefinition != null &&
2052 schemeDefinition instanceof BasicAuthDefinition_1.default) {
2053 sec.isKeyInHeader = sec.isKeyInQuery = sec.isApiKey = sec.isOAuth = false;
2054 sec.isBasic = true;
2055 }
2056 else {
2057 const oauth2Definition = schemeDefinition;
2058 sec.isKeyInHeader = sec.isKeyInQuery = sec.isApiKey = sec.isBasic = false;
2059 sec.isOAuth = true;
2060 sec.flow = oauth2Definition.getFlow();
2061 switch (sec.flow) {
2062 case 'accessCode':
2063 sec.isCode = true;
2064 break;
2065 case 'password':
2066 sec.isPassword = true;
2067 break;
2068 case 'application':
2069 sec.isApplication = true;
2070 break;
2071 case 'implicit':
2072 sec.isImplicit = true;
2073 break;
2074 default:
2075 throw new Error('unknown oauth flow: ' + sec.flow);
2076 }
2077 sec.authorizationUrl = oauth2Definition.getAuthorizationUrl();
2078 sec.tokenUrl = oauth2Definition.getTokenUrl();
2079 if (oauth2Definition.getScopes() != null) {
2080 const scopes = [];
2081 let count = 0;
2082 const numScopes = oauth2Definition.getScopes().size;
2083 for (const [n, description] of javaUtil_1.asMap(oauth2Definition.getScopes())) {
2084 const scope = javaUtil_1.newHashMap(['scope', n], ['description', description]);
2085 count += 1;
2086 if (count < numScopes) {
2087 scope.put('hasMore', 'true');
2088 }
2089 else {
2090 scope.put('hasMore', null);
2091 }
2092 scopes.push(scope);
2093 }
2094 sec.scopes = scopes;
2095 }
2096 }
2097 secs.push(sec);
2098 }
2099 if (sec) {
2100 sec.hasMore = false;
2101 }
2102 return secs;
2103 }
2104 setReservedWordsLowerCase(words) {
2105 this.__reservedWords = javaUtil_1.newHashSet();
2106 for (const word of words) {
2107 this.__reservedWords.add(word.toLowerCase());
2108 }
2109 }
2110 isReservedWord(word) {
2111 return word != null && this.__reservedWords.contains(word.toLowerCase());
2112 }
2113 /**
2114 * Get operationId from the operation object, and if it's blank, generate a new one from the given parameters.
2115 *
2116 * @param operation the operation object
2117 * @param p the path of the operation
2118 * @param httpMethod the HTTP method of the operation
2119 * @return the (generated) operationId
2120 */
2121 getOrGenerateOperationId(operation, p, httpMethod) {
2122 let operationId = operation.getOperationId();
2123 if (StringUtils_1.default.isBlank(operationId)) {
2124 let tmpPath = p;
2125 tmpPath = tmpPath.replace(new RegExp('\\{', 'g'), '');
2126 tmpPath = tmpPath.replace(new RegExp('\\}', 'g'), '');
2127 const parts = (tmpPath + '/' + httpMethod).split('/');
2128 const builder = StringBuilder_1.default();
2129 if ('/' === tmpPath) {
2130 builder.append('root');
2131 }
2132 for (let part of parts) {
2133 if (part.length > 0) {
2134 if (builder.length() === 0) {
2135 part = StringUtils_1.default.lowerFirst(part);
2136 }
2137 else {
2138 part = this.initialCaps(part);
2139 }
2140 builder.append(part);
2141 }
2142 }
2143 operationId = this.sanitizeName(builder.toString());
2144 Log.warn('Empty operationId found for path: ' +
2145 httpMethod +
2146 ' ' +
2147 p +
2148 '. Renamed to auto-generated operationId: ' +
2149 operationId);
2150 }
2151 return operationId;
2152 }
2153 /**
2154 * Check the type to see if it needs import the library/module/package
2155 *
2156 * @param type name of the type
2157 * @return true if the library/module/package of the corresponding type needs to be imported
2158 */
2159 needToImport(type) {
2160 return (!this.__defaultIncludes.contains(type) &&
2161 !this.__languageSpecificPrimitives.contains(type));
2162 }
2163 toExamples(examples) {
2164 if (examples == null) {
2165 return null;
2166 }
2167 const output = [];
2168 for (const [contentType, example] of javaUtil_1.asMap(examples)) {
2169 output.push(javaUtil_1.newHashMap(['contentType', contentType], ['example', example]));
2170 }
2171 return output;
2172 }
2173 addHeaders(response, target) {
2174 if (response.getHeaders() != null) {
2175 for (const [key, value] of response.getHeaders()) {
2176 target.push(this.fromProperty(key, factory_1.default(value)));
2177 }
2178 }
2179 }
2180 /**
2181 * Add operation to group
2182 *
2183 * @param tag name of the tag
2184 * @param resourcePath path of the resource
2185 * @param operation Swagger Operation object
2186 * @param co Codegen Operation object
2187 * @param operations map of Codegen operations
2188 */
2189 addOperationToGroup(tag, resourcePath, operation, co, operations) {
2190 let opList = operations.get(tag);
2191 if (opList == null) {
2192 opList = [];
2193 operations.put(tag, opList);
2194 }
2195 let uniqueName = co.operationId;
2196 let counter = 0;
2197 for (const op of opList) {
2198 if (uniqueName === op.operationId) {
2199 uniqueName = co.operationId + '_' + counter;
2200 counter++;
2201 }
2202 }
2203 if (!(co.operationId === uniqueName)) {
2204 Log.warn('generated unique operationId `' + uniqueName + '`');
2205 }
2206 co.operationId = uniqueName;
2207 co.operationIdLowerCase = uniqueName.toLowerCase();
2208 opList.push(co);
2209 co.baseName = tag;
2210 }
2211 addParentContainer(m, name, property) {
2212 const tmp = this.fromProperty(name, property);
2213 this.addImport(m, tmp.complexType);
2214 m.parent = this.toInstantiationType(property);
2215 const containerType = tmp.containerType;
2216 const instantiationType = this.__instantiationTypes.get(containerType);
2217 if (instantiationType != null) {
2218 this.addImport(m, instantiationType);
2219 }
2220 const mappedType = this.__typeMapping.get(containerType);
2221 if (mappedType != null) {
2222 this.addImport(m, mappedType);
2223 }
2224 }
2225 /**
2226 * Dashize the given word.
2227 *
2228 * @param word The word
2229 * @return The dashized version of the word, e.g. "my-name"
2230 */
2231 dashize(word) {
2232 return DefaultCodegen.underscore(word).replace(new RegExp('[_ ]', 'g'), '-');
2233 }
2234 addImport(m, type) {
2235 if (type != null && this.needToImport(type)) {
2236 m.imports.add(type);
2237 }
2238 }
2239 addVars(m, properties, required, allProperties, allRequired) {
2240 if (arguments.length > 4) {
2241 m.hasRequired = false;
2242 if (properties != null && !properties.isEmpty()) {
2243 m.hasVars = true;
2244 m.hasEnums = false;
2245 const mandatory = required == null
2246 ? javaUtil_1.Collections.emptySet()
2247 : new Set(required.concat().sort());
2248 this._addVars(m, m.vars, properties, mandatory);
2249 m.allMandatory = m.mandatory = mandatory;
2250 }
2251 else {
2252 m.emptyVars = true;
2253 m.hasVars = false;
2254 m.hasEnums = false;
2255 }
2256 if (allProperties != null) {
2257 const allMandatory = allRequired == null
2258 ? javaUtil_1.Collections.emptySet()
2259 : new Set(allRequired.concat().sort());
2260 this._addVars(m, m.allVars, allProperties, allMandatory);
2261 m.allMandatory = allMandatory;
2262 }
2263 }
2264 else if (arguments.length > 3) {
2265 return this._addVars(m, properties, required, allProperties);
2266 }
2267 else {
2268 return this.addVars(m, properties, required, null, null);
2269 }
2270 }
2271 _addVars(m, vars, properties, mandatory) {
2272 const propertyList = properties.entrySet().toArray();
2273 const totalCount = propertyList.length;
2274 for (let i = 0; i < totalCount; i++) {
2275 const entry = propertyList[i];
2276 const key = entry.getKey();
2277 const prop = entry.getValue();
2278 if (prop == null) {
2279 Log.warn('null property for ' + key);
2280 continue;
2281 }
2282 const cp = this.fromProperty(key, prop);
2283 if (mandatory.has) {
2284 cp.required = mandatory.has(key) ? true : null;
2285 }
2286 else {
2287 cp.required = mandatory.hasOwnProperty(key) ? true : null;
2288 }
2289 m.hasRequired = m.hasRequired || cp.required;
2290 if (cp.isEnum) {
2291 m.hasEnums = true;
2292 }
2293 if (!cp.isReadOnly) {
2294 m.hasOnlyReadOnly = false;
2295 }
2296 if (i + 1 !== totalCount) {
2297 cp.hasMore = true;
2298 if (!propertyList[i + 1].getValue().getReadOnly()) {
2299 cp.hasMoreNonReadOnly = true;
2300 }
2301 }
2302 if (cp.isContainer != null) {
2303 this.addImport(m, this.__typeMapping.get('array'));
2304 }
2305 this.addImport(m, cp.baseType);
2306 let innerCp = cp;
2307 while (innerCp != null) {
2308 this.addImport(m, innerCp.complexType);
2309 innerCp = innerCp.items;
2310 }
2311 vars.push(cp);
2312 if (cp.required) {
2313 m.requiredVars.push(cp);
2314 }
2315 else {
2316 m.optionalVars.push(cp);
2317 }
2318 if (cp.isReadOnly) {
2319 m.readOnlyVars.push(cp);
2320 }
2321 else {
2322 m.readWriteVars.push(cp);
2323 }
2324 }
2325 }
2326 /**
2327 * Remove characters that is not good to be included in method name from the input and camelize it
2328 *
2329 * @param name string to be camelize
2330 * @param nonNameElementPattern a regex pattern of the characters that is not good to be included in name
2331 * @return camelized string
2332 */
2333 removeNonNameElementToCamelCase(name, nonNameElementPattern = '[-_:;#]') {
2334 let result = StringUtils_1.default.join(javaUtil_1.Lists.transform(javaUtil_1.Lists.newArrayList(name.split(nonNameElementPattern)), input => StringUtils_1.default.capitalize(input)), '');
2335 if (result.length > 0) {
2336 result = StringUtils_1.default.lowerFirst(result);
2337 }
2338 return result;
2339 }
2340 apiFilename(templateName, tag) {
2341 const suffix = this.apiTemplateFiles().get(templateName);
2342 return this.apiFileFolder() + path_1.default.sep + this.toApiFilename(tag) + suffix;
2343 }
2344 apiDataFilename(templateName, tag) {
2345 const suffix = this.apiDataTemplateFile().get(templateName);
2346 return this.apiFileFolder() + path_1.default.sep + this.toModelName(tag) + suffix;
2347 }
2348 /**
2349 * Return the full path and API documentation file
2350 *
2351 * @param templateName template name
2352 * @param tag tag
2353 *
2354 * @return the API documentation file name with full path
2355 */
2356 apiDocFilename(templateName, tag) {
2357 const suffix = this.apiDocTemplateFiles().get(templateName);
2358 return this.apiDocFileFolder() + this.toApiDocFilename(tag) + suffix;
2359 }
2360 /**
2361 * Return the full path and API test file
2362 *
2363 * @param templateName template name
2364 * @param tag tag
2365 *
2366 * @return the API test file name with full path
2367 */
2368 apiTestFilename(templateName, tag) {
2369 const suffix = this.apiTestTemplateFiles().get(templateName);
2370 return (this.apiTestFileFolder() + path_1.default.sep + this.toApiTestFilename(tag) + suffix);
2371 }
2372 shouldOverwrite(filename) {
2373 return !(this.skipOverwrite && new File_1.default(filename).exists());
2374 }
2375 isSkipOverwrite() {
2376 return this.skipOverwrite;
2377 }
2378 setSkipOverwrite(skipOverwrite) {
2379 this.skipOverwrite = skipOverwrite;
2380 }
2381 /**
2382 * All library templates supported.
2383 * (key: library name, value: library description)
2384 * @return the supported libraries
2385 */
2386 supportedLibraries() {
2387 return this.__supportedLibraries;
2388 }
2389 /**
2390 * Set library template (sub-template).
2391 *
2392 * @param library Library template
2393 */
2394 setLibrary(library) {
2395 if (library != null && !this.__supportedLibraries.containsKey(library)) {
2396 throw new Error('unknown library: ' + library);
2397 }
2398 this.library = library;
2399 }
2400 /**
2401 * Library template (sub-template).
2402 *
2403 * @return Library template
2404 */
2405 getLibrary() {
2406 return this.library;
2407 }
2408 /**
2409 * Set Git user ID.
2410 *
2411 * @param gitUserId Git user ID
2412 */
2413 setGitUserId(gitUserId) {
2414 this.gitUserId = gitUserId;
2415 }
2416 /**
2417 * Git user ID
2418 *
2419 * @return Git user ID
2420 */
2421 getGitUserId() {
2422 return this.gitUserId;
2423 }
2424 /**
2425 * Set Git repo ID.
2426 *
2427 * @param gitRepoId Git repo ID
2428 */
2429 setGitRepoId(gitRepoId) {
2430 this.gitRepoId = gitRepoId;
2431 }
2432 /**
2433 * Git repo ID
2434 *
2435 * @return Git repo ID
2436 */
2437 getGitRepoId() {
2438 return this.gitRepoId;
2439 }
2440 /**
2441 * Set release note.
2442 *
2443 * @param releaseNote Release note
2444 */
2445 setReleaseNote(releaseNote) {
2446 this.releaseNote = releaseNote;
2447 }
2448 /**
2449 * Release note
2450 *
2451 * @return Release note
2452 */
2453 getReleaseNote() {
2454 return this.releaseNote;
2455 }
2456 /**
2457 * Set HTTP user agent.
2458 *
2459 * @param httpUserAgent HTTP user agent
2460 */
2461 setHttpUserAgent(httpUserAgent) {
2462 this.httpUserAgent = httpUserAgent;
2463 }
2464 /**
2465 * HTTP user agent
2466 *
2467 * @return HTTP user agent
2468 */
2469 getHttpUserAgent() {
2470 return this.httpUserAgent;
2471 }
2472 buildLibraryCliOption(supportedLibraries) {
2473 const sb = StringBuilder_1.default('library template (sub-template) to use:');
2474 for (const [key, lib] of supportedLibraries) {
2475 sb.append('\n')
2476 .append(key)
2477 .append(' - ')
2478 .append(lib);
2479 }
2480 return new CliOption_1.default('library', sb.toString());
2481 }
2482 /**
2483 * Sanitize name (parameter, property, method, etc)
2484 *
2485 * @param name string to be sanitize
2486 * @return sanitized string
2487 */
2488 sanitizeName(name) {
2489 if (name == null) {
2490 Log.error('String to be sanitized is null. Default to ERROR_UNKNOWN');
2491 return 'ERROR_UNKNOWN';
2492 }
2493 if ('$' === name) {
2494 return 'value';
2495 }
2496 name = name.replace(new RegExp('\\[\\]', 'g'), '');
2497 name = name.replace(new RegExp('\\[', 'g'), '_');
2498 name = name.replace(new RegExp('\\]', 'g'), '');
2499 name = name.replace(new RegExp('\\(', 'g'), '_');
2500 name = name.replace(new RegExp('\\)', 'g'), '');
2501 name = name.replace(new RegExp('\\.', 'g'), '_');
2502 name = name.replace(new RegExp('-', 'g'), '_');
2503 name = name.replace(new RegExp(' ', 'g'), '_');
2504 return name.replace(new RegExp('[^a-zA-Z0-9_]', 'g'), '');
2505 }
2506 /**
2507 * Sanitize tag
2508 *
2509 * @param tag Tag
2510 * @return Sanitized tag
2511 */
2512 sanitizeTag(tag) {
2513 const parts = tag.split(' ');
2514 const buf = StringBuilder_1.default();
2515 for (const part of parts) {
2516 {
2517 if (StringUtils_1.default.isNotEmpty(part)) {
2518 buf.append(StringUtils_1.default.capitalize(part));
2519 }
2520 }
2521 }
2522 return buf.toString().replace(new RegExp('[^a-zA-Z ]', 'g'), '');
2523 }
2524 /**
2525 * Only write if the file doesn't exist
2526 *
2527 * @param outputFolder Output folder
2528 * @param supportingFile Supporting file
2529 */
2530 writeOptional(outputFolder, supportingFile) {
2531 let folder = '';
2532 if (outputFolder != null && !('' === outputFolder)) {
2533 folder += outputFolder + File_1.default.separator;
2534 }
2535 folder += supportingFile.folder;
2536 if (!('' === folder)) {
2537 folder += File_1.default.separator + supportingFile.destinationFilename;
2538 }
2539 else {
2540 folder = supportingFile.destinationFilename;
2541 }
2542 if (!new File_1.default(folder).exists()) {
2543 this.__supportingFiles.push(supportingFile);
2544 }
2545 else {
2546 Log.info('Skipped overwriting ' +
2547 supportingFile.destinationFilename +
2548 ' as the file already exists in ' +
2549 folder);
2550 }
2551 }
2552 /**
2553 * Set CodegenParameter boolean flag using CodegenProperty.
2554 *
2555 * @param parameter Codegen Parameter
2556 * @param property Codegen property
2557 */
2558 setParameterBooleanFlagWithCodegenProperty(parameter, property) {
2559 if (parameter == null) {
2560 Log.error('Codegen Parameter cannnot be null.');
2561 return;
2562 }
2563 if (property == null) {
2564 Log.error('Codegen Property cannot be null.');
2565 return;
2566 }
2567 if (property.isString) {
2568 parameter.isString = true;
2569 parameter.isPrimitiveType = true;
2570 }
2571 else if (property.isBoolean) {
2572 parameter.isBoolean = true;
2573 parameter.isPrimitiveType = true;
2574 }
2575 else if (property.isLong) {
2576 parameter.isLong = true;
2577 parameter.isPrimitiveType = true;
2578 }
2579 else if (property.isInteger) {
2580 parameter.isInteger = true;
2581 parameter.isPrimitiveType = true;
2582 }
2583 else if (property.isDouble) {
2584 parameter.isDouble = true;
2585 parameter.isPrimitiveType = true;
2586 }
2587 else if (property.isFloat) {
2588 parameter.isFloat = true;
2589 parameter.isPrimitiveType = true;
2590 }
2591 else if (property.isByteArray) {
2592 parameter.isByteArray = true;
2593 parameter.isPrimitiveType = true;
2594 }
2595 else if (property.isBinary) {
2596 parameter.isByteArray = true;
2597 parameter.isPrimitiveType = true;
2598 }
2599 else if (property.isDate) {
2600 parameter.isDate = true;
2601 parameter.isPrimitiveType = true;
2602 }
2603 else if (property.isDateTime) {
2604 parameter.isDateTime = true;
2605 parameter.isPrimitiveType = true;
2606 }
2607 else {
2608 Log.debug('Property type is not primitive: ' + property.datatype);
2609 }
2610 if (property.isListContainer && property.items) {
2611 if (property.items.isString) {
2612 parameter.isItemString = true;
2613 }
2614 else if (property.items.isBoolean) {
2615 parameter.isItemBoolean = true;
2616 }
2617 else if (property.items.isLong) {
2618 parameter.isItemLong = true;
2619 }
2620 else if (property.items.isInteger) {
2621 parameter.isItemInteger = true;
2622 }
2623 else if (property.items.isDouble) {
2624 parameter.isItemDouble = true;
2625 }
2626 else if (property.items.isFloat) {
2627 parameter.isItemFloat = true;
2628 }
2629 else if (property.items.isByteArray) {
2630 parameter.isItemByteArray = true;
2631 }
2632 else if (property.items.isBinary) {
2633 parameter.isItemByteArray = true;
2634 }
2635 else if (property.items.isDate) {
2636 parameter.isItemDate = true;
2637 }
2638 else if (property.items.isDateTime) {
2639 parameter.isItemDateTime = true;
2640 }
2641 else {
2642 Log.debug('Property item type is not primitive: ' + property.datatype);
2643 }
2644 }
2645 }
2646 /**
2647 * Update codegen property's enum by adding "enumVars" (with name and value)
2648 *
2649 * @param var list of CodegenProperty
2650 */
2651 updateCodegenPropertyEnum(__var) {
2652 let allowableValues = __var.allowableValues;
2653 if (__var.items != null) {
2654 allowableValues = __var.items.allowableValues;
2655 }
2656 if (allowableValues == null) {
2657 return;
2658 }
2659 const values = allowableValues.get('values');
2660 if (values == null) {
2661 return;
2662 }
2663 const enumVars = [];
2664 const commonPrefix = this.findCommonPrefixOfVars(values);
2665 const truncateIdx = commonPrefix.length;
2666 for (const value of values) {
2667 const enumVar = javaUtil_1.newHashMap();
2668 let enumName;
2669 if (truncateIdx === 0) {
2670 enumName = value.toString();
2671 }
2672 else {
2673 enumName = value.toString().substring(truncateIdx);
2674 if ('' === enumName) {
2675 enumName = value.toString();
2676 }
2677 }
2678 enumVar.put('name', this.toEnumVarName(enumName, __var.datatype));
2679 enumVar.put('value', this.toEnumValue(value.toString(), __var.datatype));
2680 enumVars.push(enumVar);
2681 }
2682 allowableValues.put('enumVars', enumVars);
2683 if (__var.defaultValue != null) {
2684 let enumName = null;
2685 for (const enumVar of enumVars) {
2686 if (this.toEnumValue(__var.defaultValue, __var.datatype) ===
2687 enumVar.get('value')) {
2688 enumName = enumVar.get('name');
2689 break;
2690 }
2691 }
2692 if (enumName != null) {
2693 __var.defaultValue = this.toEnumDefaultValue(enumName, __var.datatypeWithEnum);
2694 }
2695 }
2696 }
2697}
2698exports.default = DefaultCodegen;
2699const Log = LoggerFactory_1.default.getLogger(DefaultCodegen);
2700//# sourceMappingURL=DefaultCodegen.js.map
\No newline at end of file