Skip to content
Bala Raman edited this page Mar 16, 2019 · 10 revisions

Kson is an extension of JSon and enables transformation of "pretty formatted text" to Object structures. Its not directly related to fst, however makes use of the rich reflection infrastructure of fst, so I put it in.

Extension to JSon:

  • before '{ }' optionally a type information tag can be placed (classname or a string which is internally mapped to a classname).
  • no quotes required except for strings containing whitespace or quotes themselfs
  • comments
  • no colons required in lists (optional)
  • no ':' required in maps (optional)
  • '{}' can replace '[]'. However there are last resort situations where type inference uses '[' to detect a collection or array.
  • Maps are not limited to "String" as key type

example:

test {
    aString: StringWithoutWhiteSpaceNeedNoQuotes

    # if collections/arrays are typed, no type information must be provided for an object. Just '{ .. }'
    aMap: {
        'Quoted' : { str: Hello someValue: 13 }
        UnQuoted : { str: Hello1 someValue: 14 }
        "QuotOther" : { str: Hello13 someValue: 15 }
    }

    objectMap: {
        { str: Hello someValue: 13 } : aString
        { str: Hello1 someValue: 131 } : aString1
    }

    aList: {
        {
            nameList: { a b "c c" d 'e e' }
            someValues: { 1 2 3 4 5 6 3457 }
        }
        {
            nameList: { 'Short' }
            someValues: { 1 2 3 }
        }
        {
            nameList: {}
            someValues: {}
        }
    }

    # if collections/arrays are untyped (only object supported),  objects need a type '<classname> { .. }'.
    # to avoid ugly full qualified type names, use 'map' on the KKonfig class
    untypedList: {
        pojo { str: Hello13 someValue: 15 }
        other {
            nameList: { a b "c c" d 'e e' }
            someValues: { 1 2 3 4 5 6 3457 }
        }
    }

}

Databinding

Kson tries to use types found in your class definition. The basic idea is, that you create extra classes to describe the format/fields of your kson input (e.g. for data import, testing, konfiguration files).

E.g. Point myarray[] can be defined without type annotation tag:

myarray: { { x: 13 y: 15 } { x: 17 y: 99 } }

Same would work for List or Map<String,Point>.

If you omit types (e.g. Object myArray[] or List myArray), kson expects type tags like:

myarray: { java.awt.Point { x: 13 y: 15 }  java.awt.Point { x: 17 y: 99 } }

as classnames are ugly you can do something like:

    Kson kk = new Kson()
        .map("point", Point.class);

so the example above would look like

myarray: { point { x: 13 y: 15 }  point { x: 17 y: 99 } }

Limits

Kson does some fuzzy type inference. Its not a general purpose serialization implementation. So

  • stick with pojos
  • supported collections: Map's, List's
  • Use strong typing in class definition (also for collections aka ArrayList)
  • Error messages in case of parse failure/syntax errors are pretty bad :-)
  • its pretty slow, don't use it for messaging (except you replace XML or YAML). Its faster than XML, its faster than SnakeYAML, its slower than performance optimized JSon implementations like Jackson. Its usually even with other non-optimized JSon serialization schemes. Coding style is "add 'if' until it works" :-)

Note 1: Kson can also read JSon, however the type tags have to be replaced by adding a "_type: mytype" attribute as a first attribute of an object.

Note 2: KsonSerializer/JSonSerializer do not support cyclic data structures (stackoverflow then).

Example

can be found in the test section of fst.

e.g.

public static class SomePojoConfig {
    String aString;
    HashMap<String,PojoConfigItem> aMap;
    Map<PojoConfigItem,String> objectMap;
    List<OtherPojoConfigItem> aList;
    List untypedList;
}

public static class OtherPojoConfigItem {
    String nameList[];
    int someValues[];
}

public static class PojoConfigItem {
    String str;
    int someValue;
}
[...]
Kson kk = new Kson()
          .map("test", SomePojoConfig.class)
          .map("pojo", PojoConfigItem.class)
          .map("other", OtherPojoConfigItem.class);
SomePojoConfig result = (SomePojoConfig) kk.readObject( new File("./src/test/kson/test.kson"));

can read the example at the top of this page.

Clone this wiki locally