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

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


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

  84.     private static boolean resolveEmptySchema = true;
  85.     public static boolean isResolveEmptySchema() {
  86.         return resolveEmptySchema;
  87.     }
  88.     public static void setResolveEmptySchema(boolean resolveEmptySchema) {
  89.         AbstractOpenapiApiReader.resolveEmptySchema = resolveEmptySchema;
  90.     }

  91.     private static final String SEPARATOR = "=======================================";
  92.     private static final String DEFINITIONS = "#/definitions/";
  93.     private static final String COMPONENTS_SCHEMAS = "#/components/schemas/";
  94.     private static final String COMPONENTS_PARAMETERS = "#/components/parameters/";
  95.     private static final String COMPONENTS_HEADERS = "#/components/headers/";
  96.     private static final String COMPONENTS_REQUEST_BODY = "#/components/requestBodies/";
  97.     private static final String COMPONENTS_RESPONSES = "#/components/responses/";
  98.    
  99.     private static final String SUFFIX_NON_TROVATA = "' non trovata";
  100.     private static final String SUFFIX_NON_PRESENTI = "', non presenti";
  101.     private static final String SUFFIX_NON_PRESENTE_COMPONENTI = "' non presente tra i parametri definiti come componenti";
  102.    
  103.     private static final String SEPARATOR_NON_CORRETTO_REF = "' non corretto: ref '";
  104.    
  105.     private static final String PREFIX_PARAMETRO = "Parametro '";
  106.    
  107.     private OpenAPI openApi;
  108.     private String openApiRaw;
  109.     private ApiFormats format;
  110.     private ParseOptions parseOptions;
  111.     private List<ApiSchema> schemas;
  112.     private boolean resolveExternalRef = true;
  113.     private String parseWarningResult;
  114.    
  115.     private boolean debug;
  116.     public void setDebug(boolean debug) {
  117.         this.debug = debug;
  118.     }

  119.     protected AbstractOpenapiApiReader(ApiFormats format) {
  120.         this.format = format;
  121.         this.parseOptions = new ParseOptions();
  122.         this.schemas = new ArrayList<>();
  123.     }

  124.     protected static OpenAPI parseResult(Logger log, SwaggerParseResult pr, StringBuilder sbParseWarningResult) throws ProcessingException {
  125.         if(pr==null) {
  126.             throw new ProcessingException("Parse result undefined");
  127.         }
  128.         StringBuilder bfMessage = new StringBuilder();
  129.         if(pr.getMessages()!=null && !pr.getMessages().isEmpty()) {
  130.             for (String msg : pr.getMessages()) {
  131.                 if(bfMessage.length()>0) {
  132.                     bfMessage.append("\n");
  133.                 }
  134.                 bfMessage.append("- ").append(msg);
  135.             }
  136.         }
  137.         OpenAPI openApi = null;
  138.         if(pr.getOpenAPI()!=null) {
  139.             openApi = pr.getOpenAPI();
  140.             if(bfMessage.length()>0) {
  141.                 String msg = bfMessage.toString();
  142.                 log.debug(msg);
  143.                 sbParseWarningResult.append(msg);
  144.             }
  145.         }
  146.         else {
  147.             if(bfMessage.length()>0) {
  148.                 throw new ProcessingException("Parse failed: "+bfMessage.toString());
  149.             }
  150.             else {
  151.                 throw new ProcessingException("Parse failed");
  152.             }
  153.         }
  154.         return openApi;
  155.     }
  156.    
  157.    
  158.     @Override
  159.     public void init(Logger log, String content, ApiReaderConfig config) throws ProcessingException {
  160.         this.initEngine(log, content, config);
  161.     }
  162.     @Override
  163.     public void init(Logger log, String content, ApiReaderConfig config, ApiSchema ... schema) throws ProcessingException {
  164.         this.initEngine(log, content, config, schema);
  165.     }
  166.     private void initEngine(Logger log, String contentParam, ApiReaderConfig config, ApiSchema ... schema) throws ProcessingException {
  167.        
  168.         String content = contentParam;
  169.                
  170.         boolean apiRawIsYaml = false;
  171.         YAMLUtils yamlUtils = null;
  172.         try {
  173.             yamlUtils = YAMLUtils.getInstance();
  174.             apiRawIsYaml = yamlUtils.isYaml(content);
  175.         }catch(Exception t) {
  176.             log.error("Init yaml utils failed: "+t.getMessage(),t);
  177.         }
  178.        
  179.         try {
  180.             if(apiRawIsYaml &&
  181.                 // Fix merge key '<<: *'
  182.                 YAMLUtils.containsKeyAnchor(content)) {
  183.                 // Risoluzione merge key '<<: *'
  184.                 String jsonRepresentation = YAMLUtils.resolveKeyAnchorAndConvertToJson(content);
  185.                 if(jsonRepresentation!=null) {
  186.                     content = jsonRepresentation;
  187.                 }
  188.             }
  189.         }catch(Throwable t) {
  190.             log.error("Find and resolve merge key failed: "+t.getMessage(),t);
  191.         }
  192.        
  193.         if(resolveEmptySchema) {
  194.             try {
  195.                 if(apiRawIsYaml) {
  196.                     if(YAMLUtils.containsEmptySchema(content)) {
  197.                         content = YAMLUtils.resolveEmptySchema(content);
  198.                     }
  199.                 }
  200.                 else {
  201.                     if(JSONUtils.containsEmptySchema(content)) {
  202.                         content = JSONUtils.resolveEmptySchema(content);
  203.                     }
  204.                 }
  205.             }catch(Exception t) {
  206.                 log.error("Find and resolve empty schema failed: "+t.getMessage(),t);
  207.             }
  208.         }
  209.        
  210.         try {
  211.             SwaggerParseResult pr = null;
  212.             if(ApiFormats.SWAGGER_2.equals(this.format)) {
  213.                 pr = new SwaggerConverter().readContents(content, null, this.parseOptions);
  214.             }
  215.             else {
  216.                 pr = new OpenAPIV3Parser().readContents(content, null, this.parseOptions);
  217.             }
  218.             StringBuilder sbParseWarningResult = new StringBuilder();
  219.             this.openApi = parseResult(log, pr, sbParseWarningResult);
  220.             if(sbParseWarningResult.length()>0) {
  221.                 this.parseWarningResult = sbParseWarningResult.toString();
  222.             }
  223.            
  224.             this.openApiRaw = content;
  225.                    
  226.             if(schema!=null && schema.length>0) {
  227.                 for (int i = 0; i < schema.length; i++) {
  228.                     this.schemas.add(schema[i]);
  229.                 }
  230.             }
  231.            
  232.             this.resolveExternalRef = config.isProcessInclude();
  233.            
  234.         } catch(Exception e) {
  235.             throw new ProcessingException(e);
  236.         }

  237.     }

  238.     @Override
  239.     public void init(Logger log, byte[] content, ApiReaderConfig config) throws ProcessingException {
  240.         this.initEngine(log, content, config);
  241.     }
  242.     @Override
  243.     public void init(Logger log, byte[] content, ApiReaderConfig config, ApiSchema ... schema) throws ProcessingException {
  244.         this.initEngine(log, content, config, schema);
  245.     }
  246.     private void initEngine(Logger log, byte[] content, ApiReaderConfig config, ApiSchema ... schema) throws ProcessingException {
  247.         String s = null;
  248.         try {
  249.             String charset = config!=null?config.getCharset().getValue():Charset.UTF_8.getValue();
  250.             s = new String(content,charset);
  251.         } catch(Exception e) {
  252.             throw new ProcessingException(e);
  253.         }
  254.         this.initEngine(log, s, config, schema);
  255.     }
  256.    
  257.    
  258.    
  259.     @Override
  260.     public void init(Logger log, File file, ApiReaderConfig config) throws ProcessingException {
  261.         this.initEngine(log, file, config);
  262.     }
  263.     @Override
  264.     public void init(Logger log, File file, ApiReaderConfig config, ApiSchema ... schema) throws ProcessingException {
  265.         this.initEngine(log, file, config, schema);
  266.     }
  267.     private void initEngine(Logger log, File file, ApiReaderConfig config, ApiSchema ... schema) throws ProcessingException {
  268.         byte[]c = null;
  269.         try {
  270.             c = FileSystemUtilities.readBytesFromFile(file);
  271.         } catch(Exception e) {
  272.             throw new ProcessingException(e);
  273.         }
  274.         this.initEngine(log, c, config, schema);
  275.     }

  276.    
  277.    
  278.     @Override
  279.     public void init(Logger log, URI uri, ApiReaderConfig config) throws ProcessingException {
  280.         this.initEngine(log, uri, config);
  281.     }
  282.     @Override
  283.     public void init(Logger log, URI uri, ApiReaderConfig config, ApiSchema ... schema) throws ProcessingException {
  284.         this.initEngine(log, uri, config, schema);
  285.     }
  286.     private void initEngine(Logger log, URI uri, ApiReaderConfig config, ApiSchema ... schema) throws ProcessingException {
  287.         byte[]c = null;
  288.         try {
  289.             c = Utilities.getAsByteArray(uri.toURL().openStream());
  290.         } catch(Exception e) {
  291.             throw new ProcessingException(e);
  292.         }
  293.         this.initEngine(log, c, config, schema);
  294.     }
  295.    
  296.    

  297.     @Override
  298.     public void init(Logger log, Document doc, ApiReaderConfig config) throws ProcessingException {
  299.         this.initEngine(log, doc, config);
  300.     }
  301.     @Override
  302.     public void init(Logger log, Document doc, ApiReaderConfig config, ApiSchema ... schema) throws ProcessingException {
  303.         this.initEngine(log, doc, config, schema);
  304.     }
  305.     private void initEngine(Logger log, Document doc, ApiReaderConfig config, ApiSchema ... schema) throws ProcessingException {
  306.         if(log!=null || doc!=null || config!=null || schema!=null) {
  307.             // nop
  308.         }
  309.         throw new ProcessingException("Not implemented");
  310.     }

  311.    
  312.    
  313.    
  314.     @Override
  315.     public void init(Logger log, Element element, ApiReaderConfig config) throws ProcessingException {
  316.         this.initEngine(log, element, config);
  317.     }
  318.     @Override
  319.     public void init(Logger log, Element element, ApiReaderConfig config, ApiSchema ... schema) throws ProcessingException {
  320.         this.initEngine(log, element, config, schema);
  321.     }
  322.     private void initEngine(Logger log, Element element, ApiReaderConfig config, ApiSchema ... schema) throws ProcessingException {
  323.         if(log!=null || element!=null || config!=null || schema!=null) {
  324.             // nop
  325.         }
  326.         throw new ProcessingException("Not implemented");
  327.     }

  328.    

  329.     @Override
  330.     public Api read() throws ProcessingException {
  331.         if(this.openApi == null)
  332.             throw new ProcessingException("Api non correttamente inizializzata");
  333.         try {
  334.             OpenapiApi api = new OpenapiApi(this.format, this.openApi, this.openApiRaw, this.parseWarningResult);
  335.             if(!this.schemas.isEmpty()) {
  336.                 for (ApiSchema apiSchema : this.schemas) {
  337.                     api.addSchema(apiSchema);
  338.                 }
  339.             }
  340.             if(!this.openApi.getServers().isEmpty()) {
  341.                 String server = this.openApi.getServers().get(0).getUrl();
  342.                 URL url = null;
  343.                 try {
  344.                     url = new URL(server);
  345.                 }catch(Exception e) {
  346.                     // provo a verificare se il problema è che non e' stato definito il protocollo (es. in swagger lo 'schemes')
  347.                     if(server!=null && server.startsWith("/") &&
  348.                         !server.equals("/")) {
  349.                         server = "http:"+server;
  350.                         try {
  351.                             url = new URL(server);
  352.                         }catch(Exception e2) {
  353.                             // nop
  354.                         }
  355.                     }
  356.                 }
  357.                 if(url!=null) {
  358.                     api.setBaseURL(url);
  359.                 }
  360.             }
  361.             if(this.openApi.getInfo()!=null) {
  362.                 api.setDescription(this.openApi.getInfo().getDescription());
  363.             }

  364.             if(this.openApi.getPaths() != null){
  365.                 for (String pathK : this.openApi.getPaths().keySet()) {
  366.                     PathItem path = this.openApi.getPaths().get(pathK);
  367.                     if(path.getGet() != null) {
  368.                         ApiOperation operation = getOperation(path.getGet(), path.getParameters(), HttpRequestMethod.GET, pathK, api);
  369.                         api.addOperation(operation);
  370.                     }
  371.                     if(path.getHead() != null) {
  372.                         ApiOperation operation = getOperation(path.getHead(), path.getParameters(), HttpRequestMethod.HEAD, pathK, api);
  373.                         api.addOperation(operation);
  374.                     }
  375.                     if(path.getPost() != null) {
  376.                         ApiOperation operation = getOperation(path.getPost(), path.getParameters(), HttpRequestMethod.POST, pathK, api);
  377.                         api.addOperation(operation);
  378.                     }
  379.                     if(path.getPut() != null) {
  380.                         ApiOperation operation = getOperation(path.getPut(), path.getParameters(), HttpRequestMethod.PUT, pathK, api);
  381.                         api.addOperation(operation);
  382.                     }
  383.                     if(path.getDelete() != null) {
  384.                         ApiOperation operation = getOperation(path.getDelete(), path.getParameters(), HttpRequestMethod.DELETE, pathK, api);
  385.                         api.addOperation(operation);
  386.                     }
  387.                     if(path.getOptions() != null) {
  388.                         ApiOperation operation = getOperation(path.getOptions(), path.getParameters(), HttpRequestMethod.OPTIONS, pathK, api);
  389.                         api.addOperation(operation);
  390.                     }
  391.                     if(path.getTrace() != null) {
  392.                         ApiOperation operation = getOperation(path.getTrace(), path.getParameters(), HttpRequestMethod.TRACE, pathK, api);
  393.                         api.addOperation(operation);
  394.                     }
  395.                     if(path.getPatch() != null) {
  396.                         ApiOperation operation = getOperation(path.getPatch(), path.getParameters(), HttpRequestMethod.PATCH, pathK, api);
  397.                         api.addOperation(operation);
  398.                     }
  399.                 }
  400.             }
  401.             return api;
  402.         } catch(Exception e){
  403.             throw new ProcessingException(e);
  404.         }
  405.     }

  406.     private ApiOperation getOperation(Operation operation, List<Parameter> listParameter, HttpRequestMethod method, String pathK, OpenapiApi api) {
  407.         ApiOperation apiOperation = new ApiOperation(method, pathK);
  408.         apiOperation.setDescription(operation.getDescription());
  409.         if( (listParameter!=null && !listParameter.isEmpty())
  410.                 ||
  411.                 (operation.getParameters() != null)
  412.                 ||
  413.                 (operation.getRequestBody() != null)
  414.             ) {
  415.             ApiRequest request = new ApiRequest();

  416.             if(listParameter!=null && !listParameter.isEmpty()) {
  417.                 for(Parameter param: listParameter) {
  418.                     addRequestParameter(param, request, method, pathK, api);
  419.                 }
  420.             }
  421.             if(operation.getParameters() != null) {
  422.                 for(Parameter param: operation.getParameters()) {
  423.                     addRequestParameter(param, request, method, pathK, api);
  424.                 }
  425.             }
  426.             if(operation.getRequestBody() != null) {
  427.                 List<ApiBodyParameter> lst = createRequestBody(operation.getRequestBody(), method, pathK, api);
  428.                 for(ApiBodyParameter param: lst) {
  429.                     request.addBodyParameter(param);
  430.                 }
  431.             }

  432.             apiOperation.setRequest(request);
  433.         }

  434.         if(operation.getResponses()!= null && !operation.getResponses().isEmpty()) {
  435.             List<ApiResponse> responses = new ArrayList<>();
  436.             for(String responseK: operation.getResponses().keySet()) {
  437.                 responses.add(createResponses(responseK, operation.getResponses().get(responseK), method, pathK, api));
  438.             }
  439.             apiOperation.setResponses(responses);
  440.         }

  441.         return apiOperation;
  442.     }

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

  444.         if(requestBody.get$ref()!=null) {
  445.            
  446.             String ref = requestBody.get$ref();
  447.             boolean external = false;
  448.             if(ref.contains("#")) {
  449.                 external = !ref.trim().startsWith("#");
  450.                 ref = ref.substring(ref.indexOf("#"));
  451.             }
  452.             ref = ref.trim().replace(COMPONENTS_REQUEST_BODY, "").replace(DEFINITIONS, "");
  453.            
  454.             if(api.getApi()==null) {
  455.                 throw new UtilsRuntimeException("Richiesta non corretta: api da cui risolvere la ref '"+requestBody.get$ref()+SUFFIX_NON_TROVATA);
  456.             }
  457.             if(api.getApi().getComponents()==null) {
  458.                 if(!external || this.resolveExternalRef) {
  459.                     throw new UtilsRuntimeException("Richiesta non corretta: componenti, sui cui risolvere la ref '"+requestBody.get$ref()+SUFFIX_NON_PRESENTI);
  460.                 }
  461.             }
  462.             else {
  463.                 if(api.getApi().getComponents().getResponses()==null || api.getApi().getComponents().getResponses().size()<=0) {
  464.                     if(!external || this.resolveExternalRef) {
  465.                         throw new UtilsRuntimeException("Richiesta non corretta: richieste definite come componenti, sui cui risolvere la ref '"+requestBody.get$ref()+SUFFIX_NON_PRESENTI);
  466.                     }
  467.                 }
  468.                 else {
  469.                     boolean find = false;
  470.                     Iterator<String> itKeys = api.getApi().getComponents().getRequestBodies().keySet().iterator();
  471.                     while (itKeys.hasNext()) {
  472.                         String key = itKeys.next();
  473.                         if(key.equals(ref)) {
  474.                             requestBody = api.getApi().getComponents().getRequestBodies().get(key);
  475.                             find = true;
  476.                             break;
  477.                         }
  478.                     }
  479.                     if(!find &&
  480.                         (!external || this.resolveExternalRef)) {
  481.                         throw new UtilsRuntimeException("Richiesta non corretta: ref '"+requestBody.get$ref()+"' non presente tra le richieste definite come componenti");
  482.                     }
  483.                 }
  484.             }
  485.         }
  486.        
  487.         List<ApiBodyParameter> lst = new ArrayList<>();

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

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

  491.                 String type = null;
  492.                 ApiReference apiRef = null;
  493.                 if(model.get$ref()!= null) {
  494.                     String href = model.get$ref().trim();
  495.                     if(href.contains("#") && !href.startsWith("#")) {
  496.                         type = href.substring(href.indexOf("#"), href.length());
  497.                         type = type.replace(COMPONENTS_SCHEMAS, "").replace(DEFINITIONS, "");
  498.                         String ref = href.split("#")[0];
  499.                         File fRef = new File(ref);
  500.                         apiRef = new ApiReference(fRef.getName(), type);
  501.                     }
  502.                     else {
  503.                         type = href.replace(COMPONENTS_SCHEMAS, "").replace(DEFINITIONS, "");
  504.                     }
  505.                 } else {
  506.                     type = ("request_" + method.toString() + "_" + path+ "_" + consume).replace("/", "_");
  507.                     api.getDefinitions().put(type, model);
  508.                 }
  509.                
  510.                 ApiBodyParameter bodyParam = new ApiBodyParameter(type);
  511.                 bodyParam.setMediaType(consume);
  512.                 if(apiRef!=null) {
  513.                     bodyParam.setElement(apiRef);
  514.                 }else {
  515.                     bodyParam.setElement(type);
  516.                 }
  517.                 if(requestBody.getRequired() != null)
  518.                     bodyParam.setRequired(requestBody.getRequired());

  519.                 bodyParam.setDescription(requestBody.getDescription());
  520.                
  521.                 lst.add(bodyParam);

  522.             }
  523.         }

  524.         return lst;
  525.     }

  526.     private void addRequestParameter(Parameter paramP, ApiRequest request, HttpRequestMethod method, String path, OpenapiApi api) {
  527.        
  528.         // resolve ref parameter
  529.         Parameter param = this.resolveParameterRef(paramP, api);
  530.         if(param==null) {
  531.             param = paramP;
  532.         }
  533.        
  534.         AbstractApiParameter abstractParam = null;
  535.         String name = param.getName();
  536.         if(name==null && param.get$ref()!=null) {
  537.             // provo a risolvere il nome di un eventuale parametro riferito
  538.             name = getRefParameterName(param.get$ref(), api);
  539.         }
  540.        
  541.         ApiParameterSchema apiParameterSchema = getParameterSchema(param.getSchema(), param.get$ref(), name,
  542.                 null,  
  543.                 param.getStyle()!=null ? param.getStyle().toString(): null,
  544.                 param.getExplode(),
  545.                 api);
  546.        
  547.         if(this.debug) {
  548.             printDebug(SEPARATOR);
  549.             printDebug("REQUEST ("+method+" "+path+") name ["+name+"] required["+param.getRequired()+"] className["+param.getClass().getName()+"] ref["+param.get$ref()+"] apiParameterSchema["+apiParameterSchema.toString()+"]");
  550.             printDebug(SEPARATOR);
  551.         }
  552.        
  553.         if(param instanceof PathParameter) {
  554.             abstractParam = new ApiRequestDynamicPathParameter(name, apiParameterSchema);
  555.         } else if(param instanceof QueryParameter) {
  556.             abstractParam = new ApiRequestQueryParameter(name, apiParameterSchema);
  557.         } else if(param instanceof HeaderParameter) {
  558.             abstractParam = new ApiHeaderParameter(name, apiParameterSchema);
  559.         } else if(param instanceof CookieParameter) {
  560.             abstractParam = new ApiCookieParameter(name, apiParameterSchema);
  561.         }
  562.        
  563.         if(abstractParam == null &&
  564.             param.getIn() != null) {
  565.             if(param.getIn().equals("query")) {
  566.                 abstractParam = new ApiRequestQueryParameter(name, apiParameterSchema);
  567.             } else if(param.getIn().equals("header")) {
  568.                 abstractParam = new ApiHeaderParameter(name, apiParameterSchema);
  569.             } else if(param.getIn().equals("cookie")) {
  570.                 abstractParam = new ApiCookieParameter(name, apiParameterSchema);
  571.             } else if(param.getIn().equals("path")) {
  572.                 abstractParam = new ApiRequestDynamicPathParameter(name, apiParameterSchema);
  573.             }
  574.         }

  575.         if(abstractParam != null) {
  576.             abstractParam.setDescription(param.getDescription());
  577.             if(param.getRequired() != null)
  578.                 abstractParam.setRequired(param.getRequired());

  579.             if(abstractParam instanceof ApiRequestDynamicPathParameter) {
  580.                 request.addDynamicPathParameter((ApiRequestDynamicPathParameter) abstractParam);
  581.             } else if(abstractParam instanceof ApiRequestQueryParameter) {
  582.                 request.addQueryParameter((ApiRequestQueryParameter) abstractParam);
  583.             } else if(abstractParam instanceof ApiHeaderParameter) {
  584.                 request.addHeaderParameter((ApiHeaderParameter) abstractParam);
  585.             } else if(abstractParam instanceof ApiCookieParameter) {
  586.                 request.addCookieParameter((ApiCookieParameter) abstractParam);
  587.             } else if(abstractParam instanceof ApiRequestFormParameter) {
  588.                 request.addFormParameter((ApiRequestFormParameter) abstractParam);
  589.             }
  590.         }

  591.     }

  592.     private Parameter resolveParameterRef(Parameter p,  OpenapiApi api) {
  593.         if(p.get$ref()==null || "".equals(p.get$ref())) {
  594.             return p;
  595.         }
  596.        
  597.         String ref = p.get$ref();
  598.         boolean external = false;
  599.         if(ref.contains("#")) {
  600.             external = !ref.trim().startsWith("#");
  601.             ref = ref.substring(ref.indexOf("#"));
  602.         }
  603.         boolean refParameters = ref.startsWith(COMPONENTS_PARAMETERS);
  604.         if(!refParameters) {
  605.             return p;
  606.         }
  607.        
  608.         if(api.getApi().getComponents().getParameters()==null || api.getApi().getComponents().getParameters().size()<=0) {
  609.             if(!external || this.resolveExternalRef) {
  610.                 throw new UtilsRuntimeException(PREFIX_PARAMETRO+p.getName()+"' non corretto: parametri definiti come componenti, sui cui risolvere la ref '"+ref+SUFFIX_NON_PRESENTI);
  611.             }
  612.             else {
  613.                 return null;
  614.             }
  615.         }
  616.         else {
  617.             String checkRef = ref.trim().replace(COMPONENTS_PARAMETERS, "");
  618.             Parameter param = null;
  619.             Iterator<String> itKeys = api.getApi().getComponents().getParameters().keySet().iterator();
  620.             while (itKeys.hasNext()) {
  621.                 String key = itKeys.next();
  622.                 if(key.equals(checkRef)) {
  623.                     param = api.getApi().getComponents().getParameters().get(key);
  624.                     break;
  625.                 }
  626.             }
  627.             if(param==null &&
  628.                 (!external || this.resolveExternalRef) ){
  629.                 throw new UtilsRuntimeException(PREFIX_PARAMETRO+p.getName()+SEPARATOR_NON_CORRETTO_REF+ref+SUFFIX_NON_PRESENTE_COMPONENTI);
  630.             }
  631.             return param;
  632.         }
  633.     }
  634.    
  635.     private String getRefParameterName(String refParam, OpenapiApi api) {
  636.         if(refParam != null) {
  637.             String ref = refParam;
  638.             boolean external = false;
  639.             if(ref.contains("#")) {
  640.                 external = !ref.trim().startsWith("#");
  641.                 ref = ref.substring(ref.indexOf("#"));
  642.             }
  643.            
  644.             boolean refParameters = ref.startsWith(COMPONENTS_PARAMETERS);
  645.             if(refParameters) {
  646.                 if(api.getApi()==null) {
  647.                     throw new UtilsRuntimeException("Parametro non corretto: api da cui risolvere la ref '"+ref+SUFFIX_NON_TROVATA);
  648.                 }
  649.                 if(api.getApi().getComponents()==null) {
  650.                     if(!external || this.resolveExternalRef) {
  651.                         throw new UtilsRuntimeException("Parametro non corretto: componenti, sui cui risolvere la ref '"+ref+SUFFIX_NON_PRESENTI);
  652.                     }
  653.                     else {
  654.                         return refParam;
  655.                     }
  656.                 }
  657.                 else {
  658.                     if(api.getApi().getComponents().getParameters()==null || api.getApi().getComponents().getParameters().size()<=0) {
  659.                         if(!external || this.resolveExternalRef) {
  660.                             throw new UtilsRuntimeException("Parametro non corretto: parametri definiti come componenti, sui cui risolvere la ref '"+ref+SUFFIX_NON_PRESENTI);
  661.                         }
  662.                         else {
  663.                             return refParam;
  664.                         }
  665.                     }
  666.                     else {
  667.                         String checkRef = ref.trim().replace(COMPONENTS_PARAMETERS, "");
  668.                         Parameter param = null;
  669.                         Iterator<String> itKeys = api.getApi().getComponents().getParameters().keySet().iterator();
  670.                         while (itKeys.hasNext()) {
  671.                             String key = itKeys.next();
  672.                             if(key.equals(checkRef)) {
  673.                                 param = api.getApi().getComponents().getParameters().get(key);
  674.                                 break;
  675.                             }
  676.                         }
  677.                         if(param==null) {
  678.                             if(!external || this.resolveExternalRef) {
  679.                                 throw new UtilsRuntimeException("Parametro  non corretto: ref '"+ref+SUFFIX_NON_PRESENTE_COMPONENTI);
  680.                             }
  681.                             else {
  682.                                 return refParam;
  683.                             }
  684.                         }
  685.                         else {
  686.                             return param.getName();
  687.                         }
  688.                     }
  689.                 }
  690.             }                  
  691.         }

  692.         return null;
  693.     }
  694.    
  695.     /**
  696.     private String getParameterType(Schema<?> schema, String refParam, String name, OpenapiApi api) {
  697.         if(refParam != null) {
  698.             String ref = refParam;
  699.             boolean external = false;
  700.             if(ref.contains("#")) {
  701.                 external = !ref.trim().startsWith("#");
  702.                 ref = ref.substring(ref.indexOf("#"));
  703.             }
  704.            
  705.             boolean refHeaders = ref.startsWith(COMPONENTS_HEADERS);
  706.             boolean refParameters = ref.startsWith(COMPONENTS_PARAMETERS);
  707.             boolean refSchema = ref.startsWith(COMPONENTS_SCHEMAS);
  708.             if(refHeaders || refParameters || refSchema) {
  709.                 if(api.getApi()==null) {
  710.                     throw new UtilsRuntimeException(PREFIX_PARAMETRO+name+"' non corretto: api da cui risolvere la ref '"+ref+SUFFIX_NON_TROVATA);
  711.                 }
  712.                 else {
  713.                     if(api.getApi().getComponents()==null) {
  714.                         if(!external || this.resolveExternalRef) {
  715.                             throw new UtilsRuntimeException(PREFIX_PARAMETRO+name+"' non corretto: componenti, sui cui risolvere la ref '"+ref+SUFFIX_NON_PRESENTI);
  716.                         }
  717.                         else {
  718.                             return refParam;
  719.                         }
  720.                     }
  721.                     else {
  722.                         if(refHeaders) {
  723.                             if(api.getApi().getComponents().getHeaders()==null || api.getApi().getComponents().getHeaders().size()<=0) {
  724.                                 if(!external || this.resolveExternalRef) {
  725.                                     throw new UtilsRuntimeException(PREFIX_PARAMETRO+name+"' non corretto: headers definiti come componenti, sui cui risolvere la ref '"+ref+SUFFIX_NON_PRESENTI);
  726.                                 }
  727.                                 else {
  728.                                     return refParam;
  729.                                 }
  730.                             }
  731.                             String checkRef = ref.trim().replace(COMPONENTS_HEADERS, "");
  732.                             Header hdr = null;
  733.                             Iterator<String> itKeys = api.getApi().getComponents().getHeaders().keySet().iterator();
  734.                             while (itKeys.hasNext()) {
  735.                                 String key = (String) itKeys.next();
  736.                                 if(key.equals(checkRef)) {
  737.                                     hdr = api.getApi().getComponents().getHeaders().get(key);
  738.                                     break;
  739.                                 }
  740.                             }
  741.                             if(hdr==null) {
  742.                                 if(!external || this.resolveExternalRef) {
  743.                                     throw new UtilsRuntimeException(PREFIX_PARAMETRO+name+SEPARATOR_NON_CORRETTO_REF+ref+"' non presente tra gli headers definiti come componenti");
  744.                                 }
  745.                                 else {
  746.                                     return refParam;
  747.                                 }
  748.                             }
  749.                             else {
  750.                                 return getParameterType(hdr.getSchema(), hdr.get$ref(), name, api);
  751.                             }
  752.                         }
  753.                         else if(refParameters) {
  754.                             if(api.getApi().getComponents().getParameters()==null || api.getApi().getComponents().getParameters().size()<=0) {
  755.                                 if(!external || this.resolveExternalRef) {
  756.                                     throw new UtilsRuntimeException(PREFIX_PARAMETRO+name+"' non corretto: parametri definiti come componenti, sui cui risolvere la ref '"+ref+SUFFIX_NON_PRESENTI);
  757.                                 }
  758.                                 else {
  759.                                     return refParam;
  760.                                 }
  761.                             }
  762.                             String checkRef = ref.trim().replace(COMPONENTS_PARAMETERS, "");
  763.                             Parameter param = null;
  764.                             Iterator<String> itKeys = api.getApi().getComponents().getParameters().keySet().iterator();
  765.                             while (itKeys.hasNext()) {
  766.                                 String key = (String) itKeys.next();
  767.                                 if(key.equals(checkRef)) {
  768.                                     param = api.getApi().getComponents().getParameters().get(key);
  769.                                     break;
  770.                                 }
  771.                             }
  772.                             if(param==null) {
  773.                                 if(!external || this.resolveExternalRef) {
  774.                                     throw new UtilsRuntimeException(PREFIX_PARAMETRO+name+SEPARATOR_NON_CORRETTO_REF+ref+SUFFIX_NON_PRESENTE_COMPONENTI);
  775.                                 }
  776.                                 else {
  777.                                     return refParam;
  778.                                 }
  779.                             }
  780.                             else {
  781.                                 if(name==null && param.getName()!=null) {
  782.                                     name = param.getName();
  783.                                 }
  784.                                 return getParameterType(param.getSchema(), param.get$ref(), name, api);
  785.                             }
  786.                         }
  787.                         else {
  788.                             if(api.getApi().getComponents().getSchemas()==null || api.getApi().getComponents().getSchemas().size()<=0) {
  789.                                 if(!external || this.resolveExternalRef) {
  790.                                     throw new UtilsRuntimeException(PREFIX_PARAMETRO+name+"' non corretto: schemi definiti come componenti, sui cui risolvere la ref '"+ref+SUFFIX_NON_PRESENTI);
  791.                                 }
  792.                                 else {
  793.                                     return refParam;
  794.                                 }
  795.                             }
  796.                             String checkRef = ref.trim().replace(COMPONENTS_SCHEMAS, "");
  797.                             Schema<?> schemaRiferito = null;
  798.                             Iterator<String> itKeys = api.getApi().getComponents().getSchemas().keySet().iterator();
  799.                             while (itKeys.hasNext()) {
  800.                                 String key = (String) itKeys.next();
  801.                                 if(key.equals(checkRef)) {
  802.                                     schemaRiferito = api.getApi().getComponents().getSchemas().get(key);
  803.                                     break;
  804.                                 }
  805.                             }
  806.                             if(schemaRiferito==null) {
  807.                                 if(!external || this.resolveExternalRef) {
  808.                                     throw new UtilsRuntimeException(PREFIX_PARAMETRO+name+SEPARATOR_NON_CORRETTO_REF+ref+"' non presente tra gli schemi definiti come componenti");
  809.                                 }
  810.                                 else {
  811.                                     return refParam;
  812.                                 }
  813.                             }
  814.                             else {
  815.                                 return getParameterType(schemaRiferito, null, name, api);
  816.                             }
  817.                         }
  818.                     }
  819.                 }
  820.             }
  821.             else {
  822.                 // i requestBodies e le response non dovrebbero rientrare in questo metodo
  823.                 return ref.replace(COMPONENTS_SCHEMAS, "").replaceAll(DEFINITIONS, "");
  824.             }
  825.                        
  826.         }

  827.         if(schema==null) {
  828.             throw new UtilsRuntimeException(PREFIX_PARAMETRO+name+"' non corretto: schema non definito");
  829.         }
  830.        
  831.         if(schema.get$ref() != null) {
  832.             return getParameterType(schema, schema.get$ref(), name, api);
  833.         }
  834.        
  835.         if(schema instanceof ArraySchema) {
  836.             return getParameterType(((ArraySchema)schema).getItems(), null, name, api);
  837.         }
  838.        
  839.         if(schema instanceof ComposedSchema) {
  840.             ComposedSchema cs = (ComposedSchema) schema;
  841.             if(cs.getAnyOf()!=null && !cs.getAnyOf().isEmpty() && cs.getAnyOf().get(0)!=null) {
  842.                 // utilizzo il primo schema
  843.                 //NO NON VA BENE. DEVO STRUTTURARE L'INFORMAZIONE INSIEME ALLA RESTRIZIONE come una lista ???
  844.                 if(cs.getAnyOf().get(0).getFormat() != null) {
  845.                     return cs.getAnyOf().get(0).getFormat();
  846.                 } else {
  847.                     return cs.getAnyOf().get(0).getType();
  848.                 }
  849.                 // PRIMA TERMINARE COSI PER VEDERE SE FUNZIONA USANDO UN TIPO A CASO
  850.             }
  851.             else if(cs.getAllOf()!=null && !cs.getAllOf().isEmpty() && cs.getAllOf().get(0)!=null) {
  852.                 // utilizzo il primo schema
  853.                 //NO NON VA BENE. DEVO STRUTTURARE L'INFORMAZIONE INSIEME ALLA RESTRIZIONE come una lista ???
  854.                 if(cs.getAllOf().get(0).getFormat() != null) {
  855.                     return cs.getAllOf().get(0).getFormat();
  856.                 } else {
  857.                     return cs.getAllOf().get(0).getType();
  858.                 }
  859.                 // ALL OFF HA SENSO ??????????????? PROVARE COME SI COMPORTA OPENAPI
  860.             }
  861.         }
  862.        
  863.         if(schema.getFormat() != null) {
  864.             return schema.getFormat();
  865.         } else {
  866.             return schema.getType();
  867.         }
  868.     }
  869.    
  870.     private ApiSchemaTypeRestriction getParameterSchemaTypeRestriction(Schema<?> schema, String ref, String name,
  871.             Boolean arrayParameter, String style, Boolean explode, OpenapiApi api) {
  872.         if(ref != null) {
  873.             boolean external = false;
  874.             if(ref.contains("#")) {
  875.                 external = !ref.trim().startsWith("#");
  876.                 ref = ref.substring(ref.indexOf("#"));
  877.             }
  878.            
  879.             boolean refHeaders = ref.startsWith(COMPONENTS_HEADERS);
  880.             boolean refParameters = ref.startsWith(COMPONENTS_PARAMETERS);
  881.             boolean refSchema = ref.startsWith(COMPONENTS_SCHEMAS);
  882.             if(refHeaders || refParameters || refSchema) {
  883.                 if(api.getApi()==null) {
  884.                     throw new UtilsRuntimeException(PREFIX_PARAMETRO+name+"' non corretto: api da cui risolvere la ref '"+ref+SUFFIX_NON_TROVATA);
  885.                 }
  886.                 else {
  887.                     if(api.getApi().getComponents()==null) {
  888.                         if(!external || this.resolveExternalRef) {
  889.                             throw new UtilsRuntimeException(PREFIX_PARAMETRO+name+"' non corretto: componenti, sui cui risolvere la ref '"+ref+SUFFIX_NON_PRESENTI);
  890.                         }
  891.                         else {
  892.                             return null;
  893.                         }
  894.                     }
  895.                     else {
  896.                         if(refHeaders) {
  897.                             if(api.getApi().getComponents().getHeaders()==null || api.getApi().getComponents().getHeaders().size()<=0) {
  898.                                 if(!external || this.resolveExternalRef) {
  899.                                     throw new UtilsRuntimeException(PREFIX_PARAMETRO+name+"' non corretto: headers definiti come componenti, sui cui risolvere la ref '"+ref+SUFFIX_NON_PRESENTI);
  900.                                 }
  901.                                 else {
  902.                                     return null;
  903.                                 }
  904.                             }
  905.                             String checkRef = ref.trim().replace(COMPONENTS_HEADERS, "");
  906.                             Header hdr = null;
  907.                             Iterator<String> itKeys = api.getApi().getComponents().getHeaders().keySet().iterator();
  908.                             while (itKeys.hasNext()) {
  909.                                 String key = (String) itKeys.next();
  910.                                 if(key.equals(checkRef)) {
  911.                                     hdr = api.getApi().getComponents().getHeaders().get(key);
  912.                                     break;
  913.                                 }
  914.                             }
  915.                             if(hdr==null) {
  916.                                 if(!external || this.resolveExternalRef) {
  917.                                     throw new UtilsRuntimeException(PREFIX_PARAMETRO+name+SEPARATOR_NON_CORRETTO_REF+ref+"' non presente tra gli headers definiti come componenti");
  918.                                 }
  919.                                 else {
  920.                                     return null;
  921.                                 }
  922.                             }
  923.                             else {
  924.                                 return getParameterSchemaTypeRestriction(hdr.getSchema(), hdr.get$ref(), name,
  925.                                                     arrayParameter,
  926.                                                     hdr.getStyle()!=null ? hdr.getStyle().toString(): null,
  927.                                                     hdr.getExplode(),
  928.                                                     api);
  929.                             }
  930.                         }
  931.                         else if(refParameters) {
  932.                             if(api.getApi().getComponents().getParameters()==null || api.getApi().getComponents().getParameters().size()<=0) {
  933.                                 if(!external || this.resolveExternalRef) {
  934.                                     throw new UtilsRuntimeException(PREFIX_PARAMETRO+name+"' non corretto: parametri definiti come componenti, sui cui risolvere la ref '"+ref+SUFFIX_NON_PRESENTI);
  935.                                 }
  936.                                 else {
  937.                                     return null;
  938.                                 }
  939.                             }
  940.                             String checkRef = ref.trim().replace(COMPONENTS_PARAMETERS, "");
  941.                             Parameter param = null;
  942.                             Iterator<String> itKeys = api.getApi().getComponents().getParameters().keySet().iterator();
  943.                             while (itKeys.hasNext()) {
  944.                                 String key = (String) itKeys.next();
  945.                                 if(key.equals(checkRef)) {
  946.                                     param = api.getApi().getComponents().getParameters().get(key);
  947.                                     break;
  948.                                 }
  949.                             }
  950.                             if(param==null) {
  951.                                 if(!external || this.resolveExternalRef) {
  952.                                     throw new UtilsRuntimeException(PREFIX_PARAMETRO+name+SEPARATOR_NON_CORRETTO_REF+ref+SUFFIX_NON_PRESENTE_COMPONENTI);
  953.                                 }
  954.                                 else {
  955.                                     return null;
  956.                                 }
  957.                             }
  958.                             else {
  959.                                 if(name==null && param.getName()!=null) {
  960.                                     name = param.getName();
  961.                                 }
  962.                                 return getParameterSchemaTypeRestriction(param.getSchema(), param.get$ref(), name,
  963.                                                 arrayParameter,
  964.                                                 param.getStyle()!=null ? param.getStyle().toString(): null,
  965.                                                 param.getExplode(),
  966.                                                 api);
  967.                             }
  968.                         }
  969.                         else {
  970.                             if(api.getApi().getComponents().getSchemas()==null || api.getApi().getComponents().getSchemas().size()<=0) {
  971.                                 if(!external || this.resolveExternalRef) {
  972.                                     throw new UtilsRuntimeException(PREFIX_PARAMETRO+name+"' non corretto: schemi definiti come componenti, sui cui risolvere la ref '"+ref+SUFFIX_NON_PRESENTI);
  973.                                 }
  974.                                 else {
  975.                                     return null;
  976.                                 }
  977.                             }
  978.                             String checkRef = ref.trim().replace(COMPONENTS_SCHEMAS, "");
  979.                             Schema<?> schemaRiferito = null;
  980.                             Iterator<String> itKeys = api.getApi().getComponents().getSchemas().keySet().iterator();
  981.                             while (itKeys.hasNext()) {
  982.                                 String key = (String) itKeys.next();
  983.                                 if(key.equals(checkRef)) {
  984.                                     schemaRiferito = api.getApi().getComponents().getSchemas().get(key);
  985.                                     break;
  986.                                 }
  987.                             }
  988.                             if(schemaRiferito==null) {
  989.                                 if(!external || this.resolveExternalRef) {
  990.                                     throw new UtilsRuntimeException(PREFIX_PARAMETRO+name+SEPARATOR_NON_CORRETTO_REF+ref+"' non presente tra gli schemi definiti come componenti");
  991.                                 }
  992.                                 else {
  993.                                     return null;
  994.                                 }
  995.                             }
  996.                             else {
  997.                                 return getParameterSchemaTypeRestriction(schemaRiferito, null, name,
  998.                                         arrayParameter,
  999.                                         style,
  1000.                                         explode,
  1001.                                         api);
  1002.                             }
  1003.                         }
  1004.                     }
  1005.                 }
  1006.             }
  1007.             else {
  1008.                 return null; // schema non trovato.
  1009.             }
  1010.                        
  1011.         }

  1012.         if(schema.get$ref() != null) {
  1013.             return getParameterSchemaTypeRestriction(schema, schema.get$ref(), name,
  1014.                     arrayParameter,
  1015.                     style,
  1016.                     explode,
  1017.                     api);
  1018.         }
  1019.        
  1020.         if(schema instanceof ArraySchema) {
  1021.             return getParameterSchemaTypeRestriction(((ArraySchema)schema).getItems(), null, name,
  1022.                     true,
  1023.                     style,
  1024.                     explode,
  1025.                     api);
  1026.         }
  1027.        
  1028.         return this.convertTo(schema, arrayParameter, style, explode);
  1029.     }
  1030.     */
  1031.    
  1032.     private ApiParameterSchema getParameterSchema(Schema<?> schema, String ref, String name,
  1033.             Boolean arrayParameter, String style, Boolean explode, OpenapiApi api) {
  1034.         if(ref != null) {
  1035.             boolean external = false;
  1036.             if(ref.contains("#")) {
  1037.                 external = !ref.trim().startsWith("#");
  1038.                 ref = ref.substring(ref.indexOf("#"));
  1039.             }
  1040.            
  1041.             boolean refHeaders = ref.startsWith(COMPONENTS_HEADERS);
  1042.             boolean refParameters = ref.startsWith(COMPONENTS_PARAMETERS);
  1043.             boolean refSchema = ref.startsWith(COMPONENTS_SCHEMAS);
  1044.             if(refHeaders || refParameters || refSchema) {
  1045.                 if(api.getApi()==null) {
  1046.                     throw new UtilsRuntimeException(PREFIX_PARAMETRO+name+"' non corretto: api da cui risolvere la ref '"+ref+SUFFIX_NON_TROVATA);
  1047.                 }
  1048.                 else {
  1049.                     if(api.getApi().getComponents()==null) {
  1050.                         if(!external || this.resolveExternalRef) {
  1051.                             throw new UtilsRuntimeException(PREFIX_PARAMETRO+name+"' non corretto: componenti, sui cui risolvere la ref '"+ref+SUFFIX_NON_PRESENTI);
  1052.                         }
  1053.                         else {
  1054.                             ApiParameterSchema aps = new ApiParameterSchema();
  1055.                             aps.addType(ref, null);
  1056.                             return aps;
  1057.                         }
  1058.                     }
  1059.                     else {
  1060.                         if(refHeaders) {
  1061.                             if(api.getApi().getComponents().getHeaders()==null || api.getApi().getComponents().getHeaders().size()<=0) {
  1062.                                 if(!external || this.resolveExternalRef) {
  1063.                                     throw new UtilsRuntimeException(PREFIX_PARAMETRO+name+"' non corretto: headers definiti come componenti, sui cui risolvere la ref '"+ref+SUFFIX_NON_PRESENTI);
  1064.                                 }
  1065.                                 else {
  1066.                                     ApiParameterSchema aps = new ApiParameterSchema();
  1067.                                     aps.addType(ref, null);
  1068.                                     return aps;
  1069.                                 }
  1070.                             }
  1071.                             String checkRef = ref.trim().replace(COMPONENTS_HEADERS, "");
  1072.                             Header hdr = null;
  1073.                             Iterator<String> itKeys = api.getApi().getComponents().getHeaders().keySet().iterator();
  1074.                             while (itKeys.hasNext()) {
  1075.                                 String key = itKeys.next();
  1076.                                 if(key.equals(checkRef)) {
  1077.                                     hdr = api.getApi().getComponents().getHeaders().get(key);
  1078.                                     break;
  1079.                                 }
  1080.                             }
  1081.                             if(hdr==null) {
  1082.                                 if(!external || this.resolveExternalRef) {
  1083.                                     throw new UtilsRuntimeException(PREFIX_PARAMETRO+name+SEPARATOR_NON_CORRETTO_REF+ref+"' non presente tra gli headers definiti come componenti");
  1084.                                 }
  1085.                                 else {
  1086.                                     ApiParameterSchema aps = new ApiParameterSchema();
  1087.                                     aps.addType(ref, null);
  1088.                                     return aps;
  1089.                                 }
  1090.                             }
  1091.                             else {
  1092.                                 return getParameterSchema(hdr.getSchema(), hdr.get$ref(), name,
  1093.                                                     arrayParameter,
  1094.                                                     hdr.getStyle()!=null ? hdr.getStyle().toString(): null,
  1095.                                                     hdr.getExplode(),
  1096.                                                     api);
  1097.                             }
  1098.                         }
  1099.                         else if(refParameters) {
  1100.                             if(api.getApi().getComponents().getParameters()==null || api.getApi().getComponents().getParameters().size()<=0) {
  1101.                                 if(!external || this.resolveExternalRef) {
  1102.                                     throw new UtilsRuntimeException(PREFIX_PARAMETRO+name+"' non corretto: parametri definiti come componenti, sui cui risolvere la ref '"+ref+SUFFIX_NON_PRESENTI);
  1103.                                 }
  1104.                                 else {
  1105.                                     ApiParameterSchema aps = new ApiParameterSchema();
  1106.                                     aps.addType(ref, null);
  1107.                                     return aps;
  1108.                                 }
  1109.                             }
  1110.                             String checkRef = ref.trim().replace(COMPONENTS_PARAMETERS, "");
  1111.                             Parameter param = null;
  1112.                             Iterator<String> itKeys = api.getApi().getComponents().getParameters().keySet().iterator();
  1113.                             while (itKeys.hasNext()) {
  1114.                                 String key = itKeys.next();
  1115.                                 if(key.equals(checkRef)) {
  1116.                                     param = api.getApi().getComponents().getParameters().get(key);
  1117.                                     break;
  1118.                                 }
  1119.                             }
  1120.                             if(param==null) {
  1121.                                 if(!external || this.resolveExternalRef) {
  1122.                                     throw new UtilsRuntimeException(PREFIX_PARAMETRO+name+SEPARATOR_NON_CORRETTO_REF+ref+SUFFIX_NON_PRESENTE_COMPONENTI);
  1123.                                 }
  1124.                                 else {
  1125.                                     ApiParameterSchema aps = new ApiParameterSchema();
  1126.                                     aps.addType(ref, null);
  1127.                                     return aps;
  1128.                                 }
  1129.                             }
  1130.                             else {
  1131.                                 if(name==null && param.getName()!=null) {
  1132.                                     name = param.getName();
  1133.                                 }
  1134.                                 return getParameterSchema(param.getSchema(), param.get$ref(), name,
  1135.                                                 arrayParameter,
  1136.                                                 param.getStyle()!=null ? param.getStyle().toString(): null,
  1137.                                                 param.getExplode(),
  1138.                                                 api);
  1139.                             }
  1140.                         }
  1141.                         else {
  1142.                             if(api.getApi().getComponents().getSchemas()==null || api.getApi().getComponents().getSchemas().size()<=0) {
  1143.                                 if(!external || this.resolveExternalRef) {
  1144.                                     throw new UtilsRuntimeException(PREFIX_PARAMETRO+name+"' non corretto: schemi definiti come componenti, sui cui risolvere la ref '"+ref+SUFFIX_NON_PRESENTI);
  1145.                                 }
  1146.                                 else {
  1147.                                     ApiParameterSchema aps = new ApiParameterSchema();
  1148.                                     aps.addType(ref, null);
  1149.                                     return aps;
  1150.                                 }
  1151.                             }
  1152.                             String checkRef = ref.trim().replace(COMPONENTS_SCHEMAS, "");
  1153.                             Schema<?> schemaRiferito = null;
  1154.                             Iterator<String> itKeys = api.getApi().getComponents().getSchemas().keySet().iterator();
  1155.                             while (itKeys.hasNext()) {
  1156.                                 String key = itKeys.next();
  1157.                                 if(key.equals(checkRef)) {
  1158.                                     schemaRiferito = api.getApi().getComponents().getSchemas().get(key);
  1159.                                     break;
  1160.                                 }
  1161.                             }
  1162.                             if(schemaRiferito==null) {
  1163.                                 if(!external || this.resolveExternalRef) {
  1164.                                     throw new UtilsRuntimeException(PREFIX_PARAMETRO+name+SEPARATOR_NON_CORRETTO_REF+ref+"' non presente tra gli schemi definiti come componenti");
  1165.                                 }
  1166.                                 else {
  1167.                                     ApiParameterSchema aps = new ApiParameterSchema();
  1168.                                     aps.addType(ref, null);
  1169.                                     return aps;
  1170.                                 }
  1171.                             }
  1172.                             else {
  1173.                                 return getParameterSchema(schemaRiferito, null, name,
  1174.                                         arrayParameter,
  1175.                                         style,
  1176.                                         explode,
  1177.                                         api);
  1178.                             }
  1179.                         }
  1180.                     }
  1181.                 }
  1182.             }
  1183.             else {
  1184.                 // i requestBodies e le response non dovrebbero rientrare in questo metodo
  1185.                 String typeReturn = ref.replace(COMPONENTS_SCHEMAS, "").replace(DEFINITIONS, "");
  1186.                 ApiSchemaTypeRestriction schemaReturn = null; // schema non trovato.
  1187.                 ApiParameterSchema aps = new ApiParameterSchema();
  1188.                 aps.addType(typeReturn, schemaReturn);
  1189.                 return aps;
  1190.             }
  1191.                        
  1192.         }

  1193.         if(schema==null) {
  1194.             throw new UtilsRuntimeException(PREFIX_PARAMETRO+name+"' non corretto: schema non definito");
  1195.         }
  1196.        
  1197.         if(schema.get$ref() != null) {
  1198.             return getParameterSchema(schema, schema.get$ref(), name,
  1199.                     arrayParameter,
  1200.                     style,
  1201.                     explode,
  1202.                     api);
  1203.         }
  1204.        
  1205.         if(schema instanceof ArraySchema) {
  1206.             return getParameterSchema(((ArraySchema)schema).getItems(), null, name,
  1207.                     true,
  1208.                     style,
  1209.                     explode,
  1210.                     api);
  1211.         }
  1212.        
  1213.         if(schema instanceof ComposedSchema) {
  1214.             ComposedSchema cs = (ComposedSchema) schema;
  1215.             if(cs.getAnyOf()!=null && !cs.getAnyOf().isEmpty()) {
  1216.                 ApiParameterSchema aps = new ApiParameterSchema();
  1217.                 aps.setComplexType(ApiParameterSchemaComplexType.anyOf);
  1218.                 for (Schema<?> apiSchemaAnyOf : cs.getAnyOf()) {
  1219.                     String typeReturn = null;
  1220.                     if(apiSchemaAnyOf.getFormat() != null) {
  1221.                         typeReturn = apiSchemaAnyOf.getFormat();
  1222.                     } else {
  1223.                         typeReturn = apiSchemaAnyOf.getType();
  1224.                     }
  1225.                     ApiSchemaTypeRestriction schemaReturn = this.convertTo(apiSchemaAnyOf, arrayParameter, style, explode);
  1226.                     aps.addType(typeReturn, schemaReturn);
  1227.                 }
  1228.                 return aps;
  1229.             }
  1230.             else if(cs.getAllOf()!=null && !cs.getAllOf().isEmpty()) {
  1231.                 ApiParameterSchema aps = new ApiParameterSchema();
  1232.                 aps.setComplexType(ApiParameterSchemaComplexType.allOf);
  1233.                 for (Schema<?> apiSchemaAllOf : cs.getAllOf()) {
  1234.                     String typeReturn = null;
  1235.                     if(apiSchemaAllOf.getFormat() != null) {
  1236.                         typeReturn = apiSchemaAllOf.getFormat();
  1237.                     } else {
  1238.                         typeReturn = apiSchemaAllOf.getType();
  1239.                     }
  1240.                     ApiSchemaTypeRestriction schemaReturn = this.convertTo(apiSchemaAllOf, arrayParameter, style, explode);
  1241.                     aps.addType(typeReturn, schemaReturn);
  1242.                 }
  1243.                 return aps;
  1244.             }
  1245.             else if(cs.getOneOf()!=null && !cs.getOneOf().isEmpty()) {
  1246.                 ApiParameterSchema aps = new ApiParameterSchema();
  1247.                 aps.setComplexType(ApiParameterSchemaComplexType.oneOf);
  1248.                 for (Schema<?> apiSchemaOneOf : cs.getOneOf()) {
  1249.                     String typeReturn = null;
  1250.                     if(apiSchemaOneOf.getFormat() != null) {
  1251.                         typeReturn = apiSchemaOneOf.getFormat();
  1252.                     } else {
  1253.                         typeReturn = apiSchemaOneOf.getType();
  1254.                     }
  1255.                     ApiSchemaTypeRestriction schemaReturn = this.convertTo(apiSchemaOneOf, arrayParameter, style, explode);
  1256.                     aps.addType(typeReturn, schemaReturn);
  1257.                 }
  1258.                 return aps;
  1259.             }
  1260.         }
  1261.        
  1262.         String typeReturn = null;
  1263.         if(schema.getFormat() != null) {
  1264.             typeReturn = schema.getFormat();
  1265.         } else {
  1266.             typeReturn = schema.getType();
  1267.         }
  1268.         if(typeReturn==null && schema.getTypes()!=null && !schema.getTypes().isEmpty()) {
  1269.             typeReturn=schema.getTypes().iterator().next();
  1270.         }
  1271.         ApiSchemaTypeRestriction schemaReturn = this.convertTo(schema, arrayParameter, style, explode);
  1272.         ApiParameterSchema aps = new ApiParameterSchema();
  1273.         aps.addType(typeReturn, schemaReturn);
  1274.         return aps;
  1275.     }

  1276.     private ApiSchemaTypeRestriction convertTo(Schema<?> schema, Boolean arrayParameter, String style, Boolean explode) {
  1277.         ApiSchemaTypeRestriction schemaTypeRestriction = new ApiSchemaTypeRestriction();
  1278.         schemaTypeRestriction.setSchema(schema);
  1279.         schemaTypeRestriction.setType(schema.getType());
  1280.         schemaTypeRestriction.setFormat(schema.getFormat());
  1281.        
  1282.         schemaTypeRestriction.setMinimum(schema.getMinimum());
  1283.         schemaTypeRestriction.setExclusiveMinimum(schema.getExclusiveMinimum());
  1284.         schemaTypeRestriction.setMaximum(schema.getMaximum());
  1285.         schemaTypeRestriction.setExclusiveMaximum(schema.getExclusiveMaximum());
  1286.        
  1287.         schemaTypeRestriction.setMultipleOf(schema.getMultipleOf());

  1288.         schemaTypeRestriction.setMinLength(schema.getMinLength()!=null ? Long.valueOf(schema.getMinLength()) : null);
  1289.         schemaTypeRestriction.setMaxLength(schema.getMaxLength()!=null ? Long.valueOf(schema.getMaxLength()) : null);
  1290.    
  1291.         schemaTypeRestriction.setPattern(schema.getPattern());

  1292.         schemaTypeRestriction.setEnumValues(schema.getEnum());
  1293.        
  1294.         schemaTypeRestriction.setArrayParameter(arrayParameter);
  1295.         schemaTypeRestriction.setStyle(style);
  1296.         if(explode!=null) {
  1297.             schemaTypeRestriction.setExplode(explode.booleanValue()+"");
  1298.         }
  1299.        
  1300.         return schemaTypeRestriction;
  1301.     }

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

  1303.         ApiResponse apiResponse= new ApiResponse();

  1304.         int status = -1;
  1305.         try{
  1306.             if("default".equals(responseK)) {
  1307.                 apiResponse.setDefaultHttpReturnCode();
  1308.             }
  1309.             else {
  1310.                 status = Integer.parseInt(responseK);
  1311.                 apiResponse.setHttpReturnCode(status);
  1312.             }
  1313.         } catch(NumberFormatException e) {
  1314.             throw new UtilsRuntimeException("Stato non supportato ["+responseK+"]", e);
  1315.         }
  1316.         /**if(status<=0) {
  1317.             status = 200;
  1318.         }*/
  1319.        
  1320.         if(response.get$ref()!=null) {
  1321.            
  1322.             String ref = response.get$ref();
  1323.             boolean external = false;
  1324.             if(ref.contains("#")) {
  1325.                 external = !ref.trim().startsWith("#");
  1326.                 ref = ref.substring(ref.indexOf("#"));
  1327.             }
  1328.             ref = ref.trim().replace(COMPONENTS_RESPONSES, "").replace(DEFINITIONS, "");
  1329.            
  1330.             if(api.getApi()==null) {
  1331.                 throw new UtilsRuntimeException("Stato non corretto ["+responseK+"]: api da cui risolvere la ref '"+response.get$ref()+SUFFIX_NON_TROVATA);
  1332.             }
  1333.             if(api.getApi().getComponents()==null) {
  1334.                 if(!external || this.resolveExternalRef) {
  1335.                     throw new UtilsRuntimeException("Stato non corretto ["+responseK+"]: componenti, sui cui risolvere la ref '"+response.get$ref()+SUFFIX_NON_PRESENTI);
  1336.                 }
  1337.             }
  1338.             else {
  1339.                 if(api.getApi().getComponents().getResponses()==null || api.getApi().getComponents().getResponses().size()<=0) {
  1340.                     if(!external || this.resolveExternalRef) {
  1341.                         throw new UtilsRuntimeException("Stato non corretto ["+responseK+"]: risposte definite come componenti, sui cui risolvere la ref '"+response.get$ref()+SUFFIX_NON_PRESENTI);
  1342.                     }
  1343.                 }
  1344.                 else {
  1345.                     boolean find = false;
  1346.                     Iterator<String> itKeys = api.getApi().getComponents().getResponses().keySet().iterator();
  1347.                     while (itKeys.hasNext()) {
  1348.                         String key = itKeys.next();
  1349.                         if(key.equals(ref)) {
  1350.                             response = api.getApi().getComponents().getResponses().get(key);
  1351.                             find = true;
  1352.                             break;
  1353.                         }
  1354.                     }
  1355.                     if(!find &&
  1356.                         (!external || this.resolveExternalRef) ){
  1357.                         throw new UtilsRuntimeException("Stato non corretto ["+responseK+"]: ref '"+response.get$ref()+"' non presente tra le risposte definite come componenti");
  1358.                     }
  1359.                 }
  1360.             }
  1361.         }
  1362.        
  1363.         apiResponse.setDescription(response.getDescription());

  1364.         if(response.getHeaders() != null) {
  1365.             for(String header: response.getHeaders().keySet()) {
  1366.                 Header property = response.getHeaders().get(header);
  1367.                
  1368.                 ApiParameterSchema apiParameterSchema = getParameterSchema(property.getSchema(), property.get$ref(), header,
  1369.                                 null,
  1370.                                 property.getStyle()!=null ? property.getStyle().toString(): null,
  1371.                                 property.getExplode(),
  1372.                                 api);
  1373.                
  1374.                 if(this.debug) {
  1375.                     printDebug(SEPARATOR);
  1376.                     printDebug("RESPONSE ("+method+" "+path+") name ["+header+"] required["+property.getRequired()+"] className["+property.getClass().getName()+"] ref["+property.get$ref()+"] apiParameterSchema["+apiParameterSchema+"]");
  1377.                     printDebug(SEPARATOR);
  1378.                 }
  1379.                
  1380.                 ApiHeaderParameter parameter = new ApiHeaderParameter(header, apiParameterSchema);
  1381.                 parameter.setDescription(property.getDescription());
  1382.                 if(property.getRequired() != null)
  1383.                     parameter.setRequired(property.getRequired());
  1384.                
  1385.                 apiResponse.addHeaderParameter(parameter);
  1386.             }
  1387.         }
  1388.        
  1389.         if(response.getContent() != null && !response.getContent().isEmpty()) {
  1390.             for(String contentType: response.getContent().keySet()) {

  1391.                 MediaType mediaType = response.getContent().get(contentType);
  1392.                 Schema<?> schema = mediaType.getSchema();
  1393.                
  1394.                 String name = ("response_" +method.toString() + "_" + path + "_" + responseK + "_" + contentType).replace("/", "_");

  1395.                 String type = null;
  1396.                 ApiReference apiRef = null;
  1397.                 if(schema!=null && schema.get$ref()!= null) {
  1398.                     String href = schema.get$ref().trim();
  1399.                     if(href.contains("#") && !href.startsWith("#")) {
  1400.                         type = href.substring(href.indexOf("#"), href.length());
  1401.                         type = type.replace(COMPONENTS_SCHEMAS, "").replace(DEFINITIONS, "");
  1402.                         String ref = href.split("#")[0];
  1403.                         File fRef = new File(ref);
  1404.                         apiRef = new ApiReference(fRef.getName(), type);
  1405.                     }
  1406.                     else {
  1407.                         type = href.replace(COMPONENTS_SCHEMAS, "").replace(DEFINITIONS, "");
  1408.                     }
  1409.                 } else {
  1410.                     type = ("response_" +method.toString() + "_" + path + "_" + responseK + "_" + contentType).replace("/", "_");
  1411.                     api.getDefinitions().put(type, schema);
  1412.                 }
  1413.                
  1414.                 ApiBodyParameter bodyParam = new ApiBodyParameter(name);
  1415.                 bodyParam.setMediaType(contentType);
  1416.                 if(apiRef!=null) {
  1417.                     bodyParam.setElement(apiRef);
  1418.                 }else {
  1419.                     bodyParam.setElement(type);
  1420.                 }
  1421.                
  1422.                 /**String typeF = getParameterType(schema, null);
  1423.                 bodyParam.setElement(type);*/
  1424.                
  1425.                 bodyParam.setRequired(true);
  1426.                
  1427.                 apiResponse.addBodyParameter(bodyParam);
  1428.             }
  1429.         }

  1430.         return apiResponse;
  1431.     }
  1432.    
  1433.     private void printDebug(String msg) {
  1434.         System.out.println(msg);
  1435.     }
  1436. }