JsonContainer

Hi,

I recently released the first version of
JsonContainer
add-on. The add-on is very simple but still provides a nice demo and might be of use when you quickly want to prototype displaying JSON formatted data in your Vaadin application.

Please take a look at the
demo application
and let me know what you think. This first release is quite limited in functionality and the JSON conversion works only in one direction. Possibly in later versions I might add a way to edit the container and get the new state out as JSON.

  • Teemu

Hi,

Looks like a nice addon. I tried to use it but no go. It didn’t like this json string:

{“host”:“Mark-M14x”,“version”:“2.0.6”,“process”:“mongod”,“uptime”:514.0,“uptimeEstimate”:511.0,“localTime”:{“$date”:“2012-07-24T14:51:21.599Z”},“globalLock”:{“totalTime”:5.13949613E8,“lockTime”:211012.0,“ratio”:4.1056943066518077E-4,“currentQueue”:{“total”:0,“readers”:0,“writers”:0},“activeClients”:{“total”:0,“readers”:0,“writers”:0}},“mem”:{“bits”:64,“resident”:45,“virtual”:259,“supported”:true,“mapped”:80,“mappedWithJournal”:160},“connections”:{“current”:8,“available”:19992},“extra_info”:{“note”:“fields vary by platform”,“page_faults”:12231,“usagePageFileMB”:26,“totalPageFileMB”:24378,“availPageFileMB”:17386,“ramMB”:12190},“indexCounters”:{“note”:“not supported on this platform”},“backgroundFlushing”:{“flushes”:8,“total_ms”:4,“average_ms”:0.5,“last_ms”:1,“last_finished”:{“$date”:“2012-07-24T14:50:47.669Z”}},“cursors”:{“totalOpen”:0,“clientCursors_size”:0,“timedOut”:0},“network”:{“bytesIn”:117121,“bytesOut”:605563,“numRequests”:137},“opcounters”:{“insert”:0,“query”:125,“update”:0,“delete”:0,“getmore”:11,“command”:13},“asserts”:{“regular”:0,“warning”:0,“msg”:0,“user”:0,“rollovers”:0},“writeBacksQueued”:false,“dur”:{“commits”:30,“journaledMB”:0.0,“writeToDataFilesMB”:0.0,“compression”:0.0,“commitsInWriteLock”:0,“earlyCommits”:0,“timeMs”:{“dt”:3060,“prepLogBuffer”:0,“writeToJournal”:0,“writeToDataFiles”:0,“remapPrivateView”:0}},“ok”:1.0}

which is what I get from mongo db when I call ‘db.serverStatus’

I can do the following:

    JsonParser parser = new JsonParser();
    JsonElement element = parser.parse(""+ status);
    
    System.out.println(element.toString());
//    JsonContainer dataSource = JsonContainer.Factory.newInstance(element.toString());
//    statusTable.setContainerDataSource(dataSource);

but the commented out lines throw an exception. It looks like a call to toString should be made instead of the call that is being done…

Cheers,

Mark

Hi Mark,

thanks for your comments. Unfortunately the JSON example you provided is a bit too complex for the add-on. Nested data is currently not supported. If you would take only parts of your JSON, these would work.

For example this works (try by copy-pasting
here
):

{
    "msg": 0, 
    "regular": 0, 
    "rollovers": 0, 
    "user": 0, 
    "warning": 0
}

The JsonContainer add-on is quite limited with its current version. I hope to have some time in the future to continue work on the add-on.

Hi,

I was hoping that there might be something that could be a quick fix, like calling the toString method internally. Here is the trace:

at com.google.gson.JsonElement.getAsString(JsonElement.java:185)
at org.vaadin.teemu.jsoncontainer.IndexedJsonContainer.addJsonObject(IndexedJsonContainer.java:41)
at org.vaadin.teemu.jsoncontainer.IndexedJsonContainer.(IndexedJsonContainer.java:22)
at org.vaadin.teemu.jsoncontainer.JsonContainer$Factory.newInstance(JsonContainer.java:27)

But JsonElement’s getAsString is not implemented:

public String getAsString() {
    throw new UnsupportedOperationException(getClass().getSimpleName());
  }

However, JsonElement does have a working toString method:

 /**
   * Returns a String representation of this element.
   */
  @Override
  public String toString() {
    try {
      StringWriter stringWriter = new StringWriter();
      JsonWriter jsonWriter = new JsonWriter(stringWriter);
      jsonWriter.setLenient(true);
      Streams.write(this, jsonWriter);
      return stringWriter.toString();
    } catch (IOException e) {
      throw new AssertionError(e);
    }
  }

Maybe to keep your simple add on working more robustly, toString should be called instead of getAsString…

Regardless, thanks for the effort, it might inspire me to do something similar for my use case!

Mark

Hi,

Using JSON container im getting error message “There seems to be something wrong with your JSON” Pls check the syntax."

Im thinking its because space & colon in the data.
Why the data is restricted not to contain space & colon.?

Pls any body solve this problem.

Regards,
Chethan
12556.png

Hi,

thanks for trying out my JsonContainer. The data you have tried is not valid
JSON
. You could for example put quotes around the value to make it valid.

Like this:

[{ "startDate" : "2011-01-01 00:00:00" }]

Thanx Teemu.

I got it.
I jus forgot to use “quotes”…

Regards,
Chethan

Hi,

if you’re using Ivy to resolve your dependencies, you should automatically also get the
gson-2.1.jar
into your classpath after adding the proper line to your
ivy.xml
file. If you instead download the
JsonContainer-0.1.jar
manually, you also need to download the
gson-2.1.jar
.

  • Teemu

Nope. That kind of functionality is not supported by the add-on.

Hallo Teemu,

thanks for the plugin.
I have some problems with the format of data types (decimal ##,##, date dd.mm.yyyy…), since all Values are read as String.
How do you do that in your application?
For testing i have do something like this with your Code to parse the datatypes from JSON Input.
…at bottom of IndexedJsonContainer.java

    private void addJsonObject(JsonObject jsonObject) {
        // use itemId generated by IndexedContainer
        Object itemId = addItem();
        Item i = getItem(itemId);

        for (Entry<String, JsonElement> entry : jsonObject.entrySet()) {
            //addContainerProperty(entry.getKey(), String.class, null);
            Class<?> classTyp =  getClassTyp(entry.getValue().getAsString());
             addContainerProperty(entry.getKey(), classTyp, null);
            //i.getItemProperty(entry.getKey()).setValue(entry.getValue().getAsString());
             switch (classTyp.getName()) {
            case "java.lang.Double":
                i.getItemProperty(entry.getKey()).setValue(entry.getValue().getAsDouble());
                break;
                
            case "java.lang.Long":
                i.getItemProperty(entry.getKey()).setValue(entry.getValue().getAsLong());
                break;
                
            case "java.util.Date":
                try {
                    i.getItemProperty(entry.getKey()).setValue( format.parse(entry.getValue().getAsString()) ) ;
                } catch (ReadOnlyException e) {
                    e.printStackTrace();
                } catch (ParseException e) {
                    
                    e.printStackTrace();
                }
                break;

            default:    
                i.getItemProperty(entry.getKey()).setValue(entry.getValue().getAsString());
                break;
            }
        }
    }

    private Class<?> getClassTyp(String value) {
            //Number...
             try {
                 if (value.indexOf(".")>0) {
                     Double d = null;
                     d.valueOf(value);
                    return Double.class;
                 } else {
                     Long l = null;
                     l. valueOf(value);
                     return Long.class;
                 }            
            } catch (Exception e) {
            }
             
             //Date...
             try {
                 //ISO
                 Date date = format.parse(value);
                 System.out.println("Treffer Date! "+value);
                 return Date.class;
            } catch (Exception e) {
            }
             
             return String.class;
    }

whether you can make the standard Grid using Json Container?