All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.reprezen.genflow.rapidml.swagger.XGenerateSwagger Maven / Gradle / Ivy

/**
 * Copyright © 2013, 2016 Modelsolv, Inc.
 * All Rights Reserved.
 * 
 * NOTICE: All information contained herein is, and remains the property
 * of ModelSolv, Inc. See the file license.html in the root directory of
 * this project for further information.
 */
package com.reprezen.genflow.rapidml.swagger;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.google.common.base.Objects;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.reprezen.genflow.api.template.IGenTemplateContext;
import com.reprezen.genflow.api.zenmodel.ZenModelOutputItem;
import com.reprezen.genflow.common.jsonschema.JsonSchemaHelper;
import com.reprezen.genflow.common.xtend.ExtensionsHelper;
import com.reprezen.genflow.common.xtend.ZenModelHelper;
import com.reprezen.genflow.rapidml.swagger.JsonSchemaForSwaggerGenerator;
import com.reprezen.genflow.rapidml.swagger.SwaggerOutputFormat;
import com.reprezen.genflow.rapidml.swagger.XSwaggerGenTemplate;
import com.reprezen.rapidml.AuthenticationFlows;
import com.reprezen.rapidml.AuthenticationMethod;
import com.reprezen.rapidml.AuthenticationTypes;
import com.reprezen.rapidml.Constraint;
import com.reprezen.rapidml.Example;
import com.reprezen.rapidml.Extensible;
import com.reprezen.rapidml.Feature;
import com.reprezen.rapidml.HasSecurityValue;
import com.reprezen.rapidml.HttpMessageParameterLocation;
import com.reprezen.rapidml.LengthConstraint;
import com.reprezen.rapidml.MediaType;
import com.reprezen.rapidml.MessageParameter;
import com.reprezen.rapidml.Method;
import com.reprezen.rapidml.PrimitiveProperty;
import com.reprezen.rapidml.PropertyRealization;
import com.reprezen.rapidml.PropertyReference;
import com.reprezen.rapidml.RapidmlFactory;
import com.reprezen.rapidml.RegExConstraint;
import com.reprezen.rapidml.ResourceAPI;
import com.reprezen.rapidml.ResourceDefinition;
import com.reprezen.rapidml.SecurityScheme;
import com.reprezen.rapidml.SecuritySchemeLibrary;
import com.reprezen.rapidml.SecuritySchemeParameter;
import com.reprezen.rapidml.SecurityScope;
import com.reprezen.rapidml.ServiceDataResource;
import com.reprezen.rapidml.SingleValueType;
import com.reprezen.rapidml.SourceReference;
import com.reprezen.rapidml.Structure;
import com.reprezen.rapidml.TemplateParameter;
import com.reprezen.rapidml.TypedMessage;
import com.reprezen.rapidml.TypedResponse;
import com.reprezen.rapidml.URIParameter;
import com.reprezen.rapidml.ValueRangeConstraint;
import com.reprezen.rapidml.ZenModel;
import com.reprezen.rapidml.util.OAuth2Parameters;
import io.swagger.models.Info;
import io.swagger.models.Model;
import io.swagger.models.Operation;
import io.swagger.models.Path;
import io.swagger.models.RefModel;
import io.swagger.models.Response;
import io.swagger.models.Scheme;
import io.swagger.models.Swagger;
import io.swagger.models.Tag;
import io.swagger.models.auth.ApiKeyAuthDefinition;
import io.swagger.models.auth.BasicAuthDefinition;
import io.swagger.models.auth.In;
import io.swagger.models.auth.OAuth2Definition;
import io.swagger.models.auth.SecuritySchemeDefinition;
import io.swagger.models.parameters.AbstractParameter;
import io.swagger.models.parameters.AbstractSerializableParameter;
import io.swagger.models.parameters.BodyParameter;
import io.swagger.models.parameters.HeaderParameter;
import io.swagger.models.parameters.PathParameter;
import io.swagger.models.parameters.QueryParameter;
import io.swagger.models.properties.AbstractNumericProperty;
import io.swagger.models.properties.AbstractProperty;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.BooleanProperty;
import io.swagger.models.properties.DateProperty;
import io.swagger.models.properties.DateTimeProperty;
import io.swagger.models.properties.DecimalProperty;
import io.swagger.models.properties.DoubleProperty;
import io.swagger.models.properties.FloatProperty;
import io.swagger.models.properties.IntegerProperty;
import io.swagger.models.properties.LongProperty;
import io.swagger.models.properties.Property;
import io.swagger.models.properties.RefProperty;
import io.swagger.models.properties.StringProperty;
import io.swagger.util.Json;
import io.swagger.util.Yaml;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import org.eclipse.emf.common.util.EList;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Conversions;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.ExclusiveRange;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.IteratorExtensions;
import org.eclipse.xtext.xbase.lib.ListExtensions;
import org.eclipse.xtext.xbase.lib.StringExtensions;
import org.yaml.snakeyaml.DumperOptions;

@SuppressWarnings("all")
public class XGenerateSwagger extends ZenModelOutputItem {
  public final static String OUTPUT_FORMAT_PARAM = "format";
  
  public final static String OPTION_RETAIN_EMPTY_PARAMATERS = "retainEmptyParameters";
  
  @Extension
  private ZenModelHelper _zenModelHelper = new ZenModelHelper();
  
  @Extension
  private JsonSchemaHelper _jsonSchemaHelper = new JsonSchemaHelper();
  
  @Extension
  private ExtensionsHelper _extensionsHelper = new ExtensionsHelper();
  
  private final String defaultFormat;
  
  private final JsonSchemaForSwaggerGenerator jsonSchemaGenerator;
  
  public XGenerateSwagger() {
    this(SwaggerOutputFormat.JSON);
  }
  
  public XGenerateSwagger(final SwaggerOutputFormat format) {
    this(format, new JsonSchemaForSwaggerGenerator());
  }
  
  public XGenerateSwagger(final SwaggerOutputFormat format, final JsonSchemaForSwaggerGenerator jsonSchemaGenerator) {
    this.defaultFormat = format.toString();
    this.jsonSchemaGenerator = jsonSchemaGenerator;
  }
  
  @Override
  public void init(final IGenTemplateContext context) {
    super.init(context);
  }
  
  @Override
  public String generate(final ZenModel model) {
    try {
      final Map templateParam = this.context.getGenTargetParameters();
      final Swagger swagger = this.getSwagger(model);
      final ObjectWriter mapper = Json.pretty();
      String content = mapper.writeValueAsString(swagger);
      final ObjectMapper tempMapper = new ObjectMapper();
      final ObjectNode jsonSchemasDefinitionsNode = this.jsonSchemaGenerator.generateDefinitionsNode(model, templateParam);
      JsonNode _readTree = tempMapper.readTree(content);
      final JsonNode swaggerNode = ((ObjectNode) _readTree).set("definitions", jsonSchemasDefinitionsNode);
      Object _xifexpression = null;
      Object _get = null;
      if (templateParam!=null) {
        _get=templateParam.get(XGenerateSwagger.OUTPUT_FORMAT_PARAM);
      }
      boolean _tripleNotEquals = (_get != null);
      if (_tripleNotEquals) {
        _xifexpression = templateParam.get(XGenerateSwagger.OUTPUT_FORMAT_PARAM);
      } else {
        _xifexpression = this.defaultFormat;
      }
      final Object format = _xifexpression;
      String _string = SwaggerOutputFormat.YAML.toString();
      boolean _equals = Objects.equal(_string, format);
      if (_equals) {
        final ObjectMapper swaggerYamlMapper = Yaml.mapper();
        Object _get_1 = null;
        if (templateParam!=null) {
          _get_1=templateParam.get(XSwaggerGenTemplate.FOLD_MULTILINE);
        }
        final Object foldMultiline = _get_1;
        if (((foldMultiline instanceof Boolean) && (((Boolean) foldMultiline)).booleanValue())) {
          final DumperOptions opts = new DumperOptions();
          opts.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
          final org.yaml.snakeyaml.Yaml yaml = new org.yaml.snakeyaml.Yaml(opts);
          return yaml.dump(new ObjectMapper().convertValue(swaggerNode, Object.class));
        }
        return swaggerYamlMapper.writeValueAsString(swaggerNode);
      } else {
        return tempMapper.writerWithDefaultPrettyPrinter().writeValueAsString(swaggerNode);
      }
    } catch (Throwable _e) {
      throw Exceptions.sneakyThrow(_e);
    }
  }
  
  public Swagger getSwagger(final ZenModel model) {
    final Swagger swagger = new Swagger();
    final Function1 _function = (com.reprezen.rapidml.Extension it) -> {
      return Boolean.valueOf(it.getName().startsWith("openAPI.tags."));
    };
    final Iterable groups = IterableExtensions.filter(((Extensible) model).getExtensions(), _function);
    boolean _isEmpty = IterableExtensions.isEmpty(groups);
    boolean _not = (!_isEmpty);
    if (_not) {
      final Consumer _function_1 = (com.reprezen.rapidml.Extension it) -> {
        final Tag tag = new Tag();
        tag.setName(it.getName().substring(13));
        final String description = it.getValue();
        tag.setDescription(description);
        swagger.addTag(tag);
      };
      groups.forEach(_function_1);
    }
    this.setVendorExtensions(model, swagger);
    boolean _isEmpty_1 = model.getResourceAPIs().isEmpty();
    if (_isEmpty_1) {
      this.addDefaultResourceAPI(model);
    }
    final ResourceAPI resourceAPI = model.getResourceAPIs().get(0);
    String _elvis = null;
    String _baseURI = resourceAPI.getBaseURI();
    if (_baseURI != null) {
      _elvis = _baseURI;
    } else {
      _elvis = "http://localhost";
    }
    final URI uri = URI.create(_elvis);
    String _xifexpression = null;
    if (((uri.getPath() != null) && (!uri.getPath().isEmpty()))) {
      _xifexpression = uri.getPath();
    } else {
      _xifexpression = "/";
    }
    swagger.setBasePath(_xifexpression);
    String _host = uri.getHost();
    String _xifexpression_1 = null;
    int _port = uri.getPort();
    boolean _greaterEqualsThan = (_port >= 0);
    if (_greaterEqualsThan) {
      int _port_1 = uri.getPort();
      _xifexpression_1 = (":" + Integer.valueOf(_port_1));
    } else {
      _xifexpression_1 = "";
    }
    String _plus = (_host + _xifexpression_1);
    swagger.setHost(_plus);
    String _scheme = uri.getScheme();
    boolean _tripleNotEquals = (_scheme != null);
    if (_tripleNotEquals) {
      swagger.addScheme(Scheme.forValue(uri.getScheme()));
    }
    Info _info = new Info();
    swagger.setInfo(_info);
    Info _info_1 = swagger.getInfo();
    String _xifexpression_2 = null;
    boolean _isNullOrEmpty = Strings.isNullOrEmpty(resourceAPI.getVersion());
    boolean _not_1 = (!_isNullOrEmpty);
    if (_not_1) {
      _xifexpression_2 = resourceAPI.getVersion();
    } else {
      _xifexpression_2 = "1.0.0";
    }
    _info_1.setVersion(_xifexpression_2);
    Info _info_2 = swagger.getInfo();
    _info_2.setTitle(resourceAPI.getName());
    Info _info_3 = swagger.getInfo();
    _info_3.setDescription(this._zenModelHelper.getDocumentation(resourceAPI));
    final Consumer _function_2 = (MediaType it) -> {
      swagger.addConsumes(it.getName());
      swagger.addProduces(it.getName());
    };
    resourceAPI.getDefinedMediaTypes().forEach(_function_2);
    final Function1> _function_3 = (ResourceAPI it) -> {
      return it.getOwnedResourceDefinitions();
    };
    final Consumer _function_4 = (ResourceDefinition it) -> {
      final Tag tag = new Tag();
      tag.setName(it.getName());
      tag.setDescription(this._zenModelHelper.getDocumentation(it));
      swagger.addTag(tag);
      String _xifexpression_3 = null;
      com.reprezen.rapidml.URI _uRI = it.getURI();
      boolean _tripleNotEquals_1 = (_uRI != null);
      if (_tripleNotEquals_1) {
        _xifexpression_3 = it.getURI().toString();
      } else {
        _xifexpression_3 = "";
      }
      final String pathUri = ("/" + _xifexpression_3);
      swagger.path(pathUri, this.createSwaggerPath(it));
    };
    Iterables.concat(ListExtensions.>map(model.getResourceAPIs(), _function_3)).forEach(_function_4);
    Map _paths = swagger.getPaths();
    boolean _tripleEquals = (_paths == null);
    if (_tripleEquals) {
      swagger.setPaths(Collections.emptyMap());
    }
    final Consumer _function_5 = (SecurityScheme it) -> {
      swagger.addSecurityDefinition(it.getName(), this.createSecurityScheme(it));
    };
    this.getAllUsedSecuritySchemes(model).forEach(_function_5);
    return swagger;
  }
  
  public ArrayList getAllUsedSecuritySchemes(final ZenModel model) {
    final ArrayList result = Lists.newArrayList();
    SecuritySchemeLibrary _securitySchemesLibrary = model.getSecuritySchemesLibrary();
    boolean _tripleNotEquals = (_securitySchemesLibrary != null);
    if (_tripleNotEquals) {
      result.addAll(model.getSecuritySchemesLibrary().getSecuritySchemes());
    }
    final Function1> _function = (HasSecurityValue it) -> {
      return it.getSecuredBy();
    };
    final Consumer _function_1 = (AuthenticationMethod it) -> {
      result.add(it.getScheme());
    };
    Iterables.concat(ListExtensions.>map(IteratorExtensions.toList(Iterators.filter(model.eAllContents(), HasSecurityValue.class)), _function)).forEach(_function_1);
    return result;
  }
  
  public SecuritySchemeDefinition createSecurityScheme(final SecurityScheme scheme) {
    AuthenticationTypes _type = scheme.getType();
    if (_type != null) {
      switch (_type) {
        case OAUTH2:
          final OAuth2Definition result = new OAuth2Definition();
          this.setVendorExtensions(scheme, result);
          String _switchResult_1 = null;
          AuthenticationFlows _flow = scheme.getFlow();
          if (_flow != null) {
            switch (_flow) {
              case IMPLICIT:
                _switchResult_1 = "implicit";
                break;
              case PASSWORD:
                _switchResult_1 = "password";
                break;
              case APPLICATION:
                _switchResult_1 = "application";
                break;
              case ACCESS_CODE:
                _switchResult_1 = "accessCode";
                break;
              default:
                break;
            }
          }
          result.setFlow(_switchResult_1);
          final Function1 _function = (SecuritySchemeParameter it) -> {
            String _name = it.getName();
            return Boolean.valueOf(Objects.equal(_name, OAuth2Parameters.AUTHORIZATION_URL));
          };
          final SecuritySchemeParameter authorizationUrlSetting = IterableExtensions.findFirst(scheme.getSettings(), _function);
          String _value = null;
          if (authorizationUrlSetting!=null) {
            _value=authorizationUrlSetting.getValue();
          }
          result.setAuthorizationUrl(_value);
          final Function1 _function_1 = (SecuritySchemeParameter it) -> {
            String _name = it.getName();
            return Boolean.valueOf(Objects.equal(_name, OAuth2Parameters.TOKEN_URL));
          };
          final SecuritySchemeParameter tokenUrlSetting = IterableExtensions.findFirst(scheme.getSettings(), _function_1);
          if ((tokenUrlSetting != null)) {
            result.setTokenUrl(tokenUrlSetting.getValue());
          } else {
            final Function1 _function_2 = (SecuritySchemeParameter it) -> {
              String _name = it.getName();
              return Boolean.valueOf(Objects.equal(_name, OAuth2Parameters.ACCESS_TOKEN_URL));
            };
            final SecuritySchemeParameter accessTokenUrlSetting = IterableExtensions.findFirst(scheme.getSettings(), _function_2);
            String _value_1 = null;
            if (accessTokenUrlSetting!=null) {
              _value_1=accessTokenUrlSetting.getValue();
            }
            result.setTokenUrl(_value_1);
          }
          final Consumer _function_3 = (SecurityScope it) -> {
            result.addScope(it.getName(), this._zenModelHelper.getDocumentation(it));
          };
          scheme.getScopes().forEach(_function_3);
          result.setType("oauth2");
          return result;
        case BASIC:
          final BasicAuthDefinition result_1 = new BasicAuthDefinition();
          this.setVendorExtensions(scheme, result_1);
          result_1.setType("basic");
          return result_1;
        case CUSTOM:
          final ApiKeyAuthDefinition result_2 = new ApiKeyAuthDefinition();
          this.setVendorExtensions(scheme, result_2);
          boolean _isEmpty = scheme.getParameters().isEmpty();
          boolean _not = (!_isEmpty);
          if (_not) {
            final MessageParameter param = scheme.getParameters().get(0);
            result_2.setName(param.getName());
            In _xifexpression = null;
            SingleValueType _type_1 = param.getType();
            boolean _equals = Objects.equal(_type_1, HttpMessageParameterLocation.HEADER);
            if (_equals) {
              _xifexpression = In.HEADER;
            } else {
              _xifexpression = In.QUERY;
            }
            final In in = _xifexpression;
            result_2.setIn(in);
          }
          result_2.setType("apiKey");
          return result_2;
        default:
          break;
      }
    }
    return null;
  }
  
  public Path createSwaggerPath(final ResourceDefinition res) {
    final Path path = new Path();
    this.setVendorExtensions(((Extensible) res), path);
    com.reprezen.rapidml.URI _uRI = ((ServiceDataResource) res).getURI();
    boolean _tripleNotEquals = (_uRI != null);
    if (_tripleNotEquals) {
      final Consumer _function = (URIParameter it) -> {
        AbstractSerializableParameter _xifexpression = null;
        if ((it instanceof TemplateParameter)) {
          _xifexpression = new PathParameter();
        } else {
          _xifexpression = new QueryParameter();
        }
        final AbstractSerializableParameter param = _xifexpression;
        param.setDescription(this._zenModelHelper.getDocumentation(it));
        param.setName(it.getName());
        param.setType(this._jsonSchemaHelper.getJSONSchemaTypeName(it.getSourceReference().getType()));
        String _jSONSchemaTypeFormat = this._jsonSchemaHelper.getJSONSchemaTypeFormat(it.getSourceReference().getType());
        boolean _tripleNotEquals_1 = (_jSONSchemaTypeFormat != null);
        if (_tripleNotEquals_1) {
          param.setFormat(this._jsonSchemaHelper.getJSONSchemaTypeFormat(it.getSourceReference().getType()));
        }
        this.setVendorExtensions(it, param);
        boolean _matched = false;
        if (param instanceof PathParameter) {
          _matched=true;
          ((PathParameter)param).setRequired(true);
          ((PathParameter)param).setDefaultValue(it.getDefault());
        }
        if (!_matched) {
          if (param instanceof QueryParameter) {
            _matched=true;
            ((QueryParameter)param).setRequired(it.isRequired());
            ((QueryParameter)param).setDefaultValue(it.getDefault());
          }
        }
        path.addParameter(param);
      };
      ((ServiceDataResource) res).getURI().getUriParameters().forEach(_function);
    }
    final Consumer _function_1 = (Method it) -> {
      this.createSwaggerOperation(path, it);
    };
    res.getMethods().forEach(_function_1);
    return path;
  }
  
  public void createSwaggerOperation(final Path path, final Method method) {
    final Operation operation = new Operation();
    this.setVendorExtensions(method, operation);
    operation.setOperationId(method.getId());
    operation.setDescription(this._zenModelHelper.getDocumentation(method));
    final Function1 _function = (com.reprezen.rapidml.Extension it) -> {
      String _name = it.getName();
      return Boolean.valueOf(Objects.equal(_name, "openAPI.tags"));
    };
    final Iterable groups = IterableExtensions.filter(((Extensible) method).getExtensions(), _function);
    boolean _isEmpty = IterableExtensions.isEmpty(groups);
    boolean _not = (!_isEmpty);
    if (_not) {
      final Consumer _function_1 = (com.reprezen.rapidml.Extension it) -> {
        final Consumer _function_2 = (String tag) -> {
          operation.addTag(tag.trim());
        };
        Splitter.on(",").split(it.getValue()).forEach(_function_2);
      };
      groups.forEach(_function_1);
    } else {
      operation.addTag(method.getContainingResourceDefinition().getName());
    }
    final Consumer _function_2 = (TypedResponse it) -> {
      String _xifexpression = null;
      int _statusCode = it.getStatusCode();
      boolean _greaterThan = (_statusCode > 0);
      if (_greaterThan) {
        _xifexpression = Integer.valueOf(it.getStatusCode()).toString();
      } else {
        _xifexpression = "200";
      }
      operation.addResponse(_xifexpression, this.getResponse(it));
    };
    method.getResponses().forEach(_function_2);
    final Function1> _function_3 = (TypedResponse it) -> {
      return it.getMediaTypes();
    };
    final Function1 _function_4 = (MediaType it) -> {
      return it.getName();
    };
    final Consumer _function_5 = (String it) -> {
      XGenerateSwagger.safeAddProduces(operation, it);
    };
    IterableExtensions.toSet(IterableExtensions.map(Iterables.concat(ListExtensions.>map(method.getResponses(), _function_3)), _function_4)).forEach(_function_5);
    final Function1 _function_6 = (MediaType it) -> {
      return it.getName();
    };
    final Consumer _function_7 = (String it) -> {
      XGenerateSwagger.safeAddConsumes(operation, it);
    };
    IterableExtensions.toSet(ListExtensions.map(method.getRequest().getMediaTypes(), _function_6)).forEach(_function_7);
    final Function1 _function_8 = (MessageParameter it) -> {
      HttpMessageParameterLocation _httpLocation = it.getHttpLocation();
      return Boolean.valueOf((!Objects.equal(_httpLocation, HttpMessageParameterLocation.QUERY)));
    };
    final Consumer _function_9 = (MessageParameter it) -> {
      operation.addParameter(this.getMessageHeaderParameter(it));
    };
    IterableExtensions.filter(method.getRequest().getParameters(), _function_8).forEach(_function_9);
    final Function1 _function_10 = (MessageParameter it) -> {
      HttpMessageParameterLocation _httpLocation = it.getHttpLocation();
      return Boolean.valueOf(Objects.equal(_httpLocation, HttpMessageParameterLocation.QUERY));
    };
    final Consumer _function_11 = (MessageParameter it) -> {
      operation.addParameter(this.getMessageQueryParameter(it));
    };
    IterableExtensions.filter(method.getRequest().getParameters(), _function_10).forEach(_function_11);
    boolean _shouldRetainEmptyParameters = this.shouldRetainEmptyParameters();
    boolean _not_1 = (!_shouldRetainEmptyParameters);
    if (_not_1) {
      boolean _isEmpty_1 = operation.getParameters().isEmpty();
      if (_isEmpty_1) {
        operation.setParameters(null);
      }
    }
    final String requestTypeName = this.getDefinitionName(method.getRequest());
    if ((requestTypeName != null)) {
      final BodyParameter param = new BodyParameter();
      operation.addParameter(param);
      param.setName(requestTypeName);
      param.setDescription("Request body");
      param.setDescription(this.getMessageDocumentation(method.getRequest()));
      param.setSchema(this.getReferenceToType(requestTypeName));
      this.setVendorExtensions(method.getRequest(), param);
      param.setRequired(true);
    }
    String _name = method.getHttpMethod().getName();
    if (_name != null) {
      switch (_name) {
        case "GET":
          path.setGet(operation);
          break;
        case "POST":
          path.setPost(operation);
          break;
        case "PUT":
          path.setPut(operation);
          break;
        case "DELETE":
          path.setDelete(operation);
          break;
        case "OPTIONS":
          path.setOptions(operation);
          break;
        case "PATCH":
          path.setPatch(operation);
          break;
      }
    }
    final Consumer _function_12 = (AuthenticationMethod it) -> {
      final Function1 _function_13 = (SecurityScope it_1) -> {
        return it_1.getName();
      };
      operation.addSecurity(it.getScheme().getName(), ListExtensions.map(it.getScopes(), _function_13));
    };
    method.getSecuredBy().forEach(_function_12);
  }
  
  /**
   * @returns creates Swagger Response from ZEN TypedResponse
   */
  public Response getResponse(final TypedResponse rapidResponse) {
    final Response swaggerResponse = new Response();
    this.setVendorExtensions(((Extensible) rapidResponse), swaggerResponse);
    final Example example = IterableExtensions.head(rapidResponse.getAllExamples());
    if (((example != null) && (example.getBody() != null))) {
      final MediaType type = IterableExtensions.head(rapidResponse.getMediaTypes());
      if ((type != null)) {
        swaggerResponse.example(IterableExtensions.head(rapidResponse.getMediaTypes()).getName(), this.renderExample(example.getBody(), type.getName()));
      }
    }
    final String typeName = this.getDefinitionName(rapidResponse);
    swaggerResponse.setDescription(this.getMessageDocumentation(rapidResponse));
    if ((typeName != null)) {
      final RefProperty property = new RefProperty();
      property.set$ref(("#/definitions/" + typeName));
      swaggerResponse.setSchema(property);
    }
    final Consumer _function = (MessageParameter it) -> {
      Map _headers = swaggerResponse.getHeaders();
      boolean _tripleEquals = (_headers == null);
      if (_tripleEquals) {
        HashMap _hashMap = new HashMap();
        swaggerResponse.setHeaders(_hashMap);
      }
      boolean _isArrayProperty = this._jsonSchemaHelper.isArrayProperty(it);
      if (_isArrayProperty) {
        final ArrayProperty prop = new ArrayProperty();
        prop.setItems(this.createSwaggerPropertyWithConstraints(it));
        prop.setDescription(this._zenModelHelper.getDocumentation(it));
        swaggerResponse.getHeaders().put(it.getName(), prop);
      } else {
        final Property prop_1 = this.createSwaggerPropertyWithConstraints(it);
        prop_1.setDescription(this._zenModelHelper.getDocumentation(it));
        swaggerResponse.getHeaders().put(it.getName(), prop_1);
      }
    };
    rapidResponse.getParameters().forEach(_function);
    return swaggerResponse;
  }
  
  private Object renderExample(final String example, final String type) {
    Object _switchResult = null;
    if (type != null) {
      switch (type) {
        case "application/json":
          _switchResult = this.getJsonExample(example);
          break;
        default:
          _switchResult = example;
          break;
      }
    } else {
      _switchResult = example;
    }
    return _switchResult;
  }
  
  private final static ObjectMapper jsonMapper = new ObjectMapper();
  
  private final static ObjectMapper yamlMapper = new ObjectMapper(new YAMLFactory());
  
  private Object getJsonExample(final String example) {
    try {
      return XGenerateSwagger.jsonMapper.readTree(example);
    } catch (final Throwable _t) {
      if (_t instanceof IOException) {
      } else {
        throw Exceptions.sneakyThrow(_t);
      }
    }
    try {
      return XGenerateSwagger.yamlMapper.readTree(this.removeIndentation(example));
    } catch (final Throwable _t_1) {
      if (_t_1 instanceof Exception) {
      } else {
        throw Exceptions.sneakyThrow(_t_1);
      }
    }
    return example;
  }
  
  private String removeIndentation(final String text) {
    String[] lines = text.split("(?m)^");
    final String[] _converted_lines = (String[])lines;
    final Function1 _function = (String it) -> {
      return Boolean.valueOf(it.trim().isEmpty());
    };
    lines = ((String[])Conversions.unwrapArray(IterableExtensions.dropWhile(((Iterable)Conversions.doWrapArray(_converted_lines)), _function), String.class));
    final String[] _converted_lines_1 = (String[])lines;
    final Function1 _function_1 = (String it) -> {
      return Boolean.valueOf(it.trim().isEmpty());
    };
    lines = ((String[])Conversions.unwrapArray(ListExtensions.reverse(IterableExtensions.toList(IterableExtensions.dropWhile(ListExtensions.reverse(((List)Conversions.doWrapArray(_converted_lines_1))), _function_1))), String.class));
    final String[] _converted_lines_2 = (String[])lines;
    final String indent = this.findIndent(IterableExtensions.head(((Iterable)Conversions.doWrapArray(_converted_lines_2))));
    final String[] _converted_lines_3 = (String[])lines;
    final Function1 _function_2 = (String it) -> {
      return Boolean.valueOf(it.startsWith(indent));
    };
    boolean _forall = IterableExtensions.forall(((Iterable)Conversions.doWrapArray(_converted_lines_3)), _function_2);
    if (_forall) {
      final String[] _converted_lines_4 = (String[])lines;
      final Function1 _function_3 = (String it) -> {
        return it.substring(indent.length());
      };
      return IterableExtensions.join(ListExtensions.map(((List)Conversions.doWrapArray(_converted_lines_4)), _function_3), "\n");
    } else {
      return text;
    }
  }
  
  private String findIndent(final String line) {
    if ((line != null)) {
      int _length = line.length();
      ExclusiveRange _doubleDotLessThan = new ExclusiveRange(0, _length, true);
      for (final Integer i : _doubleDotLessThan) {
        int _indexOf = " \t".indexOf(line.charAt((i).intValue()));
        boolean _lessThan = (_indexOf < 0);
        if (_lessThan) {
          return line.substring(0, (i).intValue());
        }
      }
    }
    return line;
  }
  
  public String getMessageDocumentation(final TypedMessage message) {
    String result = this._zenModelHelper.getDocumentation(message);
    boolean _isNullOrEmpty = StringExtensions.isNullOrEmpty(result);
    if (_isNullOrEmpty) {
      Structure _xifexpression = null;
      Structure _actualType = message.getActualType();
      boolean _tripleNotEquals = (_actualType != null);
      if (_tripleNotEquals) {
        _xifexpression = message.getActualType();
      } else {
        Structure _xifexpression_1 = null;
        ResourceDefinition _resourceType = message.getResourceType();
        if ((_resourceType instanceof ServiceDataResource)) {
          ResourceDefinition _resourceType_1 = message.getResourceType();
          _xifexpression_1 = ((ServiceDataResource) _resourceType_1).getDataType();
        }
        _xifexpression = _xifexpression_1;
      }
      final Structure dataType = _xifexpression;
      if ((dataType != null)) {
        result = this._zenModelHelper.getDocumentation(dataType);
      }
    }
    return result;
  }
  
  public String getDefinitionName(final TypedMessage message) {
    if ((message == null)) {
      return null;
    }
    String _xifexpression = null;
    Structure _actualType = message.getActualType();
    boolean _tripleNotEquals = (_actualType != null);
    if (_tripleNotEquals) {
      _xifexpression = this.jsonSchemaGenerator.getDefinitionName(message);
    } else {
      String _xifexpression_1 = null;
      ResourceDefinition _resourceType = message.getResourceType();
      boolean _tripleNotEquals_1 = (_resourceType != null);
      if (_tripleNotEquals_1) {
        ResourceDefinition _resourceType_1 = message.getResourceType();
        _xifexpression_1 = this.jsonSchemaGenerator.getDefinitionName(((ServiceDataResource) _resourceType_1));
      } else {
        _xifexpression_1 = null;
      }
      _xifexpression = _xifexpression_1;
    }
    String typeName = _xifexpression;
    return typeName;
  }
  
  public Model getReferenceToType(final String typeName) {
    RefModel _xblockexpression = null;
    {
      final RefModel ref = new RefModel();
      ref.set$ref(("#/definitions/" + typeName));
      _xblockexpression = ref;
    }
    return _xblockexpression;
  }
  
  public Property createSwaggerPropertyWithConstraints(final MessageParameter parameter) {
    Property _xblockexpression = null;
    {
      final SourceReference sourceReference = parameter.getSourceReference();
      final Property prop = this.getSwaggerProperty(sourceReference.getType().getName());
      this.setConstraints(prop, this.getMessageParameterConstraints(parameter));
      _xblockexpression = prop;
    }
    return _xblockexpression;
  }
  
  public Property getSwaggerProperty(final String typeName) {
    AbstractProperty _switchResult = null;
    boolean _matched = false;
    boolean _contains = Collections.unmodifiableList(CollectionLiterals.newArrayList("anyURI", "duration", "gMonth", "gMonthDay", "gDay", "gYearMonth", "gYear", "QName", "time", "string", "NCName")).contains(typeName);
    if (_contains) {
      _matched=true;
      _switchResult = new StringProperty();
    }
    if (!_matched) {
      if (Objects.equal(typeName, "boolean")) {
        _matched=true;
        _switchResult = new BooleanProperty();
      }
    }
    if (!_matched) {
      if (Objects.equal(typeName, "date")) {
        _matched=true;
        _switchResult = new DateProperty();
      }
    }
    if (!_matched) {
      if (Objects.equal(typeName, "dateTime")) {
        _matched=true;
        _switchResult = new DateTimeProperty();
      }
    }
    if (!_matched) {
      if (Objects.equal(typeName, "decimal")) {
        _matched=true;
        _switchResult = new DecimalProperty();
      }
    }
    if (!_matched) {
      if (Objects.equal(typeName, "double")) {
        _matched=true;
        _switchResult = new DoubleProperty();
      }
    }
    if (!_matched) {
      if (Objects.equal(typeName, "float")) {
        _matched=true;
        _switchResult = new FloatProperty();
      }
    }
    if (!_matched) {
      if (Objects.equal(typeName, "integer")) {
        _matched=true;
        _switchResult = new IntegerProperty();
      }
    }
    if (!_matched) {
      if (Objects.equal(typeName, "int")) {
        _matched=true;
        _switchResult = new IntegerProperty();
      }
    }
    if (!_matched) {
      if (Objects.equal(typeName, "long")) {
        _matched=true;
        _switchResult = new LongProperty();
      }
    }
    if (!_matched) {
      RefProperty _xblockexpression = null;
      {
        final RefProperty prop = new RefProperty();
        prop.set$ref(("#/definitions/" + typeName));
        _xblockexpression = prop;
      }
      _switchResult = _xblockexpression;
    }
    return _switchResult;
  }
  
  public void setConstraints(final Property property, final List constraints) {
    if (((constraints == null) || constraints.isEmpty())) {
      return;
    }
    boolean _matched = false;
    if (property instanceof StringProperty) {
      _matched=true;
      final Consumer _function = (LengthConstraint it) -> {
        boolean _isSetMinLength = it.isSetMinLength();
        if (_isSetMinLength) {
          ((StringProperty)property).setMinLength(Integer.valueOf(it.getMinLength()));
        }
        boolean _isSetMaxLength = it.isSetMaxLength();
        if (_isSetMaxLength) {
          ((StringProperty)property).setMaxLength(Integer.valueOf(it.getMaxLength()));
        }
      };
      Iterables.filter(constraints, LengthConstraint.class).forEach(_function);
      final Consumer _function_1 = (RegExConstraint it) -> {
        ((StringProperty)property).setPattern(it.getPattern());
      };
      Iterables.filter(constraints, RegExConstraint.class).forEach(_function_1);
    }
    if (!_matched) {
      if (property instanceof AbstractNumericProperty) {
        _matched=true;
        final Consumer _function = (ValueRangeConstraint it) -> {
          String _minValue = it.getMinValue();
          boolean _tripleNotEquals = (_minValue != null);
          if (_tripleNotEquals) {
            String _minValue_1 = it.getMinValue();
            BigDecimal _bigDecimal = new BigDecimal(_minValue_1);
            ((AbstractNumericProperty)property).setMinimum(_bigDecimal);
            ((AbstractNumericProperty)property).setExclusiveMinimum(Boolean.valueOf(it.isMinValueExclusive()));
          }
          String _maxValue = it.getMaxValue();
          boolean _tripleNotEquals_1 = (_maxValue != null);
          if (_tripleNotEquals_1) {
            String _maxValue_1 = it.getMaxValue();
            BigDecimal _bigDecimal_1 = new BigDecimal(_maxValue_1);
            ((AbstractNumericProperty)property).setMaximum(_bigDecimal_1);
            ((AbstractNumericProperty)property).setExclusiveMaximum(Boolean.valueOf(it.isMaxValueExclusive()));
          }
        };
        Iterables.filter(constraints, ValueRangeConstraint.class).forEach(_function);
      }
    }
  }
  
  public HeaderParameter getMessageHeaderParameter(final MessageParameter parameter) {
    final HeaderParameter swaggerParameter = new HeaderParameter();
    boolean _isArrayProperty = this._jsonSchemaHelper.isArrayProperty(parameter);
    if (_isArrayProperty) {
      final Property items = this.createSwaggerPropertyWithConstraints(parameter);
      ArrayProperty _arrayProperty = new ArrayProperty(items);
      swaggerParameter.setProperty(_arrayProperty);
    } else {
      swaggerParameter.setProperty(this.createSwaggerPropertyWithConstraints(parameter));
    }
    swaggerParameter.setDescription(this._zenModelHelper.getDocumentation(parameter));
    swaggerParameter.setName(parameter.getName());
    swaggerParameter.setRequired(parameter.isRequired());
    this.setVendorExtensions(parameter, swaggerParameter);
    return swaggerParameter;
  }
  
  private void setVendorExtensions(final Extensible rapidElement, final Swagger swaggerObj) {
    final Iterable extensions = this._extensionsHelper.getRapidExtensions(rapidElement);
    final Consumer _function = (com.reprezen.rapidml.Extension it) -> {
      swaggerObj.setVendorExtension(it.getName(), it.getValue());
    };
    extensions.forEach(_function);
  }
  
  private void setVendorExtensions(final Extensible rapidElement, final Path swaggerObj) {
    final Iterable extensions = this._extensionsHelper.getRapidExtensions(rapidElement);
    final Consumer _function = (com.reprezen.rapidml.Extension it) -> {
      swaggerObj.setVendorExtension(it.getName(), it.getValue());
    };
    extensions.forEach(_function);
  }
  
  private void setVendorExtensions(final Extensible rapidElement, final Operation swaggerObj) {
    final Iterable extensions = this._extensionsHelper.getRapidExtensions(rapidElement);
    final Consumer _function = (com.reprezen.rapidml.Extension it) -> {
      swaggerObj.setVendorExtension(it.getName(), it.getValue());
    };
    extensions.forEach(_function);
  }
  
  private void setVendorExtensions(final Extensible rapidElement, final AbstractParameter swaggerObj) {
    final Iterable extensions = this._extensionsHelper.getRapidExtensions(rapidElement);
    final Consumer _function = (com.reprezen.rapidml.Extension it) -> {
      swaggerObj.setVendorExtension(it.getName(), it.getValue());
    };
    extensions.forEach(_function);
  }
  
  private void setVendorExtensions(final Extensible rapidElement, final Response swaggerObj) {
    final Iterable extensions = this._extensionsHelper.getRapidExtensions(rapidElement);
    final Consumer _function = (com.reprezen.rapidml.Extension it) -> {
      swaggerObj.setVendorExtension(it.getName(), it.getValue());
    };
    extensions.forEach(_function);
  }
  
  private void setVendorExtensions(final Extensible rapidElement, final SecuritySchemeDefinition swaggerObj) {
    final Iterable extensions = this._extensionsHelper.getRapidExtensions(rapidElement);
    final Consumer _function = (com.reprezen.rapidml.Extension it) -> {
      swaggerObj.setVendorExtension(it.getName(), it.getValue());
    };
    extensions.forEach(_function);
  }
  
  public QueryParameter getMessageQueryParameter(final MessageParameter parameter) {
    final QueryParameter swaggerParameter = new QueryParameter();
    boolean _isArrayProperty = this._jsonSchemaHelper.isArrayProperty(parameter);
    if (_isArrayProperty) {
      final Property items = this.createSwaggerPropertyWithConstraints(parameter);
      ArrayProperty _arrayProperty = new ArrayProperty(items);
      swaggerParameter.setProperty(_arrayProperty);
    } else {
      swaggerParameter.setProperty(this.createSwaggerPropertyWithConstraints(parameter));
    }
    swaggerParameter.setDescription(this._zenModelHelper.getDocumentation(parameter));
    swaggerParameter.setName(parameter.getName());
    swaggerParameter.setRequired(parameter.isRequired());
    this.setVendorExtensions(parameter, swaggerParameter);
    return swaggerParameter;
  }
  
  public List getMessageParameterConstraints(final MessageParameter parameter) {
    final SourceReference ref = parameter.getSourceReference();
    boolean _matched = false;
    if (ref instanceof PropertyReference) {
      _matched=true;
      final Function1 _function = (PropertyRealization it) -> {
        Feature _baseProperty = it.getBaseProperty();
        PrimitiveProperty _conceptualFeature = ((PropertyReference)ref).getConceptualFeature();
        return Boolean.valueOf(Objects.equal(_baseProperty, _conceptualFeature));
      };
      PropertyRealization property = IterableExtensions.findFirst(parameter.getContainingMessage().getIncludedProperties(), _function);
      if ((property == null)) {
        return ((PropertyReference)ref).getConceptualFeature().getAllConstraints();
      }
      return property.getAllConstraints();
    }
    return null;
  }
  
  public boolean addDefaultResourceAPI(final ZenModel model) {
    boolean _xblockexpression = false;
    {
      final ResourceAPI resourceAPI = RapidmlFactory.eINSTANCE.createResourceAPI();
      resourceAPI.setBaseURI("http://localhost");
      resourceAPI.setName(model.getName());
      _xblockexpression = model.getResourceAPIs().add(resourceAPI);
    }
    return _xblockexpression;
  }
  
  private boolean shouldRetainEmptyParameters() {
    Map _genTargetParameters = null;
    if (this.context!=null) {
      _genTargetParameters=this.context.getGenTargetParameters();
    }
    Object _get = null;
    if (_genTargetParameters!=null) {
      _get=_genTargetParameters.get(XGenerateSwagger.OPTION_RETAIN_EMPTY_PARAMATERS);
    }
    final Object option = _get;
    Boolean _xifexpression = null;
    if ((option instanceof Boolean)) {
      _xifexpression = ((Boolean) option);
    } else {
      boolean _xifexpression_1 = false;
      if ((option == null)) {
        _xifexpression_1 = false;
      } else {
        String _format = String.format("Only boolean values are allowed for \'%s\', current value is of type %s", 
          XGenerateSwagger.OPTION_RETAIN_EMPTY_PARAMATERS, option.getClass().getSimpleName());
        throw new IllegalArgumentException(_format);
      }
      _xifexpression = Boolean.valueOf(_xifexpression_1);
    }
    return (_xifexpression).booleanValue();
  }
  
  private static void safeAddConsumes(final Operation op, final String mediaType) {
    if (((op.getConsumes() == null) || (!op.getConsumes().contains(mediaType)))) {
      op.addConsumes(mediaType);
    }
  }
  
  private static void safeAddProduces(final Operation op, final String mediaType) {
    if (((op.getProduces() == null) || (!op.getProduces().contains(mediaType)))) {
      op.addProduces(mediaType);
    }
  }
}