@Test
  public void resolveInlineArrayModel() throws Exception {
    Swagger swagger = new Swagger();

    swagger.addDefinition(
        "User",
        new ArrayModel()
            .items(
                new ObjectProperty()
                    .title("title")
                    ._default("default")
                    .access("access")
                    .readOnly(false)
                    .required(true)
                    .description("description")
                    .name("name")
                    .property("street", new StringProperty())
                    .property("city", new StringProperty())));

    new InlineModelResolver().flatten(swagger);

    Model model = swagger.getDefinitions().get("User");
    assertTrue(model instanceof ArrayModel);

    Model user = swagger.getDefinitions().get("User_inner");
    assertNotNull(user);
    assertEquals("description", user.getDescription());
  }
  @Test
  public void resolveInlineModelTest() throws Exception {
    Swagger swagger = new Swagger();

    swagger.addDefinition(
        "User",
        new ModelImpl()
            .name("user")
            .description("a common user")
            .property("name", new StringProperty())
            .property(
                "address",
                new ObjectProperty()
                    .title("title")
                    ._default("default")
                    .access("access")
                    .readOnly(false)
                    .required(true)
                    .description("description")
                    .name("name")
                    .property("street", new StringProperty())
                    .property("city", new StringProperty())));

    new InlineModelResolver().flatten(swagger);

    ModelImpl user = (ModelImpl) swagger.getDefinitions().get("User");

    assertNotNull(user);
    assertTrue(user.getProperties().get("address") instanceof RefProperty);

    ModelImpl address = (ModelImpl) swagger.getDefinitions().get("User_address");
    assertNotNull(address);
    assertNotNull(address.getProperties().get("city"));
    assertNotNull(address.getProperties().get("street"));
  }
  private Model asModel(String typeName, Swagger swagger) {
    boolean array = typeName.endsWith("[]");
    if (array) {
      typeName = typeName.substring(0, typeName.length() - 2);
    }

    if (swagger.getDefinitions() != null) {
      for (Model model : swagger.getDefinitions().values()) {
        StringProperty modelType = (StringProperty) model.getVendorExtensions().get("x-className");
        if (modelType != null && typeName.equals(modelType.getFormat())) {
          return model;
        }
      }
    }
    return null;
  }
  @Test
  public void testInlineMapResponse() throws Exception {
    Swagger swagger = new Swagger();

    MapProperty schema = new MapProperty();
    schema.setAdditionalProperties(new StringProperty());

    swagger.path(
        "/foo/baz",
        new Path()
            .get(
                new Operation()
                    .response(
                        200,
                        new Response()
                            .vendorExtension("x-foo", "bar")
                            .description("it works!")
                            .schema(schema))));
    new InlineModelResolver().flatten(swagger);
    Json.prettyPrint(swagger);

    Response response = swagger.getPaths().get("/foo/baz").getGet().getResponses().get("200");

    Property property = response.getSchema();
    assertTrue(property instanceof MapProperty);
    assertTrue(swagger.getDefinitions().size() == 0);
  }
  @Test
  public void resolveInlineBodyParameter() throws Exception {
    Swagger swagger = new Swagger();

    swagger.path(
        "/hello",
        new Path()
            .get(
                new Operation()
                    .parameter(
                        new BodyParameter()
                            .name("body")
                            .schema(
                                new ModelImpl()
                                    .property(
                                        "address",
                                        new ObjectProperty()
                                            .property("street", new StringProperty()))
                                    .property("name", new StringProperty())))));

    new InlineModelResolver().flatten(swagger);

    Operation operation = swagger.getPaths().get("/hello").getGet();
    BodyParameter bp = (BodyParameter) operation.getParameters().get(0);
    assertTrue(bp.getSchema() instanceof RefModel);

    Model body = swagger.getDefinitions().get("body");
    assertTrue(body instanceof ModelImpl);

    ModelImpl impl = (ModelImpl) body;
    assertNotNull(impl.getProperties().get("address"));
  }
Exemple #6
0
 private void locateReferencedDefinitions(
     String ref, Set<String> nestedReferencedDefinitions, Swagger swagger) {
   // if not already processed so as to avoid infinite loops
   if (!nestedReferencedDefinitions.contains(ref)) {
     nestedReferencedDefinitions.add(ref);
     Model model = swagger.getDefinitions().get(ref);
     if (model != null) {
       locateReferencedDefinitions(model.getProperties(), nestedReferencedDefinitions, swagger);
     }
   }
 }
  @Test(description = "returns NSData when response format is binary")
  public void binaryDataTest() {
    final Swagger model = new SwaggerParser().read("src/test/resources/2_0/binaryDataTest.json");
    final DefaultCodegen codegen = new SwiftCodegen();
    final String path = "/tests/binaryResponse";
    final Operation p = model.getPaths().get(path).getPost();
    final CodegenOperation op = codegen.fromOperation(path, "post", p, model.getDefinitions());

    Assert.assertEquals(op.returnType, "NSData");
    Assert.assertEquals(op.bodyParam.dataType, "NSData");
    Assert.assertTrue(op.bodyParam.isBinary);
    Assert.assertTrue(op.responses.get(0).isBinary);
  }
  private void assertSwagger(Swagger swagger) {
    assertEquals("/", swagger.getBasePath());

    assertEquals(INFO_DESCRIPTION, swagger.getInfo().getDescription());
    assertEquals(INFO_TERMS_OF_SERVICE, swagger.getInfo().getTermsOfService());

    // excluded prefixes
    assertNull(swagger.getPath(ServiceUriPaths.CORE_AUTHZ_USERS));
    assertNull(swagger.getPath(ServiceUriPaths.CORE_AUTHZ_ROLES));

    assertNotNull(swagger.getPath(ServiceUriPaths.CORE_PROCESSES));
    assertNotNull(swagger.getPath(ServiceUriPaths.CORE_CREDENTIALS));

    Path p = swagger.getPath("/cars");
    assertNotNull(p);
    assertNotNull(p.getPost());
    assertNotNull(p.getGet());

    assertNotNull(swagger.getPath("/cars/template"));
    assertNotNull(swagger.getPath("/cars/available"));
    assertNotNull(swagger.getPath("/cars/config"));
    assertNotNull(swagger.getPath("/cars/stats"));
    assertNotNull(swagger.getPath("/cars/subscriptions"));

    assertNotNull(swagger.getPath("/cars/{id}/template"));
    assertNotNull(swagger.getPath("/cars/{id}/available"));
    assertNotNull(swagger.getPath("/cars/{id}/config"));
    assertNotNull(swagger.getPath("/cars/{id}/stats"));
    assertNotNull(swagger.getPath("/cars/{id}/subscriptions"));

    p = swagger.getPath("/cars/{id}");
    assertNotNull(p);
    assertNull(p.getPost());
    assertNull(p.getPatch());
    assertNotNull(p.getGet());
    assertNotNull(p.getPut());

    p = swagger.getPath("/tokens");
    assertNotNull(p);
    assertNotNull(p.getGet());
    assertNotNull(p.getGet().getResponses());
    assertNotNull(p.getPost());
    assertNotNull(p.getPost().getParameters());
    assertNull(p.getPatch());
    assertNull(p.getDelete());

    Model model = swagger.getDefinitions().get(Utils.buildKind(UserToken.class));
    Map<String, Property> properties = model.getProperties();
    assertNull(properties.get(UserToken.FIELD_NAME_INTERNAL_ID));
  }
  @Test
  public void resolveInlineArrayBodyParameter() throws Exception {
    Swagger swagger = new Swagger();

    swagger.path(
        "/hello",
        new Path()
            .get(
                new Operation()
                    .parameter(
                        new BodyParameter()
                            .name("body")
                            .schema(
                                new ArrayModel()
                                    .items(
                                        new ObjectProperty()
                                            .property(
                                                "address",
                                                new ObjectProperty()
                                                    .property("street", new StringProperty())))))));

    new InlineModelResolver().flatten(swagger);

    Parameter param = swagger.getPaths().get("/hello").getGet().getParameters().get(0);
    assertTrue(param instanceof BodyParameter);

    BodyParameter bp = (BodyParameter) param;
    Model schema = bp.getSchema();

    assertTrue(schema instanceof ArrayModel);

    ArrayModel am = (ArrayModel) schema;
    Property inner = am.getItems();

    ObjectProperty op = (ObjectProperty) inner;
    Property name = op.getProperties().get("address");
    assertTrue(name instanceof RefProperty);

    Model model = swagger.getDefinitions().get("hello_address");
    assertNotNull(model);
  }
  @Test
  public void testInlineResponseModel() throws Exception {
    Swagger swagger = new Swagger();

    swagger
        .path(
            "/foo/bar",
            new Path()
                .get(
                    new Operation()
                        .response(
                            200,
                            new Response()
                                .description("it works!")
                                .schema(
                                    new ObjectProperty().property("name", new StringProperty())))))
        .path(
            "/foo/baz",
            new Path()
                .get(
                    new Operation()
                        .response(
                            200,
                            new Response()
                                .vendorExtension("x-foo", "bar")
                                .description("it works!")
                                .schema(
                                    new ObjectProperty().property("name", new StringProperty())))));
    new InlineModelResolver().flatten(swagger);

    Map<String, Response> responses = swagger.getPaths().get("/foo/bar").getGet().getResponses();

    Response response = responses.get("200");
    assertNotNull(response);
    assertTrue(response.getSchema() instanceof RefProperty);

    ModelImpl model = (ModelImpl) swagger.getDefinitions().get("inline_response_200");
    assertTrue(model.getProperties().size() == 1);
    assertNotNull(model.getProperties().get("name"));
  }
  @Test
  public void testInlineMapResponseWithObjectProperty() throws Exception {
    Swagger swagger = new Swagger();

    MapProperty schema = new MapProperty();
    schema.setAdditionalProperties(new ObjectProperty().property("name", new StringProperty()));

    swagger.path(
        "/foo/baz",
        new Path()
            .get(
                new Operation()
                    .response(
                        200,
                        new Response()
                            .vendorExtension("x-foo", "bar")
                            .description("it works!")
                            .schema(schema))));
    new InlineModelResolver().flatten(swagger);

    Response response = swagger.getPaths().get("/foo/baz").getGet().getResponses().get("200");

    Property property = response.getSchema();
    assertTrue(property instanceof RefProperty);

    Model inline = swagger.getDefinitions().get("inline_response_200");
    assertTrue(inline instanceof ModelImpl);
    ModelImpl impl = (ModelImpl) inline;

    Property innerProperty = impl.getAdditionalProperties();
    assertTrue(innerProperty instanceof ObjectProperty);

    ObjectProperty obj = (ObjectProperty) innerProperty;
    Property name = obj.getProperties().get("name");
    assertTrue(name instanceof StringProperty);
  }
Exemple #12
0
  public Swagger filter(
      Swagger swagger,
      SwaggerSpecFilter filter,
      Map<String, List<String>> params,
      Map<String, String> cookies,
      Map<String, List<String>> headers) {
    Swagger clone = new Swagger();
    clone
        .info(swagger.getInfo())
        .tags(swagger.getTags() == null ? null : new ArrayList<Tag>(swagger.getTags()))
        .host(swagger.getHost())
        .basePath(swagger.getBasePath())
        .schemes(swagger.getSchemes())
        .consumes(swagger.getConsumes())
        .produces(swagger.getProduces())
        .externalDocs(swagger.getExternalDocs())
        .vendorExtensions(swagger.getVendorExtensions());

    final Set<String> filteredTags = new HashSet<String>();
    final Set<String> allowedTags = new HashSet<String>();
    for (String resourcePath : swagger.getPaths().keySet()) {
      Path path = swagger.getPaths().get(resourcePath);
      Map<String, Operation> ops = new HashMap<String, Operation>();
      ops.put("get", path.getGet());
      ops.put("put", path.getPut());
      ops.put("post", path.getPost());
      ops.put("delete", path.getDelete());
      ops.put("patch", path.getPatch());
      ops.put("options", path.getOptions());

      Path clonedPath = new Path();
      for (String key : ops.keySet()) {
        Operation op = ops.get(key);
        if (op != null) {
          ApiDescription desc = new ApiDescription(resourcePath, key);
          final Set<String> tags;
          if (filter.isOperationAllowed(op, desc, params, cookies, headers)) {
            clonedPath.set(key, filterOperation(filter, op, desc, params, cookies, headers));
            tags = allowedTags;
          } else {
            tags = filteredTags;
          }
          if (op.getTags() != null) {
            tags.addAll(op.getTags());
          }
        }
      }
      if (!clonedPath.isEmpty()) {
        clone.path(resourcePath, clonedPath);
      }
    }
    final List<Tag> tags = clone.getTags();
    filteredTags.removeAll(allowedTags);
    if (tags != null && !filteredTags.isEmpty()) {
      for (Iterator<Tag> it = tags.iterator(); it.hasNext(); ) {
        if (filteredTags.contains(it.next().getName())) {
          it.remove();
        }
      }
      if (clone.getTags().isEmpty()) {
        clone.setTags(null);
      }
    }

    Map<String, Model> definitions =
        filterDefinitions(filter, swagger.getDefinitions(), params, cookies, headers);
    clone.setSecurityDefinitions(swagger.getSecurityDefinitions());
    clone.setDefinitions(definitions);

    // isRemovingUnreferencedDefinitions is not defined in SwaggerSpecFilter to avoid breaking
    // compatibility with
    // existing client filters directly implementing SwaggerSpecFilter.
    if (filter instanceof AbstractSpecFilter) {
      if (((AbstractSpecFilter) filter).isRemovingUnreferencedDefinitions()) {
        clone = removeBrokenReferenceDefinitions(clone);
      }
    }

    return clone;
  }
Exemple #13
0
  private Swagger removeBrokenReferenceDefinitions(Swagger swagger) {

    if (swagger.getDefinitions() == null || swagger.getDefinitions().isEmpty()) return swagger;

    Set<String> referencedDefinitions = new TreeSet<String>();

    if (swagger.getResponses() != null) {
      for (Response response : swagger.getResponses().values()) {
        String propertyRef = getPropertyRef(response.getSchema());
        if (propertyRef != null) {
          referencedDefinitions.add(propertyRef);
        }
      }
    }
    if (swagger.getParameters() != null) {
      for (Parameter p : swagger.getParameters().values()) {
        if (p instanceof BodyParameter) {
          BodyParameter bp = (BodyParameter) p;
          Set<String> modelRef = getModelRef(bp.getSchema());
          if (modelRef != null) {
            referencedDefinitions.addAll(modelRef);
          }
        }
      }
    }
    if (swagger.getPaths() != null) {
      for (Path path : swagger.getPaths().values()) {
        if (path.getParameters() != null) {
          for (Parameter p : path.getParameters()) {
            if (p instanceof BodyParameter) {
              BodyParameter bp = (BodyParameter) p;
              Set<String> modelRef = getModelRef(bp.getSchema());
              if (modelRef != null) {
                referencedDefinitions.addAll(modelRef);
              }
            }
          }
        }
        if (path.getOperations() != null) {
          for (Operation op : path.getOperations()) {
            if (op.getResponses() != null) {
              for (Response response : op.getResponses().values()) {
                String propertyRef = getPropertyRef(response.getSchema());
                if (propertyRef != null) {
                  referencedDefinitions.add(propertyRef);
                }
              }
            }
            if (op.getParameters() != null) {
              for (Parameter p : op.getParameters()) {
                if (p instanceof BodyParameter) {
                  BodyParameter bp = (BodyParameter) p;
                  Set<String> modelRef = getModelRef(bp.getSchema());
                  if (modelRef != null) {
                    referencedDefinitions.addAll(modelRef);
                  }
                }
              }
            }
          }
        }
      }
    }

    if (swagger.getDefinitions() != null) {
      Set<String> nestedReferencedDefinitions = new TreeSet<String>();
      for (String ref : referencedDefinitions) {
        locateReferencedDefinitions(ref, nestedReferencedDefinitions, swagger);
      }
      referencedDefinitions.addAll(nestedReferencedDefinitions);
      swagger.getDefinitions().keySet().retainAll(referencedDefinitions);
    }

    return swagger;
  }
  public void processOperation(
      String resourcePath,
      String httpMethod,
      Operation operation,
      Map<String, List<CodegenOperation>> operations,
      Path path) {
    if (operation != null) {
      if (System.getProperty("debugOperations") != null) {
        LOGGER.debug(
            "processOperation: resourcePath= "
                + resourcePath
                + "\t;"
                + httpMethod
                + " "
                + operation
                + "\n");
      }
      List<String> tags = operation.getTags();
      if (tags == null) {
        tags = new ArrayList<String>();
        tags.add("default");
      }

      /*
       build up a set of parameter "ids" defined at the operation level
       per the swagger 2.0 spec "A unique parameter is defined by a combination of a name and location"
        i'm assuming "location" == "in"
      */
      Set<String> operationParameters = new HashSet<String>();
      if (operation.getParameters() != null) {
        for (Parameter parameter : operation.getParameters()) {
          operationParameters.add(generateParameterId(parameter));
        }
      }

      // need to propagate path level down to the operation
      if (path.getParameters() != null) {
        for (Parameter parameter : path.getParameters()) {
          // skip propagation if a parameter with the same name is already defined at the operation
          // level
          if (!operationParameters.contains(generateParameterId(parameter))) {
            operation.addParameter(parameter);
          }
        }
      }

      for (String tag : tags) {
        CodegenOperation co = null;
        try {
          co =
              config.fromOperation(
                  resourcePath, httpMethod, operation, swagger.getDefinitions(), swagger);
          co.tags = new ArrayList<String>();
          co.tags.add(sanitizeTag(tag));
          config.addOperationToGroup(sanitizeTag(tag), resourcePath, operation, co, operations);

          List<Map<String, List<String>>> securities = operation.getSecurity();
          if (securities == null && swagger.getSecurity() != null) {
            securities = new ArrayList<Map<String, List<String>>>();
            for (SecurityRequirement sr : swagger.getSecurity()) {
              securities.add(sr.getRequirements());
            }
          }
          if (securities == null || securities.isEmpty()) {
            continue;
          }
          Map<String, SecuritySchemeDefinition> authMethods =
              new HashMap<String, SecuritySchemeDefinition>();
          // NOTE: Use only the first security requirement for now.
          // See the "security" field of "Swagger Object":
          //  https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#swagger-object
          //  "there is a logical OR between the security requirements"
          if (securities.size() > 1) {
            LOGGER.warn("More than 1 security requirements are found, using only the first one");
          }
          Map<String, List<String>> security = securities.get(0);
          for (String securityName : security.keySet()) {
            SecuritySchemeDefinition securityDefinition = fromSecurity(securityName);
            if (securityDefinition != null) {
              if (securityDefinition instanceof OAuth2Definition) {
                OAuth2Definition oauth2Definition = (OAuth2Definition) securityDefinition;
                OAuth2Definition oauth2Operation = new OAuth2Definition();
                oauth2Operation.setType(oauth2Definition.getType());
                oauth2Operation.setAuthorizationUrl(oauth2Definition.getAuthorizationUrl());
                oauth2Operation.setFlow(oauth2Definition.getFlow());
                oauth2Operation.setTokenUrl(oauth2Definition.getTokenUrl());
                oauth2Operation.setScopes(new HashMap<String, String>());
                for (String scope : security.get(securityName)) {
                  if (oauth2Definition.getScopes().containsKey(scope)) {
                    oauth2Operation.addScope(scope, oauth2Definition.getScopes().get(scope));
                  }
                }
                authMethods.put(securityName, oauth2Operation);
              } else {
                authMethods.put(securityName, securityDefinition);
              }
            }
          }
          if (!authMethods.isEmpty()) {
            co.authMethods = config.fromSecurity(authMethods);
            co.hasAuthMethods = true;
          }
        } catch (Exception ex) {
          String msg =
              "Could not process operation:\n" //
                  + "  Tag: "
                  + tag
                  + "\n" //
                  + "  Operation: "
                  + operation.getOperationId()
                  + "\n" //
                  + "  Resource: "
                  + httpMethod
                  + " "
                  + resourcePath
                  + "\n" //
                  + "  Definitions: "
                  + swagger.getDefinitions()
                  + "\n" //
                  + "  Exception: "
                  + ex.getMessage();
          throw new RuntimeException(msg, ex);
        }
      }
    }
  }
  @Override
  public List<File> generate() {
    Boolean generateApis = null;
    Boolean generateModels = null;
    Boolean generateSupportingFiles = null;

    Set<String> modelsToGenerate = null;
    Set<String> apisToGenerate = null;
    Set<String> supportingFilesToGenerate = null;

    // allows generating only models by specifying a CSV of models to generate, or empty for all
    if (System.getProperty("models") != null) {
      String modelNames = System.getProperty("models");
      generateModels = true;
      if (!modelNames.isEmpty()) {
        modelsToGenerate = new HashSet<String>(Arrays.asList(modelNames.split(",")));
      }
    }
    if (System.getProperty("apis") != null) {
      String apiNames = System.getProperty("apis");
      generateApis = true;
      if (!apiNames.isEmpty()) {
        apisToGenerate = new HashSet<String>(Arrays.asList(apiNames.split(",")));
      }
    }
    if (System.getProperty("supportingFiles") != null) {
      String supportingFiles = System.getProperty("supportingFiles");
      generateSupportingFiles = true;
      if (!supportingFiles.isEmpty()) {
        supportingFilesToGenerate = new HashSet<String>(Arrays.asList(supportingFiles.split(",")));
      }
    }

    if (generateApis == null && generateModels == null && generateSupportingFiles == null) {
      // no specifics are set, generate everything
      generateApis = true;
      generateModels = true;
      generateSupportingFiles = true;
    } else {
      if (generateApis == null) {
        generateApis = false;
      }
      if (generateModels == null) {
        generateModels = false;
      }
      if (generateSupportingFiles == null) {
        generateSupportingFiles = false;
      }
    }

    if (swagger == null || config == null) {
      throw new RuntimeException("missing swagger input or config!");
    }
    if (System.getProperty("debugSwagger") != null) {
      Json.prettyPrint(swagger);
    }
    List<File> files = new ArrayList<File>();
    config.processOpts();
    config.preprocessSwagger(swagger);

    config.additionalProperties().put("generatedDate", DateTime.now().toString());
    config.additionalProperties().put("generatorClass", config.getClass().toString());

    if (swagger.getInfo() != null) {
      Info info = swagger.getInfo();
      if (info.getTitle() != null) {
        config.additionalProperties().put("appName", info.getTitle());
      }
      if (info.getVersion() != null) {
        config.additionalProperties().put("appVersion", info.getVersion());
      }
      if (info.getDescription() != null) {
        config
            .additionalProperties()
            .put("appDescription", config.escapeText(info.getDescription()));
      }
      if (info.getContact() != null) {
        Contact contact = info.getContact();
        config.additionalProperties().put("infoUrl", contact.getUrl());
        if (contact.getEmail() != null) {
          config.additionalProperties().put("infoEmail", contact.getEmail());
        }
      }
      if (info.getLicense() != null) {
        License license = info.getLicense();
        if (license.getName() != null) {
          config.additionalProperties().put("licenseInfo", license.getName());
        }
        if (license.getUrl() != null) {
          config.additionalProperties().put("licenseUrl", license.getUrl());
        }
      }
      if (info.getVersion() != null) {
        config.additionalProperties().put("version", info.getVersion());
      }
    }

    StringBuilder hostBuilder = new StringBuilder();
    String scheme;
    if (swagger.getSchemes() != null && swagger.getSchemes().size() > 0) {
      scheme = swagger.getSchemes().get(0).toValue();
    } else {
      scheme = "https";
    }
    hostBuilder.append(scheme);
    hostBuilder.append("://");
    if (swagger.getHost() != null) {
      hostBuilder.append(swagger.getHost());
    } else {
      hostBuilder.append("localhost");
    }
    if (swagger.getBasePath() != null) {
      hostBuilder.append(swagger.getBasePath());
    }
    String contextPath = swagger.getBasePath() == null ? "" : swagger.getBasePath();
    String basePath = hostBuilder.toString();
    String basePathWithoutHost = swagger.getBasePath();

    // resolve inline models
    InlineModelResolver inlineModelResolver = new InlineModelResolver();
    inlineModelResolver.flatten(swagger);

    List<Object> allOperations = new ArrayList<Object>();
    List<Object> allModels = new ArrayList<Object>();

    // models
    Map<String, Model> definitions = swagger.getDefinitions();
    if (definitions != null) {
      List<String> sortedModelKeys = sortModelsByInheritance(definitions);

      if (generateModels) {
        if (modelsToGenerate != null && modelsToGenerate.size() > 0) {
          List<String> updatedKeys = new ArrayList<String>();
          for (String m : sortedModelKeys) {
            if (modelsToGenerate.contains(m)) {
              updatedKeys.add(m);
            }
          }
          sortedModelKeys = updatedKeys;
        }

        for (String name : sortedModelKeys) {
          try {
            // don't generate models that have an import mapping
            if (config.importMapping().containsKey(name)) {
              continue;
            }

            Model model = definitions.get(name);
            Map<String, Model> modelMap = new HashMap<String, Model>();
            modelMap.put(name, model);
            Map<String, Object> models = processModels(config, modelMap, definitions);
            models.putAll(config.additionalProperties());

            allModels.add(((List<Object>) models.get("models")).get(0));

            for (String templateName : config.modelTemplateFiles().keySet()) {
              String suffix = config.modelTemplateFiles().get(templateName);
              String filename =
                  config.modelFileFolder() + File.separator + config.toModelFilename(name) + suffix;
              if (!config.shouldOverwrite(filename)) {
                continue;
              }
              String templateFile = getFullTemplateFile(config, templateName);
              String template = readTemplate(templateFile);
              Template tmpl =
                  Mustache.compiler()
                      .withLoader(
                          new Mustache.TemplateLoader() {
                            @Override
                            public Reader getTemplate(String name) {
                              return getTemplateReader(
                                  getFullTemplateFile(config, name + ".mustache"));
                            }
                          })
                      .defaultValue("")
                      .compile(template);
              writeToFile(filename, tmpl.execute(models));
              files.add(new File(filename));
            }
          } catch (Exception e) {
            throw new RuntimeException("Could not generate model '" + name + "'", e);
          }
        }
      }
    }
    if (System.getProperty("debugModels") != null) {
      System.out.println("############ Model info ############");
      Json.prettyPrint(allModels);
    }

    // apis
    Map<String, List<CodegenOperation>> paths = processPaths(swagger.getPaths());
    if (generateApis) {
      if (apisToGenerate != null && apisToGenerate.size() > 0) {
        Map<String, List<CodegenOperation>> updatedPaths =
            new TreeMap<String, List<CodegenOperation>>();
        for (String m : paths.keySet()) {
          if (apisToGenerate.contains(m)) {
            updatedPaths.put(m, paths.get(m));
          }
        }
        paths = updatedPaths;
      }
      for (String tag : paths.keySet()) {
        try {
          List<CodegenOperation> ops = paths.get(tag);
          Map<String, Object> operation = processOperations(config, tag, ops);

          operation.put("basePath", basePath);
          operation.put("basePathWithoutHost", basePathWithoutHost);
          operation.put("contextPath", contextPath);
          operation.put("baseName", tag);
          operation.put("modelPackage", config.modelPackage());
          operation.putAll(config.additionalProperties());
          operation.put("classname", config.toApiName(tag));
          operation.put("classVarName", config.toApiVarName(tag));
          operation.put("importPath", config.toApiImport(tag));

          // Pass sortParamsByRequiredFlag through to the Mustache template...
          boolean sortParamsByRequiredFlag = true;
          if (this.config
              .additionalProperties()
              .containsKey(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG)) {
            sortParamsByRequiredFlag =
                Boolean.valueOf(
                    (String)
                        this.config
                            .additionalProperties()
                            .get(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG)
                            .toString());
          }
          operation.put("sortParamsByRequiredFlag", sortParamsByRequiredFlag);

          processMimeTypes(swagger.getConsumes(), operation, "consumes");
          processMimeTypes(swagger.getProduces(), operation, "produces");

          allOperations.add(new HashMap<String, Object>(operation));
          for (int i = 0; i < allOperations.size(); i++) {
            Map<String, Object> oo = (Map<String, Object>) allOperations.get(i);
            if (i < (allOperations.size() - 1)) {
              oo.put("hasMore", "true");
            }
          }

          for (String templateName : config.apiTemplateFiles().keySet()) {
            String filename = config.apiFilename(templateName, tag);
            if (!config.shouldOverwrite(filename) && new File(filename).exists()) {
              continue;
            }

            String templateFile = getFullTemplateFile(config, templateName);
            String template = readTemplate(templateFile);
            Template tmpl =
                Mustache.compiler()
                    .withLoader(
                        new Mustache.TemplateLoader() {
                          @Override
                          public Reader getTemplate(String name) {
                            return getTemplateReader(
                                getFullTemplateFile(config, name + ".mustache"));
                          }
                        })
                    .defaultValue("")
                    .compile(template);

            writeToFile(filename, tmpl.execute(operation));
            files.add(new File(filename));
          }
        } catch (Exception e) {
          throw new RuntimeException("Could not generate api file for '" + tag + "'", e);
        }
      }
    }
    if (System.getProperty("debugOperations") != null) {
      System.out.println("############ Operation info ############");
      Json.prettyPrint(allOperations);
    }

    // supporting files
    Map<String, Object> bundle = new HashMap<String, Object>();
    bundle.putAll(config.additionalProperties());
    bundle.put("apiPackage", config.apiPackage());

    Map<String, Object> apis = new HashMap<String, Object>();
    apis.put("apis", allOperations);
    if (swagger.getHost() != null) {
      bundle.put("host", swagger.getHost());
    }
    bundle.put("basePath", basePath);
    bundle.put("scheme", scheme);
    bundle.put("contextPath", contextPath);
    bundle.put("apiInfo", apis);
    bundle.put("models", allModels);
    bundle.put("apiFolder", config.apiPackage().replace('.', File.separatorChar));
    bundle.put("modelPackage", config.modelPackage());
    List<CodegenSecurity> authMethods = config.fromSecurity(swagger.getSecurityDefinitions());
    if (authMethods != null && !authMethods.isEmpty()) {
      bundle.put("authMethods", authMethods);
      bundle.put("hasAuthMethods", true);
    }
    if (swagger.getExternalDocs() != null) {
      bundle.put("externalDocs", swagger.getExternalDocs());
    }
    for (int i = 0; i < allModels.size() - 1; i++) {
      HashMap<String, CodegenModel> cm = (HashMap<String, CodegenModel>) allModels.get(i);
      CodegenModel m = cm.get("model");
      m.hasMoreModels = true;
    }

    config.postProcessSupportingFileData(bundle);

    if (System.getProperty("debugSupportingFiles") != null) {
      System.out.println("############ Supporting file info ############");
      Json.prettyPrint(bundle);
    }

    if (generateSupportingFiles) {
      for (SupportingFile support : config.supportingFiles()) {
        try {
          String outputFolder = config.outputFolder();
          if (isNotEmpty(support.folder)) {
            outputFolder += File.separator + support.folder;
          }
          File of = new File(outputFolder);
          if (!of.isDirectory()) {
            of.mkdirs();
          }
          String outputFilename = outputFolder + File.separator + support.destinationFilename;
          if (!config.shouldOverwrite(outputFilename)) {
            continue;
          }

          String templateFile = getFullTemplateFile(config, support.templateFile);

          boolean shouldGenerate = true;
          if (supportingFilesToGenerate != null && supportingFilesToGenerate.size() > 0) {
            if (supportingFilesToGenerate.contains(support.destinationFilename)) {
              shouldGenerate = true;
            } else {
              shouldGenerate = false;
            }
          }
          if (shouldGenerate) {
            if (templateFile.endsWith("mustache")) {
              String template = readTemplate(templateFile);
              Template tmpl =
                  Mustache.compiler()
                      .withLoader(
                          new Mustache.TemplateLoader() {
                            @Override
                            public Reader getTemplate(String name) {
                              return getTemplateReader(
                                  getFullTemplateFile(config, name + ".mustache"));
                            }
                          })
                      .defaultValue("")
                      .compile(template);

              writeToFile(outputFilename, tmpl.execute(bundle));
              files.add(new File(outputFilename));
            } else {
              InputStream in = null;

              try {
                in = new FileInputStream(templateFile);
              } catch (Exception e) {
                // continue
              }
              if (in == null) {
                in =
                    this.getClass()
                        .getClassLoader()
                        .getResourceAsStream(getCPResourcePath(templateFile));
              }
              File outputFile = new File(outputFilename);
              OutputStream out = new FileOutputStream(outputFile, false);
              if (in != null && out != null) {
                System.out.println("writing file " + outputFile);
                IOUtils.copy(in, out);
              } else {
                if (in == null) {
                  System.out.println("can't open " + templateFile + " for input");
                }
                if (out == null) {
                  System.out.println("can't open " + outputFile + " for output");
                }
              }

              files.add(outputFile);
            }
          }
        } catch (Exception e) {
          throw new RuntimeException("Could not generate supporting file '" + support + "'", e);
        }
      }
    }

    config.processSwagger(swagger);

    return files;
  }
  public String processRefToExternalDefinition(String $ref, RefFormat refFormat) {
    final Model model = cache.loadRef($ref, refFormat, Model.class);

    String newRef;

    Map<String, Model> definitions = swagger.getDefinitions();

    if (definitions == null) {
      definitions = new HashMap<>();
    }

    final String possiblyConflictingDefinitionName = computeDefinitionName($ref);

    Model existingModel = definitions.get(possiblyConflictingDefinitionName);

    if (existingModel != null) {
      LOGGER.debug("A model for " + existingModel + " already exists");
      if (existingModel instanceof RefModel) {
        // use the new model
        existingModel = null;
      }
    }
    newRef = possiblyConflictingDefinitionName;
    cache.putRenamedRef($ref, newRef);

    if (existingModel == null) {
      // don't overwrite existing model reference
      swagger.addDefinition(newRef, model);
      cache.addReferencedKey(newRef);

      String file = $ref.split("#/")[0];
      if (model instanceof RefModel) {
        RefModel refModel = (RefModel) model;
        if (isAnExternalRefFormat(refModel.getRefFormat())) {
          refModel.set$ref(
              processRefToExternalDefinition(refModel.get$ref(), refModel.getRefFormat()));
        } else {
          processRefToExternalDefinition(file + refModel.get$ref(), RefFormat.RELATIVE);
        }
      }
      // Loop the properties and recursively call this method;
      Map<String, Property> subProps = model.getProperties();
      if (subProps != null) {
        for (Map.Entry<String, Property> prop : subProps.entrySet()) {
          if (prop.getValue() instanceof RefProperty) {
            processRefProperty((RefProperty) prop.getValue(), file);
          } else if (prop.getValue() instanceof ArrayProperty) {
            ArrayProperty arrayProp = (ArrayProperty) prop.getValue();
            if (arrayProp.getItems() instanceof RefProperty) {
              processRefProperty((RefProperty) arrayProp.getItems(), file);
            }
          } else if (prop.getValue() instanceof MapProperty) {
            MapProperty mapProp = (MapProperty) prop.getValue();
            if (mapProp.getAdditionalProperties() instanceof RefProperty) {
              processRefProperty((RefProperty) mapProp.getAdditionalProperties(), file);
            } else if (mapProp.getAdditionalProperties() instanceof ArrayProperty
                && ((ArrayProperty) mapProp.getAdditionalProperties()).getItems()
                    instanceof RefProperty) {
              processRefProperty(
                  (RefProperty) ((ArrayProperty) mapProp.getAdditionalProperties()).getItems(),
                  file);
            }
          }
        }
      }
      if (model instanceof ArrayModel && ((ArrayModel) model).getItems() instanceof RefProperty) {
        processRefProperty((RefProperty) ((ArrayModel) model).getItems(), file);
      }
    }

    return newRef;
  }