AbstractOpenapiApiReader.java

  1. /*
  2.  * GovWay - A customizable API Gateway
  3.  * https://govway.org
  4.  *
  5.  * Copyright (c) 2005-2025 Link.it srl (https://link.it).
  6.  *
  7.  * This program is free software: you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License version 3, as published by
  9.  * the Free Software Foundation.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  *
  19.  */


  20. package org.openspcoop2.utils.openapi;

  21. import java.io.File;
  22. import java.net.URI;
  23. import java.net.URL;
  24. import java.util.ArrayList;
  25. import java.util.Iterator;
  26. import java.util.List;

  27. import org.openspcoop2.utils.Utilities;
  28. import org.openspcoop2.utils.json.YAMLUtils;
  29. import org.openspcoop2.utils.resources.Charset;
  30. import org.openspcoop2.utils.resources.FileSystemUtilities;
  31. import org.openspcoop2.utils.rest.ApiFormats;
  32. import org.openspcoop2.utils.rest.ApiReaderConfig;
  33. import org.openspcoop2.utils.rest.IApiReader;
  34. import org.openspcoop2.utils.rest.ProcessingException;
  35. import org.openspcoop2.utils.rest.api.AbstractApiParameter;
  36. import org.openspcoop2.utils.rest.api.Api;
  37. import org.openspcoop2.utils.rest.api.ApiBodyParameter;
  38. import org.openspcoop2.utils.rest.api.ApiCookieParameter;
  39. import org.openspcoop2.utils.rest.api.ApiHeaderParameter;
  40. import org.openspcoop2.utils.rest.api.ApiOperation;
  41. import org.openspcoop2.utils.rest.api.ApiParameterSchema;
  42. import org.openspcoop2.utils.rest.api.ApiParameterSchemaComplexType;
  43. import org.openspcoop2.utils.rest.api.ApiReference;
  44. import org.openspcoop2.utils.rest.api.ApiRequest;
  45. import org.openspcoop2.utils.rest.api.ApiRequestDynamicPathParameter;
  46. import org.openspcoop2.utils.rest.api.ApiRequestFormParameter;
  47. import org.openspcoop2.utils.rest.api.ApiRequestQueryParameter;
  48. import org.openspcoop2.utils.rest.api.ApiResponse;
  49. import org.openspcoop2.utils.rest.api.ApiSchema;
  50. import org.openspcoop2.utils.rest.api.ApiSchemaTypeRestriction;
  51. import org.openspcoop2.utils.transport.http.HttpRequestMethod;
  52. import org.slf4j.Logger;
  53. import org.w3c.dom.Document;
  54. import org.w3c.dom.Element;

  55. import io.swagger.v3.oas.models.OpenAPI;
  56. import io.swagger.v3.oas.models.Operation;
  57. import io.swagger.v3.oas.models.PathItem;
  58. import io.swagger.v3.oas.models.headers.Header;
  59. import io.swagger.v3.oas.models.media.ArraySchema;
  60. import io.swagger.v3.oas.models.media.ComposedSchema;
  61. import io.swagger.v3.oas.models.media.MediaType;
  62. import io.swagger.v3.oas.models.media.Schema;
  63. import io.swagger.v3.oas.models.parameters.CookieParameter;
  64. import io.swagger.v3.oas.models.parameters.HeaderParameter;
  65. import io.swagger.v3.oas.models.parameters.Parameter;
  66. import io.swagger.v3.oas.models.parameters.PathParameter;
  67. import io.swagger.v3.oas.models.parameters.QueryParameter;
  68. import io.swagger.v3.oas.models.parameters.RequestBody;
  69. import io.swagger.v3.parser.OpenAPIV3Parser;
  70. import io.swagger.v3.parser.converter.SwaggerConverter;
  71. import io.swagger.v3.parser.core.models.ParseOptions;
  72. import io.swagger.v3.parser.core.models.SwaggerParseResult;


  73. /**
  74.  * AbstractOpenapiApiReader
  75.  *
  76.  * @author Andrea Poli (apoli@link.it)
  77.  * @author $Author$
  78.  * @version $Rev$, $Date$
  79.  *
  80.  */
  81. public abstract class AbstractOpenapiApiReader implements IApiReader {

  82.     private OpenAPI openApi;
  83.     private String openApiRaw;
  84.     private ApiFormats format;
  85.     private ParseOptions parseOptions;
  86.     private List<ApiSchema> schemas;
  87.     private boolean resolveExternalRef = true;
  88.     private String parseWarningResult;
  89.    
  90.     private boolean debug;
  91.     public void setDebug(boolean debug) {
  92.         this.debug = debug;
  93.     }

  94.     public AbstractOpenapiApiReader(ApiFormats format) {
  95.         this.format = format;
  96.         this.parseOptions = new ParseOptions();
  97.         this.schemas = new ArrayList<>();
  98.     }

  99.     protected static OpenAPI parseResult(Logger log, SwaggerParseResult pr, StringBuilder sbParseWarningResult) throws ProcessingException {
  100.         if(pr==null) {
  101.             throw new ProcessingException("Parse result undefined");
  102.         }
  103.         StringBuilder bfMessage = new StringBuilder();
  104.         if(pr.getMessages()!=null && pr.getMessages().size()>0) {
  105.             for (String msg : pr.getMessages()) {
  106.                 if(bfMessage.length()>0) {
  107.                     bfMessage.append("\n");
  108.                 }
  109.                 bfMessage.append("- ").append(msg);
  110.             }
  111.         }
  112.         OpenAPI openApi = null;
  113.         if(pr.getOpenAPI()!=null) {
  114.             openApi = pr.getOpenAPI();
  115.             if(bfMessage.length()>0) {
  116.                 log.debug(bfMessage.toString());
  117.                 sbParseWarningResult.append(bfMessage.toString());
  118.             }
  119.         }
  120.         else {
  121.             if(bfMessage.length()>0) {
  122.                 throw new ProcessingException("Parse failed: "+bfMessage.toString());
  123.             }
  124.             else {
  125.                 throw new ProcessingException("Parse failed");
  126.             }
  127.         }
  128.         return openApi;
  129.     }
  130.    
  131.    
  132.     @Override
  133.     public void init(Logger log, String content, ApiReaderConfig config) throws ProcessingException {
  134.         this._init(log, content, config);
  135.     }
  136.     @Override
  137.     public void init(Logger log, String content, ApiReaderConfig config, ApiSchema ... schema) throws ProcessingException {
  138.         this._init(log, content, config, schema);
  139.     }
  140.     private void _init(Logger log, String contentParam, ApiReaderConfig config, ApiSchema ... schema) throws ProcessingException {
  141.        
  142.         String content = contentParam;
  143.         try {
  144.             YAMLUtils yamlUtils = YAMLUtils.getInstance();
  145.             boolean apiRawIsYaml = yamlUtils.isYaml(content);
  146.             if(apiRawIsYaml) {
  147.                 // Fix merge key '<<: *'
  148.                 if(YAMLUtils.containsMergeKeyAnchor(content)) {
  149.                     // Risoluzione merge key '<<: *'
  150.                     String jsonRepresentation = YAMLUtils.resolveMergeKeyAndConvertToJson(content);
  151.                     if(jsonRepresentation!=null) {
  152.                         content = jsonRepresentation;
  153.                     }
  154.                 }
  155.             }
  156.         }catch(Throwable t) {
  157.             log.error("Find and resolve merge key failed: "+t.getMessage(),t);
  158.             content = contentParam;
  159.         }
  160.        
  161.         try {
  162.             SwaggerParseResult pr = null;
  163.             if(ApiFormats.SWAGGER_2.equals(this.format)) {
  164.                 pr = new SwaggerConverter().readContents(content, null, this.parseOptions);
  165.             }
  166.             else {
  167.                 pr = new OpenAPIV3Parser().readContents(content, null, this.parseOptions);
  168.             }
  169.             StringBuilder sbParseWarningResult = new StringBuilder();
  170.             this.openApi = parseResult(log, pr, sbParseWarningResult);
  171.             if(sbParseWarningResult.length()>0) {
  172.                 this.parseWarningResult = sbParseWarningResult.toString();
  173.             }
  174.            
  175.             this.openApiRaw = content;
  176.                    
  177.             if(schema!=null && schema.length>0) {
  178.                 for (int i = 0; i < schema.length; i++) {
  179.                     this.schemas.add(schema[i]);
  180.                 }
  181.             }
  182.            
  183.             this.resolveExternalRef = config.isProcessInclude();
  184.            
  185.         } catch(Exception e) {
  186.             throw new ProcessingException(e);
  187.         }

  188.     }

  189.     @Override
  190.     public void init(Logger log, byte[] content, ApiReaderConfig config) throws ProcessingException {
  191.         this._init(log, content, config);
  192.     }
  193.     @Override
  194.     public void init(Logger log, byte[] content, ApiReaderConfig config, ApiSchema ... schema) throws ProcessingException {
  195.         this._init(log, content, config, schema);
  196.     }
  197.     private void _init(Logger log, byte[] content, ApiReaderConfig config, ApiSchema ... schema) throws ProcessingException {
  198.         String s = null;
  199.         try {
  200.             String charset = config!=null?config.getCharset().getValue():Charset.UTF_8.getValue();
  201.             s = new String(content,charset);
  202.         } catch(Exception e) {
  203.             throw new ProcessingException(e);
  204.         }
  205.         this._init(log, s, config, schema);
  206.     }
  207.    
  208.    
  209.    
  210.     @Override
  211.     public void init(Logger log, File file, ApiReaderConfig config) throws ProcessingException {
  212.         this._init(log, file, config);
  213.     }
  214.     @Override
  215.     public void init(Logger log, File file, ApiReaderConfig config, ApiSchema ... schema) throws ProcessingException {
  216.         this._init(log, file, config, schema);
  217.     }
  218.     private void _init(Logger log, File file, ApiReaderConfig config, ApiSchema ... schema) throws ProcessingException {
  219.         byte[]c = null;
  220.         try {
  221.             c = FileSystemUtilities.readBytesFromFile(file);
  222.         } catch(Exception e) {
  223.             throw new ProcessingException(e);
  224.         }
  225.         this._init(log, c, config, schema);
  226.     }

  227.    
  228.    
  229.     @Override
  230.     public void init(Logger log, URI uri, ApiReaderConfig config) throws ProcessingException {
  231.         this._init(log, uri, config);
  232.     }
  233.     @Override
  234.     public void init(Logger log, URI uri, ApiReaderConfig config, ApiSchema ... schema) throws ProcessingException {
  235.         this._init(log, uri, config, schema);
  236.     }
  237.     private void _init(Logger log, URI uri, ApiReaderConfig config, ApiSchema ... schema) throws ProcessingException {
  238.         byte[]c = null;
  239.         try {
  240.             c = Utilities.getAsByteArray(uri.toURL().openStream());
  241.         } catch(Exception e) {
  242.             throw new ProcessingException(e);
  243.         }
  244.         this._init(log, c, config, schema);
  245.     }
  246.    
  247.    

  248.     @Override
  249.     public void init(Logger log, Document doc, ApiReaderConfig config) throws ProcessingException {
  250.         this._init(log, doc, config);
  251.     }
  252.     @Override
  253.     public void init(Logger log, Document doc, ApiReaderConfig config, ApiSchema ... schema) throws ProcessingException {
  254.         this._init(log, doc, config, schema);
  255.     }
  256.     private void _init(Logger log, Document doc, ApiReaderConfig config, ApiSchema ... schema) throws ProcessingException {
  257.         throw new ProcessingException("Not implemented");
  258.     }

  259.    
  260.    
  261.    
  262.     @Override
  263.     public void init(Logger log, Element element, ApiReaderConfig config) throws ProcessingException {
  264.         this._init(log, element, config);
  265.     }
  266.     @Override
  267.     public void init(Logger log, Element element, ApiReaderConfig config, ApiSchema ... schema) throws ProcessingException {
  268.         this._init(log, element, config, schema);
  269.     }
  270.     private void _init(Logger log, Element element, ApiReaderConfig config, ApiSchema ... schema) throws ProcessingException {
  271.         throw new ProcessingException("Not implemented");
  272.     }

  273.    

  274.     @Override
  275.     public Api read() throws ProcessingException {
  276.         if(this.openApi == null)
  277.             throw new ProcessingException("Api non correttamente inizializzata");
  278.         try {
  279.             OpenapiApi api = new OpenapiApi(this.format, this.openApi, this.openApiRaw, this.parseWarningResult);
  280.             if(!this.schemas.isEmpty()) {
  281.                 for (ApiSchema apiSchema : this.schemas) {
  282.                     api.addSchema(apiSchema);
  283.                 }
  284.             }
  285.             if(!this.openApi.getServers().isEmpty()) {
  286.                 String server = this.openApi.getServers().get(0).getUrl();
  287.                 URL url = null;
  288.                 try {
  289.                     url = new URL(server);
  290.                 }catch(Exception e) {
  291.                     // provo a verificare se il problema è che non e' stato definito il protocollo (es. in swagger lo 'schemes')
  292.                     if(server!=null && server.startsWith("/")) {
  293.                         if(!server.equals("/")) {
  294.                             server = "http:"+server;
  295.                             try {
  296.                                 url = new URL(server);
  297.                             }catch(Exception e2) {
  298.                                 // nop
  299.                             }
  300.                         }
  301.                     }
  302.                 }
  303.                 if(url!=null) {
  304.                     api.setBaseURL(url);
  305.                 }
  306.             }
  307.             if(this.openApi.getInfo()!=null) {
  308.                 api.setDescription(this.openApi.getInfo().getDescription());
  309.             }

  310.             if(this.openApi.getPaths() != null){
  311.                 for (String pathK : this.openApi.getPaths().keySet()) {
  312.                     PathItem path = this.openApi.getPaths().get(pathK);
  313.                     if(path.getGet() != null) {
  314.                         ApiOperation operation = getOperation(path.getGet(), path.getParameters(), HttpRequestMethod.GET, pathK, api);
  315.                         api.addOperation(operation);
  316.                     }
  317.                     if(path.getHead() != null) {
  318.                         ApiOperation operation = getOperation(path.getHead(), path.getParameters(), HttpRequestMethod.HEAD, pathK, api);
  319.                         api.addOperation(operation);
  320.                     }
  321.                     if(path.getPost() != null) {
  322.                         ApiOperation operation = getOperation(path.getPost(), path.getParameters(), HttpRequestMethod.POST, pathK, api);
  323.                         api.addOperation(operation);
  324.                     }
  325.                     if(path.getPut() != null) {
  326.                         ApiOperation operation = getOperation(path.getPut(), path.getParameters(), HttpRequestMethod.PUT, pathK, api);
  327.                         api.addOperation(operation);
  328.                     }
  329.                     if(path.getDelete() != null) {
  330.                         ApiOperation operation = getOperation(path.getDelete(), path.getParameters(), HttpRequestMethod.DELETE, pathK, api);
  331.                         api.addOperation(operation);
  332.                     }
  333.                     if(path.getOptions() != null) {
  334.                         ApiOperation operation = getOperation(path.getOptions(), path.getParameters(), HttpRequestMethod.OPTIONS, pathK, api);
  335.                         api.addOperation(operation);
  336.                     }
  337.                     if(path.getTrace() != null) {
  338.                         ApiOperation operation = getOperation(path.getTrace(), path.getParameters(), HttpRequestMethod.TRACE, pathK, api);
  339.                         api.addOperation(operation);
  340.                     }
  341.                     if(path.getPatch() != null) {
  342.                         ApiOperation operation = getOperation(path.getPatch(), path.getParameters(), HttpRequestMethod.PATCH, pathK, api);
  343.                         api.addOperation(operation);
  344.                     }
  345.                 }
  346.             }
  347.             return api;
  348.         } catch(Exception e){
  349.             throw new ProcessingException(e);
  350.         }
  351.     }

  352.     private ApiOperation getOperation(Operation operation, List<Parameter> listParameter, HttpRequestMethod method, String pathK, OpenapiApi api) {
  353.         ApiOperation apiOperation = new ApiOperation(method, pathK);
  354.         apiOperation.setDescription(operation.getDescription());
  355.         if( (listParameter!=null && !listParameter.isEmpty())
  356.                 ||
  357.                 (operation.getParameters() != null)
  358.                 ||
  359.                 (operation.getRequestBody() != null)
  360.             ) {
  361.             ApiRequest request = new ApiRequest();

  362.             if(listParameter!=null && !listParameter.isEmpty()) {
  363.                 for(Parameter param: listParameter) {
  364.                     addRequestParameter(param, request, method, pathK, api);
  365.                 }
  366.             }
  367.             if(operation.getParameters() != null) {
  368.                 for(Parameter param: operation.getParameters()) {
  369.                     addRequestParameter(param, request, method, pathK, api);
  370.                 }
  371.             }
  372.             if(operation.getRequestBody() != null) {
  373.                 List<ApiBodyParameter> lst = createRequestBody(operation.getRequestBody(), method, pathK, api);
  374.                 for(ApiBodyParameter param: lst) {
  375.                     request.addBodyParameter(param);
  376.                 }
  377.             }

  378.             apiOperation.setRequest(request);
  379.         }

  380.         if(operation.getResponses()!= null && !operation.getResponses().isEmpty()) {
  381.             List<ApiResponse> responses = new ArrayList<ApiResponse>();
  382.             for(String responseK: operation.getResponses().keySet()) {
  383.                 responses.add(createResponses(responseK, operation.getResponses().get(responseK), method, pathK, api));
  384.             }
  385.             apiOperation.setResponses(responses);
  386.         }

  387.         return apiOperation;
  388.     }

  389.     private List<ApiBodyParameter> createRequestBody(RequestBody requestBody, HttpRequestMethod method, String path, OpenapiApi api) {

  390.         if(requestBody.get$ref()!=null) {
  391.            
  392.             String ref = requestBody.get$ref();
  393.             boolean external = false;
  394.             if(ref.contains("#")) {
  395.                 external = !ref.trim().startsWith("#");
  396.                 ref = ref.substring(ref.indexOf("#"));
  397.             }
  398.             ref = ref.trim().replaceAll("#/components/requestBodies/", "").replaceAll("#/definitions/", "");
  399.            
  400.             if(api.getApi()==null) {
  401.                 throw new RuntimeException("Richiesta non corretta: api da cui risolvere la ref '"+requestBody.get$ref()+"' non trovata");
  402.             }
  403.             if(api.getApi().getComponents()==null) {
  404.                 if(!external || this.resolveExternalRef) {
  405.                     throw new RuntimeException("Richiesta non corretta: componenti, sui cui risolvere la ref '"+requestBody.get$ref()+"', non presenti");
  406.                 }
  407.             }
  408.             else {
  409.                 if(api.getApi().getComponents().getResponses()==null || api.getApi().getComponents().getResponses().size()<=0) {
  410.                     if(!external || this.resolveExternalRef) {
  411.                         throw new RuntimeException("Richiesta non corretta: richieste definite come componenti, sui cui risolvere la ref '"+requestBody.get$ref()+"', non presenti");
  412.                     }
  413.                 }
  414.                 else {
  415.                     boolean find = false;
  416.                     Iterator<String> itKeys = api.getApi().getComponents().getRequestBodies().keySet().iterator();
  417.                     while (itKeys.hasNext()) {
  418.                         String key = (String) itKeys.next();
  419.                         if(key.equals(ref)) {
  420.                             requestBody = api.getApi().getComponents().getRequestBodies().get(key);
  421.                             find = true;
  422.                             break;
  423.                         }
  424.                     }
  425.                     if(!find) {
  426.                         if(!external || this.resolveExternalRef) {
  427.                             throw new RuntimeException("Richiesta non corretta: ref '"+requestBody.get$ref()+"' non presente tra le richieste definite come componenti");
  428.                         }
  429.                     }
  430.                 }
  431.             }
  432.         }
  433.        
  434.         List<ApiBodyParameter> lst = new ArrayList<ApiBodyParameter>();

  435.         if(requestBody.getContent() != null && !requestBody.getContent().isEmpty()) {
  436.             for(String consume: requestBody.getContent().keySet()) {

  437.                 Schema<?> model = requestBody.getContent().get(consume).getSchema();

  438.                 String type = null;
  439.                 ApiReference apiRef = null;
  440.                 if(model.get$ref()!= null) {
  441.                     String href = model.get$ref().trim();
  442.                     if(href.contains("#") && !href.startsWith("#")) {
  443.                         type = href.substring(href.indexOf("#"), href.length());
  444.                         type = type.replaceAll("#/components/schemas/", "").replaceAll("#/definitions/", "");
  445.                         String ref = href.split("#")[0];
  446.                         File fRef = new File(ref);
  447.                         apiRef = new ApiReference(fRef.getName(), type);
  448.                     }
  449.                     else {
  450.                         type = href.replaceAll("#/components/schemas/", "").replaceAll("#/definitions/", "");
  451.                     }
  452.                 } else {
  453.                     type = ("request_" + method.toString() + "_" + path+ "_" + consume).replace("/", "_");
  454.                     api.getDefinitions().put(type, model);
  455.                 }
  456.                
  457.                 ApiBodyParameter bodyParam = new ApiBodyParameter(type);
  458.                 bodyParam.setMediaType(consume);
  459.                 if(apiRef!=null) {
  460.                     bodyParam.setElement(apiRef);
  461.                 }else {
  462.                     bodyParam.setElement(type);
  463.                 }
  464.                 if(requestBody.getRequired() != null)
  465.                     bodyParam.setRequired(requestBody.getRequired());

  466.                 bodyParam.setDescription(requestBody.getDescription());
  467.                
  468.                 lst.add(bodyParam);

  469.             }
  470.         }

  471.         return lst;
  472.     }

  473.     private void addRequestParameter(Parameter paramP, ApiRequest request, HttpRequestMethod method, String path, OpenapiApi api) {
  474.        
  475.         // resolve ref parameter
  476.         Parameter param = this.resolveParameterRef(paramP, api);
  477.         if(param==null) {
  478.             param = paramP;
  479.         }
  480.        
  481.         AbstractApiParameter abstractParam = null;
  482.         String name = param.getName();
  483.         if(name==null && param.get$ref()!=null) {
  484.             // provo a risolvere il nome di un eventuale parametro riferito
  485.             name = getRefParameterName(param.get$ref(), api);
  486.         }
  487.        
  488.         ApiParameterSchema apiParameterSchema = getParameterSchema(param.getSchema(), param.get$ref(), name,
  489.                 null,  
  490.                 param.getStyle()!=null ? param.getStyle().toString(): null,
  491.                 param.getExplode(),
  492.                 api);
  493.        
  494.         if(this.debug) {
  495.             System.out.println("=======================================");
  496.             System.out.println("REQUEST ("+method+" "+path+") name ["+name+"] required["+param.getRequired()+"] className["+param.getClass().getName()+"] ref["+param.get$ref()+"] apiParameterSchema["+apiParameterSchema.toString()+"]");
  497.             System.out.println("=======================================");
  498.         }
  499.        
  500.         if(param instanceof PathParameter) {
  501.             abstractParam = new ApiRequestDynamicPathParameter(name, apiParameterSchema);
  502.         } else if(param instanceof QueryParameter) {
  503.             abstractParam = new ApiRequestQueryParameter(name, apiParameterSchema);
  504.         } else if(param instanceof HeaderParameter) {
  505.             abstractParam = new ApiHeaderParameter(name, apiParameterSchema);
  506.         } else if(param instanceof CookieParameter) {
  507.             abstractParam = new ApiCookieParameter(name, apiParameterSchema);
  508.         }
  509.        
  510.         if(abstractParam == null) {
  511.             if(param.getIn() != null) {
  512.                 if(param.getIn().equals("query")) {
  513.                     abstractParam = new ApiRequestQueryParameter(name, apiParameterSchema);
  514.                 } else if(param.getIn().equals("header")) {
  515.                     abstractParam = new ApiHeaderParameter(name, apiParameterSchema);
  516.                 } else if(param.getIn().equals("cookie")) {
  517.                     abstractParam = new ApiCookieParameter(name, apiParameterSchema);
  518.                 } else if(param.getIn().equals("path")) {
  519.                     abstractParam = new ApiRequestDynamicPathParameter(name, apiParameterSchema);
  520.                 }
  521.             }
  522.         }

  523.         if(abstractParam != null) {
  524.             abstractParam.setDescription(param.getDescription());
  525.             if(param.getRequired() != null)
  526.                 abstractParam.setRequired(param.getRequired());

  527.             if(abstractParam instanceof ApiRequestDynamicPathParameter) {
  528.                 request.addDynamicPathParameter((ApiRequestDynamicPathParameter) abstractParam);
  529.             } else if(abstractParam instanceof ApiRequestQueryParameter) {
  530.                 request.addQueryParameter((ApiRequestQueryParameter) abstractParam);
  531.             } else if(abstractParam instanceof ApiHeaderParameter) {
  532.                 request.addHeaderParameter((ApiHeaderParameter) abstractParam);
  533.             } else if(abstractParam instanceof ApiCookieParameter) {
  534.                 request.addCookieParameter((ApiCookieParameter) abstractParam);
  535.             } else if(abstractParam instanceof ApiRequestFormParameter) {
  536.                 request.addFormParameter((ApiRequestFormParameter) abstractParam);
  537.             }
  538.         }

  539.     }

  540.     private Parameter resolveParameterRef(Parameter p,  OpenapiApi api) {
  541.         if(p.get$ref()==null || "".equals(p.get$ref())) {
  542.             return p;
  543.         }
  544.        
  545.         String ref = p.get$ref();
  546.         boolean external = false;
  547.         if(ref.contains("#")) {
  548.             external = !ref.trim().startsWith("#");
  549.             ref = ref.substring(ref.indexOf("#"));
  550.         }
  551.         boolean refParameters = ref.startsWith("#/components/parameters/");
  552.         if(!refParameters) {
  553.             return p;
  554.         }
  555.        
  556.         if(api.getApi().getComponents().getParameters()==null || api.getApi().getComponents().getParameters().size()<=0) {
  557.             if(!external || this.resolveExternalRef) {
  558.                 throw new RuntimeException("Parametro '"+p.getName()+"' non corretto: parametri definiti come componenti, sui cui risolvere la ref '"+ref+"', non presenti");
  559.             }
  560.             else {
  561.                 return null;
  562.             }
  563.         }
  564.         else {
  565.             String checkRef = ref.trim().replaceAll("#/components/parameters/", "");
  566.             Parameter param = null;
  567.             Iterator<String> itKeys = api.getApi().getComponents().getParameters().keySet().iterator();
  568.             while (itKeys.hasNext()) {
  569.                 String key = (String) itKeys.next();
  570.                 if(key.equals(checkRef)) {
  571.                     param = api.getApi().getComponents().getParameters().get(key);
  572.                     break;
  573.                 }
  574.             }
  575.             if(param==null) {
  576.                 if(!external || this.resolveExternalRef) {
  577.                     throw new RuntimeException("Parametro '"+p.getName()+"' non corretto: ref '"+ref+"' non presente tra i parametri definiti come componenti");
  578.                 }
  579.             }
  580.             return param;
  581.         }
  582.     }
  583.    
  584.     private String getRefParameterName(String refParam, OpenapiApi api) {
  585.         if(refParam != null) {
  586.             String ref = refParam;
  587.             boolean external = false;
  588.             if(ref.contains("#")) {
  589.                 external = !ref.trim().startsWith("#");
  590.                 ref = ref.substring(ref.indexOf("#"));
  591.             }
  592.            
  593.             boolean refParameters = ref.startsWith("#/components/parameters/");
  594.             if(refParameters) {
  595.                 if(api.getApi()==null) {
  596.                     throw new RuntimeException("Parametro non corretto: api da cui risolvere la ref '"+ref+"' non trovata");
  597.                 }
  598.                 if(api.getApi().getComponents()==null) {
  599.                     if(!external || this.resolveExternalRef) {
  600.                         throw new RuntimeException("Parametro non corretto: componenti, sui cui risolvere la ref '"+ref+"', non presenti");
  601.                     }
  602.                     else {
  603.                         return refParam;
  604.                     }
  605.                 }
  606.                 else {
  607.                     if(api.getApi().getComponents().getParameters()==null || api.getApi().getComponents().getParameters().size()<=0) {
  608.                         if(!external || this.resolveExternalRef) {
  609.                             throw new RuntimeException("Parametro non corretto: parametri definiti come componenti, sui cui risolvere la ref '"+ref+"', non presenti");
  610.                         }
  611.                         else {
  612.                             return refParam;
  613.                         }
  614.                     }
  615.                     else {
  616.                         String checkRef = ref.trim().replaceAll("#/components/parameters/", "");
  617.                         Parameter param = null;
  618.                         Iterator<String> itKeys = api.getApi().getComponents().getParameters().keySet().iterator();
  619.                         while (itKeys.hasNext()) {
  620.                             String key = (String) itKeys.next();
  621.                             if(key.equals(checkRef)) {
  622.                                 param = api.getApi().getComponents().getParameters().get(key);
  623.                                 break;
  624.                             }
  625.                         }
  626.                         if(param==null) {
  627.                             if(!external || this.resolveExternalRef) {
  628.                                 throw new RuntimeException("Parametro  non corretto: ref '"+ref+"' non presente tra i parametri definiti come componenti");
  629.                             }
  630.                             else {
  631.                                 return refParam;
  632.                             }
  633.                         }
  634.                         else {
  635.                             return param.getName();
  636.                         }
  637.                     }
  638.                 }
  639.             }                  
  640.         }

  641.         return null;
  642.     }
  643.    
  644.     /*
  645.     private String getParameterType(Schema<?> schema, String refParam, String name, OpenapiApi api) {
  646.         if(refParam != null) {
  647.             String ref = refParam;
  648.             boolean external = false;
  649.             if(ref.contains("#")) {
  650.                 external = !ref.trim().startsWith("#");
  651.                 ref = ref.substring(ref.indexOf("#"));
  652.             }
  653.            
  654.             boolean refHeaders = ref.startsWith("#/components/headers/");
  655.             boolean refParameters = ref.startsWith("#/components/parameters/");
  656.             boolean refSchema = ref.startsWith("#/components/schemas/");
  657.             if(refHeaders || refParameters || refSchema) {
  658.                 if(api.getApi()==null) {
  659.                     throw new RuntimeException("Parametro '"+name+"' non corretto: api da cui risolvere la ref '"+ref+"' non trovata");
  660.                 }
  661.                 else {
  662.                     if(api.getApi().getComponents()==null) {
  663.                         if(!external || this.resolveExternalRef) {
  664.                             throw new RuntimeException("Parametro '"+name+"' non corretto: componenti, sui cui risolvere la ref '"+ref+"', non presenti");
  665.                         }
  666.                         else {
  667.                             return refParam;
  668.                         }
  669.                     }
  670.                     else {
  671.                         if(refHeaders) {
  672.                             if(api.getApi().getComponents().getHeaders()==null || api.getApi().getComponents().getHeaders().size()<=0) {
  673.                                 if(!external || this.resolveExternalRef) {
  674.                                     throw new RuntimeException("Parametro '"+name+"' non corretto: headers definiti come componenti, sui cui risolvere la ref '"+ref+"', non presenti");
  675.                                 }
  676.                                 else {
  677.                                     return refParam;
  678.                                 }
  679.                             }
  680.                             String checkRef = ref.trim().replaceAll("#/components/headers/", "");
  681.                             Header hdr = null;
  682.                             Iterator<String> itKeys = api.getApi().getComponents().getHeaders().keySet().iterator();
  683.                             while (itKeys.hasNext()) {
  684.                                 String key = (String) itKeys.next();
  685.                                 if(key.equals(checkRef)) {
  686.                                     hdr = api.getApi().getComponents().getHeaders().get(key);
  687.                                     break;
  688.                                 }
  689.                             }
  690.                             if(hdr==null) {
  691.                                 if(!external || this.resolveExternalRef) {
  692.                                     throw new RuntimeException("Parametro '"+name+"' non corretto: ref '"+ref+"' non presente tra gli headers definiti come componenti");
  693.                                 }
  694.                                 else {
  695.                                     return refParam;
  696.                                 }
  697.                             }
  698.                             else {
  699.                                 return getParameterType(hdr.getSchema(), hdr.get$ref(), name, api);
  700.                             }
  701.                         }
  702.                         else if(refParameters) {
  703.                             if(api.getApi().getComponents().getParameters()==null || api.getApi().getComponents().getParameters().size()<=0) {
  704.                                 if(!external || this.resolveExternalRef) {
  705.                                     throw new RuntimeException("Parametro '"+name+"' non corretto: parametri definiti come componenti, sui cui risolvere la ref '"+ref+"', non presenti");
  706.                                 }
  707.                                 else {
  708.                                     return refParam;
  709.                                 }
  710.                             }
  711.                             String checkRef = ref.trim().replaceAll("#/components/parameters/", "");
  712.                             Parameter param = null;
  713.                             Iterator<String> itKeys = api.getApi().getComponents().getParameters().keySet().iterator();
  714.                             while (itKeys.hasNext()) {
  715.                                 String key = (String) itKeys.next();
  716.                                 if(key.equals(checkRef)) {
  717.                                     param = api.getApi().getComponents().getParameters().get(key);
  718.                                     break;
  719.                                 }
  720.                             }
  721.                             if(param==null) {
  722.                                 if(!external || this.resolveExternalRef) {
  723.                                     throw new RuntimeException("Parametro '"+name+"' non corretto: ref '"+ref+"' non presente tra i parametri definiti come componenti");
  724.                                 }
  725.                                 else {
  726.                                     return refParam;
  727.                                 }
  728.                             }
  729.                             else {
  730.                                 if(name==null && param.getName()!=null) {
  731.                                     name = param.getName();
  732.                                 }
  733.                                 return getParameterType(param.getSchema(), param.get$ref(), name, api);
  734.                             }
  735.                         }
  736.                         else {
  737.                             if(api.getApi().getComponents().getSchemas()==null || api.getApi().getComponents().getSchemas().size()<=0) {
  738.                                 if(!external || this.resolveExternalRef) {
  739.                                     throw new RuntimeException("Parametro '"+name+"' non corretto: schemi definiti come componenti, sui cui risolvere la ref '"+ref+"', non presenti");
  740.                                 }
  741.                                 else {
  742.                                     return refParam;
  743.                                 }
  744.                             }
  745.                             String checkRef = ref.trim().replaceAll("#/components/schemas/", "");
  746.                             Schema<?> schemaRiferito = null;
  747.                             Iterator<String> itKeys = api.getApi().getComponents().getSchemas().keySet().iterator();
  748.                             while (itKeys.hasNext()) {
  749.                                 String key = (String) itKeys.next();
  750.                                 if(key.equals(checkRef)) {
  751.                                     schemaRiferito = api.getApi().getComponents().getSchemas().get(key);
  752.                                     break;
  753.                                 }
  754.                             }
  755.                             if(schemaRiferito==null) {
  756.                                 if(!external || this.resolveExternalRef) {
  757.                                     throw new RuntimeException("Parametro '"+name+"' non corretto: ref '"+ref+"' non presente tra gli schemi definiti come componenti");
  758.                                 }
  759.                                 else {
  760.                                     return refParam;
  761.                                 }
  762.                             }
  763.                             else {
  764.                                 return getParameterType(schemaRiferito, null, name, api);
  765.                             }
  766.                         }
  767.                     }
  768.                 }
  769.             }
  770.             else {
  771.                 // i requestBodies e le response non dovrebbero rientrare in questo metodo
  772.                 return ref.replaceAll("#/components/schemas/", "").replaceAll("#/definitions/", "");
  773.             }
  774.                        
  775.         }

  776.         if(schema==null) {
  777.             throw new RuntimeException("Parametro '"+name+"' non corretto: schema non definito");
  778.         }
  779.        
  780.         if(schema.get$ref() != null) {
  781.             return getParameterType(schema, schema.get$ref(), name, api);
  782.         }
  783.        
  784.         if(schema instanceof ArraySchema) {
  785.             return getParameterType(((ArraySchema)schema).getItems(), null, name, api);
  786.         }
  787.        
  788.         if(schema instanceof ComposedSchema) {
  789.             ComposedSchema cs = (ComposedSchema) schema;
  790.             if(cs.getAnyOf()!=null && !cs.getAnyOf().isEmpty() && cs.getAnyOf().get(0)!=null) {
  791.                 // utilizzo il primo schema
  792.                 //NO NON VA BENE. DEVO STRUTTURARE L'INFORMAZIONE INSIEME ALLA RESTRIZIONE come una lista ???
  793.                 if(cs.getAnyOf().get(0).getFormat() != null) {
  794.                     return cs.getAnyOf().get(0).getFormat();
  795.                 } else {
  796.                     return cs.getAnyOf().get(0).getType();
  797.                 }
  798.                 // PRIMA TERMINARE COSI PER VEDERE SE FUNZIONA USANDO UN TIPO A CASO
  799.             }
  800.             else if(cs.getAllOf()!=null && !cs.getAllOf().isEmpty() && cs.getAllOf().get(0)!=null) {
  801.                 // utilizzo il primo schema
  802.                 //NO NON VA BENE. DEVO STRUTTURARE L'INFORMAZIONE INSIEME ALLA RESTRIZIONE come una lista ???
  803.                 if(cs.getAllOf().get(0).getFormat() != null) {
  804.                     return cs.getAllOf().get(0).getFormat();
  805.                 } else {
  806.                     return cs.getAllOf().get(0).getType();
  807.                 }
  808.                 // ALL OFF HA SENSO ??????????????? PROVARE COME SI COMPORTA OPENAPI
  809.             }
  810.         }
  811.        
  812.         if(schema.getFormat() != null) {
  813.             return schema.getFormat();
  814.         } else {
  815.             return schema.getType();
  816.         }
  817.     }
  818.    
  819.     private ApiSchemaTypeRestriction getParameterSchemaTypeRestriction(Schema<?> schema, String ref, String name,
  820.             Boolean arrayParameter, String style, Boolean explode, OpenapiApi api) {
  821.         if(ref != null) {
  822.             boolean external = false;
  823.             if(ref.contains("#")) {
  824.                 external = !ref.trim().startsWith("#");
  825.                 ref = ref.substring(ref.indexOf("#"));
  826.             }
  827.            
  828.             boolean refHeaders = ref.startsWith("#/components/headers/");
  829.             boolean refParameters = ref.startsWith("#/components/parameters/");
  830.             boolean refSchema = ref.startsWith("#/components/schemas/");
  831.             if(refHeaders || refParameters || refSchema) {
  832.                 if(api.getApi()==null) {
  833.                     throw new RuntimeException("Parametro '"+name+"' non corretto: api da cui risolvere la ref '"+ref+"' non trovata");
  834.                 }
  835.                 else {
  836.                     if(api.getApi().getComponents()==null) {
  837.                         if(!external || this.resolveExternalRef) {
  838.                             throw new RuntimeException("Parametro '"+name+"' non corretto: componenti, sui cui risolvere la ref '"+ref+"', non presenti");
  839.                         }
  840.                         else {
  841.                             return null;
  842.                         }
  843.                     }
  844.                     else {
  845.                         if(refHeaders) {
  846.                             if(api.getApi().getComponents().getHeaders()==null || api.getApi().getComponents().getHeaders().size()<=0) {
  847.                                 if(!external || this.resolveExternalRef) {
  848.                                     throw new RuntimeException("Parametro '"+name+"' non corretto: headers definiti come componenti, sui cui risolvere la ref '"+ref+"', non presenti");
  849.                                 }
  850.                                 else {
  851.                                     return null;
  852.                                 }
  853.                             }
  854.                             String checkRef = ref.trim().replaceAll("#/components/headers/", "");
  855.                             Header hdr = null;
  856.                             Iterator<String> itKeys = api.getApi().getComponents().getHeaders().keySet().iterator();
  857.                             while (itKeys.hasNext()) {
  858.                                 String key = (String) itKeys.next();
  859.                                 if(key.equals(checkRef)) {
  860.                                     hdr = api.getApi().getComponents().getHeaders().get(key);
  861.                                     break;
  862.                                 }
  863.                             }
  864.                             if(hdr==null) {
  865.                                 if(!external || this.resolveExternalRef) {
  866.                                     throw new RuntimeException("Parametro '"+name+"' non corretto: ref '"+ref+"' non presente tra gli headers definiti come componenti");
  867.                                 }
  868.                                 else {
  869.                                     return null;
  870.                                 }
  871.                             }
  872.                             else {
  873.                                 return getParameterSchemaTypeRestriction(hdr.getSchema(), hdr.get$ref(), name,
  874.                                                     arrayParameter,
  875.                                                     hdr.getStyle()!=null ? hdr.getStyle().toString(): null,
  876.                                                     hdr.getExplode(),
  877.                                                     api);
  878.                             }
  879.                         }
  880.                         else if(refParameters) {
  881.                             if(api.getApi().getComponents().getParameters()==null || api.getApi().getComponents().getParameters().size()<=0) {
  882.                                 if(!external || this.resolveExternalRef) {
  883.                                     throw new RuntimeException("Parametro '"+name+"' non corretto: parametri definiti come componenti, sui cui risolvere la ref '"+ref+"', non presenti");
  884.                                 }
  885.                                 else {
  886.                                     return null;
  887.                                 }
  888.                             }
  889.                             String checkRef = ref.trim().replaceAll("#/components/parameters/", "");
  890.                             Parameter param = null;
  891.                             Iterator<String> itKeys = api.getApi().getComponents().getParameters().keySet().iterator();
  892.                             while (itKeys.hasNext()) {
  893.                                 String key = (String) itKeys.next();
  894.                                 if(key.equals(checkRef)) {
  895.                                     param = api.getApi().getComponents().getParameters().get(key);
  896.                                     break;
  897.                                 }
  898.                             }
  899.                             if(param==null) {
  900.                                 if(!external || this.resolveExternalRef) {
  901.                                     throw new RuntimeException("Parametro '"+name+"' non corretto: ref '"+ref+"' non presente tra i parametri definiti come componenti");
  902.                                 }
  903.                                 else {
  904.                                     return null;
  905.                                 }
  906.                             }
  907.                             else {
  908.                                 if(name==null && param.getName()!=null) {
  909.                                     name = param.getName();
  910.                                 }
  911.                                 return getParameterSchemaTypeRestriction(param.getSchema(), param.get$ref(), name,
  912.                                                 arrayParameter,
  913.                                                 param.getStyle()!=null ? param.getStyle().toString(): null,
  914.                                                 param.getExplode(),
  915.                                                 api);
  916.                             }
  917.                         }
  918.                         else {
  919.                             if(api.getApi().getComponents().getSchemas()==null || api.getApi().getComponents().getSchemas().size()<=0) {
  920.                                 if(!external || this.resolveExternalRef) {
  921.                                     throw new RuntimeException("Parametro '"+name+"' non corretto: schemi definiti come componenti, sui cui risolvere la ref '"+ref+"', non presenti");
  922.                                 }
  923.                                 else {
  924.                                     return null;
  925.                                 }
  926.                             }
  927.                             String checkRef = ref.trim().replaceAll("#/components/schemas/", "");
  928.                             Schema<?> schemaRiferito = null;
  929.                             Iterator<String> itKeys = api.getApi().getComponents().getSchemas().keySet().iterator();
  930.                             while (itKeys.hasNext()) {
  931.                                 String key = (String) itKeys.next();
  932.                                 if(key.equals(checkRef)) {
  933.                                     schemaRiferito = api.getApi().getComponents().getSchemas().get(key);
  934.                                     break;
  935.                                 }
  936.                             }
  937.                             if(schemaRiferito==null) {
  938.                                 if(!external || this.resolveExternalRef) {
  939.                                     throw new RuntimeException("Parametro '"+name+"' non corretto: ref '"+ref+"' non presente tra gli schemi definiti come componenti");
  940.                                 }
  941.                                 else {
  942.                                     return null;
  943.                                 }
  944.                             }
  945.                             else {
  946.                                 return getParameterSchemaTypeRestriction(schemaRiferito, null, name,
  947.                                         arrayParameter,
  948.                                         style,
  949.                                         explode,
  950.                                         api);
  951.                             }
  952.                         }
  953.                     }
  954.                 }
  955.             }
  956.             else {
  957.                 return null; // schema non trovato.
  958.             }
  959.                        
  960.         }

  961.         if(schema.get$ref() != null) {
  962.             return getParameterSchemaTypeRestriction(schema, schema.get$ref(), name,
  963.                     arrayParameter,
  964.                     style,
  965.                     explode,
  966.                     api);
  967.         }
  968.        
  969.         if(schema instanceof ArraySchema) {
  970.             return getParameterSchemaTypeRestriction(((ArraySchema)schema).getItems(), null, name,
  971.                     true,
  972.                     style,
  973.                     explode,
  974.                     api);
  975.         }
  976.        
  977.         return this.convertTo(schema, arrayParameter, style, explode);
  978.     }
  979.     */
  980.    
  981.     private ApiParameterSchema getParameterSchema(Schema<?> schema, String ref, String name,
  982.             Boolean arrayParameter, String style, Boolean explode, OpenapiApi api) {
  983.         if(ref != null) {
  984.             boolean external = false;
  985.             if(ref.contains("#")) {
  986.                 external = !ref.trim().startsWith("#");
  987.                 ref = ref.substring(ref.indexOf("#"));
  988.             }
  989.            
  990.             boolean refHeaders = ref.startsWith("#/components/headers/");
  991.             boolean refParameters = ref.startsWith("#/components/parameters/");
  992.             boolean refSchema = ref.startsWith("#/components/schemas/");
  993.             if(refHeaders || refParameters || refSchema) {
  994.                 if(api.getApi()==null) {
  995.                     throw new RuntimeException("Parametro '"+name+"' non corretto: api da cui risolvere la ref '"+ref+"' non trovata");
  996.                 }
  997.                 else {
  998.                     if(api.getApi().getComponents()==null) {
  999.                         if(!external || this.resolveExternalRef) {
  1000.                             throw new RuntimeException("Parametro '"+name+"' non corretto: componenti, sui cui risolvere la ref '"+ref+"', non presenti");
  1001.                         }
  1002.                         else {
  1003.                             ApiParameterSchema aps = new ApiParameterSchema();
  1004.                             aps.addType(ref, null);
  1005.                             return aps;
  1006.                         }
  1007.                     }
  1008.                     else {
  1009.                         if(refHeaders) {
  1010.                             if(api.getApi().getComponents().getHeaders()==null || api.getApi().getComponents().getHeaders().size()<=0) {
  1011.                                 if(!external || this.resolveExternalRef) {
  1012.                                     throw new RuntimeException("Parametro '"+name+"' non corretto: headers definiti come componenti, sui cui risolvere la ref '"+ref+"', non presenti");
  1013.                                 }
  1014.                                 else {
  1015.                                     ApiParameterSchema aps = new ApiParameterSchema();
  1016.                                     aps.addType(ref, null);
  1017.                                     return aps;
  1018.                                 }
  1019.                             }
  1020.                             String checkRef = ref.trim().replaceAll("#/components/headers/", "");
  1021.                             Header hdr = null;
  1022.                             Iterator<String> itKeys = api.getApi().getComponents().getHeaders().keySet().iterator();
  1023.                             while (itKeys.hasNext()) {
  1024.                                 String key = (String) itKeys.next();
  1025.                                 if(key.equals(checkRef)) {
  1026.                                     hdr = api.getApi().getComponents().getHeaders().get(key);
  1027.                                     break;
  1028.                                 }
  1029.                             }
  1030.                             if(hdr==null) {
  1031.                                 if(!external || this.resolveExternalRef) {
  1032.                                     throw new RuntimeException("Parametro '"+name+"' non corretto: ref '"+ref+"' non presente tra gli headers definiti come componenti");
  1033.                                 }
  1034.                                 else {
  1035.                                     ApiParameterSchema aps = new ApiParameterSchema();
  1036.                                     aps.addType(ref, null);
  1037.                                     return aps;
  1038.                                 }
  1039.                             }
  1040.                             else {
  1041.                                 return getParameterSchema(hdr.getSchema(), hdr.get$ref(), name,
  1042.                                                     arrayParameter,
  1043.                                                     hdr.getStyle()!=null ? hdr.getStyle().toString(): null,
  1044.                                                     hdr.getExplode(),
  1045.                                                     api);
  1046.                             }
  1047.                         }
  1048.                         else if(refParameters) {
  1049.                             if(api.getApi().getComponents().getParameters()==null || api.getApi().getComponents().getParameters().size()<=0) {
  1050.                                 if(!external || this.resolveExternalRef) {
  1051.                                     throw new RuntimeException("Parametro '"+name+"' non corretto: parametri definiti come componenti, sui cui risolvere la ref '"+ref+"', non presenti");
  1052.                                 }
  1053.                                 else {
  1054.                                     ApiParameterSchema aps = new ApiParameterSchema();
  1055.                                     aps.addType(ref, null);
  1056.                                     return aps;
  1057.                                 }
  1058.                             }
  1059.                             String checkRef = ref.trim().replaceAll("#/components/parameters/", "");
  1060.                             Parameter param = null;
  1061.                             Iterator<String> itKeys = api.getApi().getComponents().getParameters().keySet().iterator();
  1062.                             while (itKeys.hasNext()) {
  1063.                                 String key = (String) itKeys.next();
  1064.                                 if(key.equals(checkRef)) {
  1065.                                     param = api.getApi().getComponents().getParameters().get(key);
  1066.                                     break;
  1067.                                 }
  1068.                             }
  1069.                             if(param==null) {
  1070.                                 if(!external || this.resolveExternalRef) {
  1071.                                     throw new RuntimeException("Parametro '"+name+"' non corretto: ref '"+ref+"' non presente tra i parametri definiti come componenti");
  1072.                                 }
  1073.                                 else {
  1074.                                     ApiParameterSchema aps = new ApiParameterSchema();
  1075.                                     aps.addType(ref, null);
  1076.                                     return aps;
  1077.                                 }
  1078.                             }
  1079.                             else {
  1080.                                 if(name==null && param.getName()!=null) {
  1081.                                     name = param.getName();
  1082.                                 }
  1083.                                 return getParameterSchema(param.getSchema(), param.get$ref(), name,
  1084.                                                 arrayParameter,
  1085.                                                 param.getStyle()!=null ? param.getStyle().toString(): null,
  1086.                                                 param.getExplode(),
  1087.                                                 api);
  1088.                             }
  1089.                         }
  1090.                         else {
  1091.                             if(api.getApi().getComponents().getSchemas()==null || api.getApi().getComponents().getSchemas().size()<=0) {
  1092.                                 if(!external || this.resolveExternalRef) {
  1093.                                     throw new RuntimeException("Parametro '"+name+"' non corretto: schemi definiti come componenti, sui cui risolvere la ref '"+ref+"', non presenti");
  1094.                                 }
  1095.                                 else {
  1096.                                     ApiParameterSchema aps = new ApiParameterSchema();
  1097.                                     aps.addType(ref, null);
  1098.                                     return aps;
  1099.                                 }
  1100.                             }
  1101.                             String checkRef = ref.trim().replaceAll("#/components/schemas/", "");
  1102.                             Schema<?> schemaRiferito = null;
  1103.                             Iterator<String> itKeys = api.getApi().getComponents().getSchemas().keySet().iterator();
  1104.                             while (itKeys.hasNext()) {
  1105.                                 String key = (String) itKeys.next();
  1106.                                 if(key.equals(checkRef)) {
  1107.                                     schemaRiferito = api.getApi().getComponents().getSchemas().get(key);
  1108.                                     break;
  1109.                                 }
  1110.                             }
  1111.                             if(schemaRiferito==null) {
  1112.                                 if(!external || this.resolveExternalRef) {
  1113.                                     throw new RuntimeException("Parametro '"+name+"' non corretto: ref '"+ref+"' non presente tra gli schemi definiti come componenti");
  1114.                                 }
  1115.                                 else {
  1116.                                     ApiParameterSchema aps = new ApiParameterSchema();
  1117.                                     aps.addType(ref, null);
  1118.                                     return aps;
  1119.                                 }
  1120.                             }
  1121.                             else {
  1122.                                 return getParameterSchema(schemaRiferito, null, name,
  1123.                                         arrayParameter,
  1124.                                         style,
  1125.                                         explode,
  1126.                                         api);
  1127.                             }
  1128.                         }
  1129.                     }
  1130.                 }
  1131.             }
  1132.             else {
  1133.                 // i requestBodies e le response non dovrebbero rientrare in questo metodo
  1134.                 String _type = ref.replaceAll("#/components/schemas/", "").replaceAll("#/definitions/", "");
  1135.                 ApiSchemaTypeRestriction _schema = null; // schema non trovato.
  1136.                 ApiParameterSchema aps = new ApiParameterSchema();
  1137.                 aps.addType(_type, _schema);
  1138.                 return aps;
  1139.             }
  1140.                        
  1141.         }

  1142.         if(schema==null) {
  1143.             throw new RuntimeException("Parametro '"+name+"' non corretto: schema non definito");
  1144.         }
  1145.        
  1146.         if(schema.get$ref() != null) {
  1147.             return getParameterSchema(schema, schema.get$ref(), name,
  1148.                     arrayParameter,
  1149.                     style,
  1150.                     explode,
  1151.                     api);
  1152.         }
  1153.        
  1154.         if(schema instanceof ArraySchema) {
  1155.             return getParameterSchema(((ArraySchema)schema).getItems(), null, name,
  1156.                     true,
  1157.                     style,
  1158.                     explode,
  1159.                     api);
  1160.         }
  1161.        
  1162.         if(schema instanceof ComposedSchema) {
  1163.             ComposedSchema cs = (ComposedSchema) schema;
  1164.             if(cs.getAnyOf()!=null && !cs.getAnyOf().isEmpty()) {
  1165.                 ApiParameterSchema aps = new ApiParameterSchema();
  1166.                 aps.setComplexType(ApiParameterSchemaComplexType.anyOf);
  1167.                 for (Schema<?> apiSchemaAnyOf : cs.getAnyOf()) {
  1168.                     String _type = null;
  1169.                     if(apiSchemaAnyOf.getFormat() != null) {
  1170.                         _type = apiSchemaAnyOf.getFormat();
  1171.                     } else {
  1172.                         _type = apiSchemaAnyOf.getType();
  1173.                     }
  1174.                     ApiSchemaTypeRestriction _schema = this.convertTo(apiSchemaAnyOf, arrayParameter, style, explode);
  1175.                     aps.addType(_type, _schema);
  1176.                 }
  1177.                 return aps;
  1178.             }
  1179.             else if(cs.getAllOf()!=null && !cs.getAllOf().isEmpty()) {
  1180.                 ApiParameterSchema aps = new ApiParameterSchema();
  1181.                 aps.setComplexType(ApiParameterSchemaComplexType.allOf);
  1182.                 for (Schema<?> apiSchemaAllOf : cs.getAllOf()) {
  1183.                     String _type = null;
  1184.                     if(apiSchemaAllOf.getFormat() != null) {
  1185.                         _type = apiSchemaAllOf.getFormat();
  1186.                     } else {
  1187.                         _type = apiSchemaAllOf.getType();
  1188.                     }
  1189.                     ApiSchemaTypeRestriction _schema = this.convertTo(apiSchemaAllOf, arrayParameter, style, explode);
  1190.                     aps.addType(_type, _schema);
  1191.                 }
  1192.                 return aps;
  1193.             }
  1194.             else if(cs.getOneOf()!=null && !cs.getOneOf().isEmpty()) {
  1195.                 ApiParameterSchema aps = new ApiParameterSchema();
  1196.                 aps.setComplexType(ApiParameterSchemaComplexType.oneOf);
  1197.                 for (Schema<?> apiSchemaOneOf : cs.getOneOf()) {
  1198.                     String _type = null;
  1199.                     if(apiSchemaOneOf.getFormat() != null) {
  1200.                         _type = apiSchemaOneOf.getFormat();
  1201.                     } else {
  1202.                         _type = apiSchemaOneOf.getType();
  1203.                     }
  1204.                     ApiSchemaTypeRestriction _schema = this.convertTo(apiSchemaOneOf, arrayParameter, style, explode);
  1205.                     aps.addType(_type, _schema);
  1206.                 }
  1207.                 return aps;
  1208.             }
  1209.         }
  1210.        
  1211.         String _type = null;
  1212.         if(schema.getFormat() != null) {
  1213.             _type = schema.getFormat();
  1214.         } else {
  1215.             _type = schema.getType();
  1216.         }
  1217.         if(_type==null && schema.getTypes()!=null && !schema.getTypes().isEmpty()) {
  1218.             _type=schema.getTypes().iterator().next();
  1219.         }
  1220.         ApiSchemaTypeRestriction _schema = this.convertTo(schema, arrayParameter, style, explode);
  1221.         ApiParameterSchema aps = new ApiParameterSchema();
  1222.         aps.addType(_type, _schema);
  1223.         return aps;
  1224.     }

  1225.     private ApiSchemaTypeRestriction convertTo(Schema<?> schema, Boolean arrayParameter, String style, Boolean explode) {
  1226.         ApiSchemaTypeRestriction schemaTypeRestriction = new ApiSchemaTypeRestriction();
  1227.         schemaTypeRestriction.setSchema(schema);
  1228.         schemaTypeRestriction.setType(schema.getType());
  1229.         schemaTypeRestriction.setFormat(schema.getFormat());
  1230.        
  1231.         schemaTypeRestriction.setMinimum(schema.getMinimum());
  1232.         schemaTypeRestriction.setExclusiveMinimum(schema.getExclusiveMinimum());
  1233.         schemaTypeRestriction.setMaximum(schema.getMaximum());
  1234.         schemaTypeRestriction.setExclusiveMaximum(schema.getExclusiveMaximum());
  1235.        
  1236.         schemaTypeRestriction.setMultipleOf(schema.getMultipleOf());

  1237.         schemaTypeRestriction.setMinLength(schema.getMinLength()!=null ? Long.valueOf(schema.getMinLength()) : null);
  1238.         schemaTypeRestriction.setMaxLength(schema.getMaxLength()!=null ? Long.valueOf(schema.getMaxLength()) : null);
  1239.    
  1240.         schemaTypeRestriction.setPattern(schema.getPattern());

  1241.         schemaTypeRestriction.setEnumValues(schema.getEnum());
  1242.        
  1243.         schemaTypeRestriction.setArrayParameter(arrayParameter);
  1244.         schemaTypeRestriction.setStyle(style);
  1245.         if(explode!=null) {
  1246.             schemaTypeRestriction.setExplode(explode.booleanValue()+"");
  1247.         }
  1248.        
  1249.         return schemaTypeRestriction;
  1250.     }

  1251.     private ApiResponse createResponses(String responseK, io.swagger.v3.oas.models.responses.ApiResponse response, HttpRequestMethod method, String path, OpenapiApi api) {

  1252.         ApiResponse apiResponse= new ApiResponse();

  1253.         int status = -1;
  1254.         try{
  1255.             if("default".equals(responseK)) {
  1256.                 apiResponse.setDefaultHttpReturnCode();
  1257.             }
  1258.             else {
  1259.                 status = Integer.parseInt(responseK);
  1260.                 apiResponse.setHttpReturnCode(status);
  1261.             }
  1262.         } catch(NumberFormatException e) {
  1263.             throw new RuntimeException("Stato non supportato ["+responseK+"]", e);
  1264.         }
  1265. //      if(status<=0) {
  1266. //          status = 200;
  1267. //      }
  1268.        
  1269.         if(response.get$ref()!=null) {
  1270.            
  1271.             String ref = response.get$ref();
  1272.             boolean external = false;
  1273.             if(ref.contains("#")) {
  1274.                 external = !ref.trim().startsWith("#");
  1275.                 ref = ref.substring(ref.indexOf("#"));
  1276.             }
  1277.             ref = ref.trim().replaceAll("#/components/responses/", "").replaceAll("#/definitions/", "");
  1278.            
  1279.             if(api.getApi()==null) {
  1280.                 throw new RuntimeException("Stato non corretto ["+responseK+"]: api da cui risolvere la ref '"+response.get$ref()+"' non trovata");
  1281.             }
  1282.             if(api.getApi().getComponents()==null) {
  1283.                 if(!external || this.resolveExternalRef) {
  1284.                     throw new RuntimeException("Stato non corretto ["+responseK+"]: componenti, sui cui risolvere la ref '"+response.get$ref()+"', non presenti");
  1285.                 }
  1286.             }
  1287.             else {
  1288.                 if(api.getApi().getComponents().getResponses()==null || api.getApi().getComponents().getResponses().size()<=0) {
  1289.                     if(!external || this.resolveExternalRef) {
  1290.                         throw new RuntimeException("Stato non corretto ["+responseK+"]: risposte definite come componenti, sui cui risolvere la ref '"+response.get$ref()+"', non presenti");
  1291.                     }
  1292.                 }
  1293.                 else {
  1294.                     boolean find = false;
  1295.                     Iterator<String> itKeys = api.getApi().getComponents().getResponses().keySet().iterator();
  1296.                     while (itKeys.hasNext()) {
  1297.                         String key = (String) itKeys.next();
  1298.                         if(key.equals(ref)) {
  1299.                             response = api.getApi().getComponents().getResponses().get(key);
  1300.                             find = true;
  1301.                             break;
  1302.                         }
  1303.                     }
  1304.                     if(!find) {
  1305.                         if(!external || this.resolveExternalRef) {
  1306.                             throw new RuntimeException("Stato non corretto ["+responseK+"]: ref '"+response.get$ref()+"' non presente tra le risposte definite come componenti");
  1307.                         }
  1308.                     }
  1309.                 }
  1310.             }
  1311.         }
  1312.        
  1313.         apiResponse.setDescription(response.getDescription());

  1314.         if(response.getHeaders() != null) {
  1315.             for(String header: response.getHeaders().keySet()) {
  1316.                 Header property = response.getHeaders().get(header);
  1317.                
  1318.                 ApiParameterSchema apiParameterSchema = getParameterSchema(property.getSchema(), property.get$ref(), header,
  1319.                                 null,
  1320.                                 property.getStyle()!=null ? property.getStyle().toString(): null,
  1321.                                 property.getExplode(),
  1322.                                 api);
  1323.                
  1324.                 if(this.debug) {
  1325.                     System.out.println("=======================================");
  1326.                     System.out.println("RESPONSE ("+method+" "+path+") name ["+header+"] required["+property.getRequired()+"] className["+property.getClass().getName()+"] ref["+property.get$ref()+"] apiParameterSchema["+apiParameterSchema+"]");
  1327.                     System.out.println("=======================================");
  1328.                 }
  1329.                
  1330.                 ApiHeaderParameter parameter = new ApiHeaderParameter(header, apiParameterSchema);
  1331.                 parameter.setDescription(property.getDescription());
  1332.                 if(property.getRequired() != null)
  1333.                     parameter.setRequired(property.getRequired());
  1334.                
  1335.                 apiResponse.addHeaderParameter(parameter);
  1336.             }
  1337.         }
  1338.        
  1339.         if(response.getContent() != null && !response.getContent().isEmpty()) {
  1340.             for(String contentType: response.getContent().keySet()) {

  1341.                 MediaType mediaType = response.getContent().get(contentType);
  1342.                 Schema<?> schema = mediaType.getSchema();
  1343.                
  1344.                 String name = ("response_" +method.toString() + "_" + path + "_" + responseK + "_" + contentType).replace("/", "_");

  1345.                 String type = null;
  1346.                 ApiReference apiRef = null;
  1347.                 if(schema!=null && schema.get$ref()!= null) {
  1348.                     String href = schema.get$ref().trim();
  1349.                     if(href.contains("#") && !href.startsWith("#")) {
  1350.                         type = href.substring(href.indexOf("#"), href.length());
  1351.                         type = type.replaceAll("#/components/schemas/", "").replaceAll("#/definitions/", "");
  1352.                         String ref = href.split("#")[0];
  1353.                         File fRef = new File(ref);
  1354.                         apiRef = new ApiReference(fRef.getName(), type);
  1355.                     }
  1356.                     else {
  1357.                         type = href.replaceAll("#/components/schemas/", "").replaceAll("#/definitions/", "");
  1358.                     }
  1359.                 } else {
  1360.                     type = ("response_" +method.toString() + "_" + path + "_" + responseK + "_" + contentType).replace("/", "_");
  1361.                     api.getDefinitions().put(type, schema);
  1362.                 }
  1363.                
  1364.                 ApiBodyParameter bodyParam = new ApiBodyParameter(name);
  1365.                 bodyParam.setMediaType(contentType);
  1366.                 if(apiRef!=null) {
  1367.                     bodyParam.setElement(apiRef);
  1368.                 }else {
  1369.                     bodyParam.setElement(type);
  1370.                 }
  1371.                
  1372. //              String typeF = getParameterType(schema, null);
  1373. //              bodyParam.setElement(type);
  1374.                
  1375.                 bodyParam.setRequired(true);
  1376.                
  1377.                 apiResponse.addBodyParameter(bodyParam);
  1378.             }
  1379.         }

  1380.         return apiResponse;
  1381.     }
  1382.    
  1383. }