public SecuritySchemeDefinition securityDefinition(
      ObjectNode node, String location, ParseResult result) {
    if (node == null) return null;

    SecuritySchemeDefinition output = null;

    String type = getString("type", node, true, location, result);
    if (type != null) {
      if (type.equals("basic")) {
        // TODO: parse manually for better feedback
        output = Json.mapper().convertValue(node, BasicAuthDefinition.class);
      } else if (type.equals("apiKey")) {
        String position = getString("in", node, true, location, result);
        String name = getString("name", node, true, location, result);

        if (name != null && ("header".equals(position) || "query".equals(position))) {
          In in = In.forValue(position);
          if (in != null) {
            ApiKeyAuthDefinition auth = new ApiKeyAuthDefinition().name(name).in(in);
            output = auth;
          }
        }
      } else if (type.equals("oauth2")) {
        // TODO: parse manually for better feedback
        output = Json.mapper().convertValue(node, OAuth2Definition.class);
      } else {
        result.invalidType(location + ".type", "type", "basic|apiKey|oauth2", node);
      }
    }

    return output;
  }
  public Response response(ObjectNode node, String location, ParseResult result) {
    if (node == null) return null;

    Response output = new Response();
    JsonNode ref = node.get("$ref");
    if (ref != null) {
      if (ref.getNodeType().equals(JsonNodeType.STRING)) {
        return refResponse((TextNode) ref, location, result);
      } else {
        result.invalidType(location, "$ref", "string", node);
        return null;
      }
    }

    String value = getString("description", node, true, location, result);
    output.description(value);

    ObjectNode schema = getObject("schema", node, false, location, result);
    if (schema != null) {
      output.schema(Json.mapper().convertValue(schema, Property.class));
    }
    ObjectNode headersNode = getObject("headers", node, false, location, result);
    if (headersNode != null) {
      // TODO
      Map<String, Property> headers =
          Json.mapper()
              .convertValue(
                  headersNode,
                  Json.mapper()
                      .getTypeFactory()
                      .constructMapType(Map.class, String.class, Property.class));
      output.headers(headers);
    }

    ObjectNode examplesNode = getObject("examples", node, false, location, result);
    if (examplesNode != null) {
      Map<String, Object> examples =
          Json.mapper()
              .convertValue(
                  examplesNode,
                  Json.mapper()
                      .getTypeFactory()
                      .constructMapType(Map.class, String.class, Object.class));
      output.setExamples(examples);
    }

    // extra keys
    Set<String> keys = getKeys(node);
    for (String key : keys) {
      if (key.startsWith("x-")) {
        output.setVendorExtension(key, extension(node.get(key)));
      } else if (!RESPONSE_KEYS.contains(key)) {
        result.extra(location, key, node.get(key));
      }
    }
    return output;
  }
 /**
  * Returns the API documentation of all annotated resources for purposes of Swagger documentation.
  *
  * @return The resource's documentation
  */
 @GET
 @Path("/swagger.json")
 @Produces(MediaType.APPLICATION_JSON)
 public HttpResponse getSwaggerJSON() {
   Swagger swagger = new Reader(new Swagger()).read(this.getClass());
   if (swagger == null) {
     return new HttpResponse(
         "Swagger API declaration not available!", HttpURLConnection.HTTP_NOT_FOUND);
   }
   try {
     return new HttpResponse(Json.mapper().writeValueAsString(swagger), HttpURLConnection.HTTP_OK);
   } catch (JsonProcessingException e) {
     e.printStackTrace();
     return new HttpResponse(e.getMessage(), HttpURLConnection.HTTP_INTERNAL_ERROR);
   }
 }
  /** verifies that the return value uses the schema example */
  @Test
  public void verifyGetComplexResponseWithExample() throws Exception {
    Map<String, String> queryParams = new HashMap<String, String>();

    String str =
        client.invokeAPI(
            "/mockResponses/complexResponseWithExample",
            "GET",
            queryParams,
            null,
            new HashMap<String, String>(),
            null,
            "application/json",
            null,
            new String[0]);
    ObjectMapper mapper =
        Json.mapper().configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
    assertEquals(
        mapper.readValue(str, JsonNode.class),
        mapper.readValue("{\n  \"foo\":\"bar\"\n}\n", JsonNode.class));
  }
  /** verifies that the return value generates a schema */
  @Test
  public void verifyGetComplexResponse() throws Exception {
    Map<String, String> queryParams = new HashMap<String, String>();

    String str =
        client.invokeAPI(
            "/mockResponses/complexResponse",
            "GET",
            queryParams,
            null,
            new HashMap<String, String>(),
            null,
            "application/json",
            null,
            new String[0]);
    ObjectMapper mapper =
        Json.mapper().configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
    assertEquals(
        mapper.readValue(str, JsonNode.class),
        mapper.readValue(
            "{\"street\":\"12345 El Monte Road\",\"city\":\"Los Altos Hills\",\"state\":\"CA\",\"zip\":\"94022\"}",
            JsonNode.class));
  }
  @Override
  public void run(InflectorServerConfiguration configuration, Environment environment)
      throws Exception {
    final FilterRegistration.Dynamic cors =
        environment.servlets().addFilter("crossOriginRequsts", CrossOriginFilter.class);
    cors.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*");

    SwaggerInflector inflector =
        new SwaggerInflector(Configuration.read(configuration.getConfig()));
    environment.jersey().getResourceConfig().registerResources(inflector.getResources());

    // add serializers for swagger
    environment.jersey().register(SwaggerSerializers.class);

    // example serializers
    environment.jersey().register(ExampleSerializer.class);

    // mappers
    SimpleModule simpleModule = new SimpleModule();
    simpleModule.addSerializer(new JsonNodeExampleSerializer());
    Json.mapper().registerModule(simpleModule);
    Yaml.mapper().registerModule(simpleModule);
  }
  private void assertDescriptorJson(Operation o, Throwable e) {
    if (e != null) {
      e.printStackTrace();

      if (e.getMessage().contains("Unparseable JSON body")) {
        // Ignore failure
        // Expecting GSON classloading issue to be fixed:
        //  - https://github.com/google/gson/issues/764
        //  - https://www.pivotaltracker.com/story/show/120885303
        Utils.logWarning("GSON initialization failure: %s", e);
        // Stop assertion logic here, test will finish as success
        return;
      } else {
        fail(e.getMessage());
      }
    }

    try {
      Swagger swagger = Json.mapper().readValue(o.getBody(String.class), Swagger.class);
      assertSwagger(swagger);
    } catch (IOException ioe) {
      fail(ioe.getMessage());
    }
  }
 public Property property(ObjectNode node, String location, ParseResult result) {
   Property output = Json.mapper().convertValue(node, Property.class);
   return output;
 }
  public Model definition(ObjectNode node, String location, ParseResult result) {
    if (node == null) {
      result.missing(location, "empty schema");
    }
    if (node.get("$ref") != null) {
      return refModel(node, location, result);
    }
    if (node.get("allOf") != null) {
      return allOfModel(node, location, result);
    }
    Model model = null;
    String value = null;

    String type = getString("type", node, false, location, result);
    Model m = new ModelImpl();
    if ("array".equals(type)) {
      ArrayModel am = new ArrayModel();
      ObjectNode propertyNode = getObject("properties", node, false, location, result);
      Map<String, Property> properties = properties(propertyNode, location, result);
      am.setProperties(properties);

      ObjectNode itemsNode = getObject("items", node, false, location, result);
      Property items = property(itemsNode, location, result);
      if (items != null) {
        am.items(items);
      }

      model = am;
    } else {
      ModelImpl impl = new ModelImpl();
      impl.setType(value);

      JsonNode ap = node.get("additionalProperties");
      if (ap != null && ap.getNodeType().equals(JsonNodeType.OBJECT)) {
        impl.setAdditionalProperties(Json.mapper().convertValue(ap, Property.class));
      }

      value = getString("default", node, false, location, result);
      impl.setDefaultValue(value);

      value = getString("format", node, false, location, result);
      impl.setFormat(value);

      value = getString("discriminator", node, false, location, result);
      impl.setDiscriminator(value);

      JsonNode xml = node.get("xml");
      if (xml != null) {
        impl.setXml(Json.mapper().convertValue(xml, Xml.class));
      }

      ObjectNode externalDocs = getObject("externalDocs", node, false, location, result);
      ExternalDocs docs = externalDocs(externalDocs, location, result);
      impl.setExternalDocs(docs);

      ObjectNode properties = getObject("properties", node, true, location, result);
      if (properties != null) {
        Set<String> propertyNames = getKeys(properties);
        for (String propertyName : propertyNames) {
          JsonNode propertyNode = properties.get(propertyName);
          if (propertyNode.getNodeType().equals(JsonNodeType.OBJECT)) {
            ObjectNode on = (ObjectNode) propertyNode;
            Property property = property(on, location, result);
            impl.property(propertyName, property);
          } else {
            result.invalidType(location, "properties", "object", propertyNode);
          }
        }
      }

      // need to set properties first
      ArrayNode required = getArray("required", node, false, location, result);
      if (required != null) {
        List<String> requiredProperties = new ArrayList<String>();
        for (JsonNode n : required) {
          if (n.getNodeType().equals(JsonNodeType.STRING)) {
            requiredProperties.add(((TextNode) n).textValue());
          } else {
            result.invalidType(location, "required", "string", n);
          }
        }
        if (requiredProperties.size() > 0) {
          impl.setRequired(requiredProperties);
        }
      }

      // extra keys
      Set<String> keys = getKeys(node);
      for (String key : keys) {
        if (key.startsWith("x-")) {
          impl.setVendorExtension(key, extension(node.get(key)));
        } else if (!SCHEMA_KEYS.contains(key)) {
          result.extra(location, key, node.get(key));
        }
      }
      if ("{ }".equals(Json.pretty(impl))) return null;
      model = impl;
    }
    JsonNode exampleNode = node.get("example");
    if (exampleNode != null) {
      // we support text or object nodes
      if (exampleNode.getNodeType().equals(JsonNodeType.OBJECT)) {
        ObjectNode on = getObject("example", node, false, location, result);
        if (on != null) {
          model.setExample(on);
        }
      } else {
        model.setExample(exampleNode.asText());
      }
    }

    if (model != null) {
      value = getString("description", node, false, location, result);
      model.setDescription(value);

      value = getString("title", node, false, location, result);
      model.setTitle(value);
    }

    return model;
  }
 private Property schema(
     Map<String, Object> schemaItems, JsonNode obj, String location, ParseResult result) {
   return Json.mapper().convertValue(obj, Property.class);
 }
  public Parameter parameter(ObjectNode obj, String location, ParseResult result) {
    if (obj == null) {
      return null;
    }

    Parameter output = null;
    JsonNode ref = obj.get("$ref");
    if (ref != null) {
      if (ref.getNodeType().equals(JsonNodeType.STRING)) {
        return refParameter((TextNode) ref, location, result);
      } else {
        result.invalidType(location, "$ref", "string", obj);
        return null;
      }
    }

    String l = null;
    JsonNode ln = obj.get("name");
    if (ln != null) {
      l = ln.asText();
    } else {
      l = "['unknown']";
    }
    location += ".[" + l + "]";

    String value = getString("in", obj, true, location, result);
    if (value != null) {
      String type = getString("type", obj, false, location, result);
      String format = getString("format", obj, false, location, result);
      AbstractSerializableParameter<?> sp = null;
      if ("query".equals(value)) {
        sp = new QueryParameter();
      } else if ("header".equals(value)) {
        sp = new HeaderParameter();
      } else if ("path".equals(value)) {
        sp = new PathParameter();
      } else if ("formData".equals(value)) {
        sp = new FormParameter();
      }

      if (sp != null) {
        // type is mandatory when sp != null
        getString("type", obj, true, location, result);
        Map<PropertyBuilder.PropertyId, Object> map =
            new HashMap<PropertyBuilder.PropertyId, Object>();

        map.put(TYPE, type);
        map.put(FORMAT, format);
        String defaultValue = getString("default", obj, false, location, result);
        map.put(DEFAULT, defaultValue);
        sp.setDefault(defaultValue);

        Double dbl = getDouble("maximum", obj, false, location, result);
        if (dbl != null) {
          map.put(MAXIMUM, dbl);
          sp.setMaximum(dbl);
        }

        Boolean bl = getBoolean("exclusiveMaximum", obj, false, location, result);
        if (bl != null) {
          map.put(EXCLUSIVE_MAXIMUM, bl);
          sp.setExclusiveMaximum(bl);
        }

        dbl = getDouble("minimum", obj, false, location, result);
        if (dbl != null) {
          map.put(MINIMUM, dbl);
          sp.setMinimum(dbl);
        }

        bl = getBoolean("exclusiveMinimum", obj, false, location, result);
        if (bl != null) {
          map.put(EXCLUSIVE_MINIMUM, bl);
          sp.setExclusiveMinimum(bl);
        }

        map.put(MAX_LENGTH, getInteger("maxLength", obj, false, location, result));
        map.put(MIN_LENGTH, getInteger("minLength", obj, false, location, result));

        String pat = getString("pattern", obj, false, location, result);
        map.put(PATTERN, pat);
        sp.setPattern(pat);

        Integer iv = getInteger("maxItems", obj, false, location, result);
        map.put(MAX_ITEMS, iv);
        sp.setMaxItems(iv);

        iv = getInteger("minItems", obj, false, location, result);
        map.put(MIN_ITEMS, iv);
        sp.setMinItems(iv);

        map.put(UNIQUE_ITEMS, getBoolean("uniqueItems", obj, false, location, result));

        ArrayNode an = getArray("enum", obj, false, location, result);
        if (an != null) {
          List<String> _enum = new ArrayList<String>();
          for (JsonNode n : an) {
            _enum.add(n.textValue());
          }
          sp.setEnum(_enum);
          map.put(ENUM, _enum);
        }

        Property prop = PropertyBuilder.build(type, format, map);

        if (prop != null) {
          sp.setProperty(prop);
          ObjectNode items = getObject("items", obj, false, location, result);
          if (items != null) {
            Property inner = schema(null, items, location, result);
            sp.setItems(inner);
          }
        }

        Set<String> keys = getKeys(obj);
        for (String key : keys) {
          if (key.startsWith("x-")) {
            sp.setVendorExtension(key, extension(obj.get(key)));
          } else if (!PARAMETER_KEYS.contains(key)) {
            result.extra(location, key, obj.get(key));
          }
        }

        String collectionFormat = getString("collectionFormat", obj, false, location, result);
        sp.setCollectionFormat(collectionFormat);

        output = sp;
      } else if ("body".equals(value)) {
        output = Json.mapper().convertValue(obj, Parameter.class);
      }
      if (output != null) {
        value = getString("name", obj, true, location, result);
        output.setName(value);

        value = getString("description", obj, false, location, result);
        output.setDescription(value);

        Boolean required = getBoolean("required", obj, false, location, result);
        if (required != null) {
          output.setRequired(required);
        }
      }
    }

    return output;
  }
  public Swagger parseRoot(JsonNode node, ParseResult result) {
    String location = "";
    Swagger swagger = new Swagger();
    if (node.getNodeType().equals(JsonNodeType.OBJECT)) {
      ObjectNode on = (ObjectNode) node;
      Iterator<JsonNode> it = null;

      // required
      String value = getString("swagger", on, true, location, result);
      swagger.setSwagger(value);

      ObjectNode obj = getObject("info", on, true, "", result);
      if (obj != null) {
        Info info = info(obj, "info", result);
        swagger.info(info);
      }

      // optional
      value = getString("host", on, false, location, result);
      swagger.setHost(value);

      value = getString("basePath", on, false, location, result);
      swagger.setBasePath(value);

      ArrayNode array = getArray("schemes", on, false, location, result);
      if (array != null) {
        it = array.iterator();
        while (it.hasNext()) {
          JsonNode n = it.next();
          String s = getString(n, location + ".schemes", result);
          if (s != null) {
            Scheme scheme = Scheme.forValue(s);
            if (scheme != null) {
              swagger.scheme(scheme);
            }
          }
        }
      }

      array = getArray("consumes", on, false, location, result);
      if (array != null) {
        it = array.iterator();
        while (it.hasNext()) {
          JsonNode n = it.next();
          String s = getString(n, location + ".consumes", result);
          if (s != null) {
            swagger.consumes(s);
          }
        }
      }

      array = getArray("produces", on, false, location, result);
      if (array != null) {
        it = array.iterator();
        while (it.hasNext()) {
          JsonNode n = it.next();
          String s = getString(n, location + ".produces", result);
          if (s != null) {
            swagger.produces(s);
          }
        }
      }

      obj = getObject("paths", on, true, location, result);
      Map<String, Path> paths = paths(obj, "paths", result);
      swagger.paths(paths);

      obj = getObject("definitions", on, false, location, result);
      Map<String, Model> definitions = definitions(obj, "definitions", result);
      swagger.setDefinitions(definitions);

      obj = getObject("parameters", on, false, location, result);
      // TODO: parse
      Map<String, Parameter> parameters =
          Json.mapper()
              .convertValue(
                  obj,
                  Json.mapper()
                      .getTypeFactory()
                      .constructMapType(Map.class, String.class, Parameter.class));
      swagger.setParameters(parameters);

      obj = getObject("responses", on, false, location, result);
      Map<String, Response> responses = responses(obj, "responses", result);
      swagger.responses(responses);

      obj = getObject("securityDefinitions", on, false, location, result);
      Map<String, SecuritySchemeDefinition> securityDefinitions =
          securityDefinitions(obj, location, result);
      swagger.setSecurityDefinitions(securityDefinitions);

      array = getArray("security", on, false, location, result);
      List<SecurityRequirement> security = securityRequirements(array, location, result);
      swagger.setSecurity(security);

      array = getArray("tags", on, false, location, result);
      List<Tag> tags = tags(array, location, result);
      swagger.tags(tags);

      obj = getObject("externalDocs", on, false, location, result);
      ExternalDocs docs = externalDocs(obj, location, result);
      swagger.externalDocs(docs);

      // extra keys
      Set<String> keys = getKeys(on);
      for (String key : keys) {
        if (key.startsWith("x-")) {
          swagger.vendorExtension(key, extension(on.get(key)));
        } else if (!ROOT_KEYS.contains(key)) {
          result.extra(location, key, node.get(key));
        }
      }
    } else {
      result.invalidType("", "", "object", node);
      result.invalid();
      return null;
    }
    return swagger;
  }
 public static boolean compareAsJson(Object objectToSerialize, String jsonStr) {
   return apply(objectToSerialize, jsonStr, Json.mapper());
 }