Sunday, December 22, 2013

Starting with JSON

I am using jQuery in an application to build a user interface that creates a tree of classes. I want to use that tree as a template in another application that looks for a similar structure.

I am trying to use JSON to save the tree from the first app, read it in the second app, convert it to a Java object and then compare it to the other structure.

I took a quick look at JSON.simple, but I only looked at one post where the advice was to use either Jackson or GSON. I will try GSON first.

Download: http://code.google.com/p/google-gson/downloads/list

Tutorial: http://www.studytrails.com/java/json/java-google-json-parse-json-to-java.jsp

I have successfully completed my task.
  1. Created JSON from the object structure using jQuery and javascript.
  2. Added the JSON to a hidden field that is submitted to the server application.
  3. In the server application using Java and GSON, I read the JSON data and created a class hierarchy from it.
These are the methods that created the JSON from my object structure. There are two structures, TextPart and Group. Group contains TextPart and other Groups. TextPart contains text and another field to indicate if the text is equivalent to another TextPart.
    
    //grab the text, replacing " with \".
    function getTextPartText(textPart) {
        return $.trim($(textPart).children('code').text()).replace(/\"/g, "\\\"");     
    }
  
    //grab the text, replacing " with \". Change to lower case, change space to underscore.
    function getTextPartEquivalent(textPart) {
        var result = $.trim($(textPart).children('var').text().toLowerCase());
        result = result.toLowerCase().replace(/\s/g,'_');
        return result.replace(/\"/g, "\\\"");     
    }
  
    function textPartToJson(textPart) {
        return '{ ' +
                '"textPart" : "' + getTextPartText(textPart) + '"' +
                ', "equivalent" : "' + getTextPartEquivalent(textPart) + '"' +
               '}';
    }
  
    function groupToJson(group) {
        var state, result, children, comma, classAttr, i, radioGroup;
      
        state = "sequential";      
        radioGroup = $(group).children('.radioGroupType');
        if (radioGroup.length > 0) {
            if (radioGroup.children(".groupTypeRandom").prop('checked')) {
                state = "random";
            }
        }
        result = '{ "groupType":"' + state + '", "children": [';
        children = $(group).children();
        comma="";
        for (i = 0; i < children.length; i++) {
            classAttr = $(children[i]).attr('class');
            if ( classAttr === 'group') {
                result += comma + groupToJson(children[i]);         
                comma = ", ";
            } else if ( classAttr === 'textPart') {
                result += comma + textPartToJson(children[i]);                
                comma = ", ";
            } else {
                console.log("warn: skipping object in groupToJson: ", classAttr);
            }
        }
        result += "]}";
        return result;
    }

In the server application, create an equivalent object structure using GSON.

Object processJsonObject(JsonObject object) {
        if (object.has("children")) {
            Group group = new Group();
            group.setGroupType(GroupType.valueOf(object.get("groupType").getAsString().toUpperCase()));
            group.setChildren(processJsonArray(object.getAsJsonArray("children")));
            System.out.print("---start group");
            System.out.println(String.format(" (%s) ---", object.get("groupType").getAsString()));     
            processJsonArray(object.getAsJsonArray("children"));
            System.out.println("---end group---");
            return group;
        } else if (object.has("textPart")) { 
            TextPart textPart = new TextPart();
            textPart.setTextPart(object.get("textPart").getAsString());
            textPart.setEquivalent(object.get("equivalent").getAsString());
            System.out.print(object.get("textPart").getAsString());       
            System.out.println(String.format(", %s", object.get("equivalent").getAsString()));
            return textPart;
        } else {
            return null;
        }
    }
   
    Object[] processJsonArray(JsonArray array) {
        ArrayList list = new ArrayList();
        for (JsonElement element : array) {
            if (element.isJsonArray()) {
                list.add(processJsonArray((JsonArray)element));
            } else if (element.isJsonObject()) {
                list.add(processJsonObject((JsonObject)element));
            } else {
                System.out.println(String.format("No object or array: %s", element));
            }
        }
        return list.toArray();
    }

I added a serialize and deserialize routine for saving the object structure. This allows the structure to be referenced by other applications.

public void serialize() {
      try
      {
         FileOutputStream fileOut =
           new FileOutputStream(context.getRealPath("/WEB-INF/templates/example.rote"));
         ObjectOutputStream out = new ObjectOutputStream(fileOut);
         out.writeObject(getRoot());
         out.close();
         fileOut.close();
         System.out.printf("Serialized data is saved in /WEB-INF/templates/example.rote");
      }catch(IOException i)
      {
         i.printStackTrace();
      }
    }
   
    public void deserialize() {
        try
      {
         FileInputStream fileIn =
           new FileInputStream(context.getRealPath("/WEB-INF/templates/example.rote"));
         ObjectInputStream in = new ObjectInputStream(fileIn);
         setRoot((Group) in.readObject());
         in.close();
         fileIn.close();
      }catch(IOException i)
      {
         i.printStackTrace();
         return;
      }catch(ClassNotFoundException c)
      {
         System.out.println("Example class not found");
         c.printStackTrace();
         return;
      }
    }

In the other application, I read the file that was created by the first application.








No comments:

Post a Comment

Followers