0
votes

I have to extract information of a JSON response and evaluate if some file dis present or not. I'm using the following method definition:

override def hasField(field: Field): Boolean = {
  val schema = parse(httpClient.doGet(url + Solr5EndpointUris.schemaOverviewEndpoint)).extract[Map[String, Any]]

  val fieldsNames: List[String] = schema.get("schema") match {
    case schema: Some[Map[String, Any]] => schema.get(if (field.dynamic) "dynamicFields" else "fields") match {
      case fields: List[Map[String, Any]] => fields.map {
        case field: Map[String, Any] => field.get("name") match {
          case name: Some[String] => name.getOrElse("")
        }
      }
      case _ => throw new ApiException("Malformed Response! Missing definition for schema > fields/dynamicFields.")
    }
    case _ => throw new ApiException("Malformed Response! Could not extract schema from JSON.")
  }

  fieldsNames.contains(field.name)
}

The method inspects the JSON response via pattern matching and should return true if a field with specific name is present. An example JSON response could be the following:

{
  "responseHeader":{
  "status":0,
  "QTime":2},
  "schema":{
    "name":"example-data-driven-schema",
    "version":1.5,
    "uniqueKey":"id",
    "fieldTypes":[],
    "fields":[{
      "name":"id",
      "type":"string",
      "multiValued":false,
      "indexed":true,
      "required":true,
      "stored":true}],
    "dynamicFields":[],
    "copyFields":[]
  }
}

This implementations does work, but i'm pretty sure there is a more straight forward / less complex implementation to achieve this. Also i get many warnings like the following:

SchemaManager.scala:38: non-variable type argument Map[String,Any] in type pattern Some[Map[String,Any]] is unchecked since it is eliminated by erasure

Can anyone provide a better solution, and / or explain the warnings i get?

1

1 Answers

1
votes
SchemaManager.scala:38: non-variable type argument Map[String,Any] in type pattern Some[Map[String,Any]] is unchecked since it is eliminated by erasure

Scala compiler will erase the generic type in compile time. so when you use pattern match, the compiler will erase your match type parameter. and throw this warning. it calls type erasure.

For your question, you can use json4s for your JSON extract:

scala> import org.json4s._
scala> import org.json4s.native.JsonMethods._
scala> val jsonStr = "{\n  \"responseHeader\":{\n  \"status\":0,\n  \"QTime\":2},\n  \"schema\":{\n    \"name\":\"example-data-driven-schema\",\n    \"version\":1.5,\n    \"uniqueKey\":\"id\",\n    \"fieldTypes\":[],\n    \"fields\":[{\n      \"name\":\"id\",\n      \"type\":\"string\",\n      \"multiValued\":false,\n      \"indexed\":true,\n      \"required\":true,\n      \"stored\":true}],\n    \"dynamicFields\":[],\n    \"copyFields\":[]\n  }\n}"
scala> implicit val formats = DefaultFormats
scala> val f = parse(jsonStr)
scala> println((f \\ "schema" \\ "fields" \\ "name").extractOrElse("Null"))
id
scala> println((f \\ "schema" \\ "fields" \\ "unknow").extractOrElse("Null"))
Null

Use extractOrElse to set the default value.