3
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "id": {
      "type": "string"
    },
    "i": {
      "type": "integer"
    },
    "p": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "id": {
          "type": "string"
        },
        "i": {
          "type": "integer"
        },
        "p1": {
          "type": "object",
          "properties": {
            "name": {
              "type": "string"
            },
            "id": {
              "type": "string"
            },
            "i": {
              "type": "integer"
            }
          }
        }
      }
    }
  },
  "classname": "com.tibco.tea.agent.Person"
}

I've the above generated schema, to which I want to do some modification. As you can see, I've nested Object's in this schema. I want to insert a "classname" attribute for each object. Can anybody suggest me how can I use jackson 2.3.0 to traverse through this schema and manipulate it as mentioned above.

Piyush Jajoo
  • 1,095
  • 2
  • 18
  • 27
  • Any version of jackson parser implementation work, if it solves the cyclic redundancy issue i.e. a self reference issue, which was there in previous versions. – Piyush Jajoo Sep 19 '14 at 08:46

2 Answers2

2

If the nodes are objects, You could cast them to an ObjectNode and use the put method to add desired key/value pairs.

JSON = // stuff you have in example
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(JSON);
// using root node for this example
if (jsonNode.isObject()) {
    ((ObjectNode) jsonNode).put("classname", "com.stackoverflow.Cheese");
}
mkobit
  • 43,979
  • 12
  • 156
  • 150
  • Thanks for the solution, but what if I wan't to traverse to the inside objects and put the classname for them. Can you please suggest how to do that? – Piyush Jajoo Sep 20 '14 at 07:15
  • You would have to traverse into those nodes and use the method above. You could change the call above to `JsonNode propertiesNode = jsonNode.get("properties");` and then do the same operations on that Node. – mkobit Sep 20 '14 at 18:50
  • Take a look at the [JsonNode](http://fasterxml.github.io/jackson-databind/javadoc/2.3.0/com/fasterxml/jackson/databind/JsonNode.html) JavaDoc or read some of the Jackson documentation to see examples of how you could do this. Please mark this as the solution because I believe it resolves your questoin. – mkobit Sep 20 '14 at 21:16
0

This is my code of putting the classnames in the generated schema. This code handles the case when the an array or a non-array parameter is provided. i.e. Person.class and Person[].class can be handled successfully. This code cannot handle the self reference issue which is still open on Jackson - https://github.com/FasterXML/jackson-databind/issues/339

The code below can be instantiated as follows -

public static void main(String[] args) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        Class<?> cls = Person[].class;
        if(cls.isArray()){
            cls = cls.getComponentType();
        }
        String s = "{\"rootNode\":{\"classname\":\"" + cls.getName() + "\"},"
                + getAttributeClassnames(cls) + "}";
        s = s.replace("\",}", "\"}").replace("},}", "}}");
        System.out.println(s);
        s = mapper.generateJsonSchema(cls).getSchemaNode().put("type", "array")
                .put("classnames", s).toString();
        s = s.replace("\\", "").replace("\"{", "{").replace("}\"", "}");        
        System.out.println(s);
    }

static String getAttributeClassnames(Class<?> cls) {
    String s = "";      
        Field[] field = cls.getDeclaredFields();
        int i = 0;
        while (i < field.length) {              
            if (!(field[i].getType() == Boolean.class)
                    && !(field[i].getType() == Integer.class)
                    && !(field[i].getType() == Character.class)
                    && !(field[i].getType() == Byte.class)
                    && !(field[i].getType() == Short.class)
                    && !(field[i].getType() == Long.class)
                    && !(field[i].getType() == Float.class)
                    && !(field[i].getType() == Double.class)
                    && !(field[i].getType().isPrimitive())
                    && !(field[i].getType() == String.class)
                    && !(Collection.class.isAssignableFrom(field[i]
                            .getType()))
                    && !(Map.class.isAssignableFrom(field[i].getType()))
                    && !(Arrays.class.isAssignableFrom(field[i].getType()))) {
                if(field[i].getType() == cls){
                    if (i == field.length - 1) {
                        Class<?> name = null;
                        if(field[i].getType().isArray()){
                            name = field[i].getType().getComponentType();
                        }else{
                            name = field[i].getType();
                        }
                        s = s + "\"" + field[i].getName() + "\""
                                + ":{\"classname\":\""
                                + name.getName() + "\","
                                +"}";
                    } else {
                        Class<?> name = null;                       
                        if(field[i].getType().isArray()){
                            name = field[i].getType().getComponentType();
                        }else{
                            name = field[i].getType();
                        }
                        s = s + "\"" + field[i].getName() + "\""
                                + ":{\"classname\":\""
                                + name.getName() + "\","
                                + "}" + ",";
                    }

                }else{
                    if (i == field.length - 1) {
                        Class<?> name = null;
                        if(field[i].getType().isArray()){
                            name = field[i].getType().getComponentType();
                        }else{
                            name = field[i].getType();
                        }
                        s = s + "\"" + field[i].getName() + "\""
                                + ":{\"classname\":\""
                                + name.getName() + "\","
                                + getAttributeClassnames(name)
                                + "}";
                    } else {
                        Class<?> name = null;                       
                        if(field[i].getType().isArray()){
                            name = field[i].getType().getComponentType();
                        }else{
                            name = field[i].getType();
                        }
                        s = s + "\"" + field[i].getName() + "\""
                                + ":{\"classname\":\""
                                + name.getName() + "\","
                                + getAttributeClassnames(name)
                                + "}" + ",";
                    }
                }
            }
            i++;
        }
    return s;
}
Piyush Jajoo
  • 1,095
  • 2
  • 18
  • 27