Rick

Rick
Rick

Saturday, March 8, 2014

Java Boon - Boon path expressions for Java instances, Map/List and JSON

Boon Home | Boon Source | If you are new to boon, you might want to start here. Simple opinionated Java for the novice to expert level Java Programmer. Low Ceremony. High Productivity. A real boon to Java to developers!

Java Boon - Boon path expressions for Java instances, Map/List and JSON

Many languages have path expressions. Boon adds this to Java.

Boon has powerful path expressions that work with objects, lists and maps. It also works with JSON. Full examples of Java, Maps/Lists and JSON are included in this tutorial.
It supports expressions like:
  • [0].name
  • [1].employees
  • this.employees
  • name
  • employees.firstName
  • employees.contactInfo.phoneNumbers
The power in these expressions compared to many other similar efforts is Boon will happily traverse lists of lists of lists to retrieve a property and return back a single list. There are few path expressions that do this. It is crazy powerful.
The path expressions makes the basis of the Boon in-memory object query system (Boon Data Repo), the handlebars engine (Boon Templates), the JSTL engine (Boon Templates), the velocity engine (Boon Templates) and the free marker engine (Boon Templates). The path expressions also gets used by ** Boon Dependency Injection** and Boon Validation framework.
You can use them as well. They are quite accessible. Let's review. First step, let's create some objects to do some path expressions against. (Also you will need the latest snapshot of 0.12 or 0.13 or later as I fixed some issues as I wrote the docs which is always a good reason for writing docs).

Path Expressions with instances of Java classes

For the sake of brevity, I will leave out the getter/setter/toString/equals/hashCode and misc Java trivia. The complete listing will be at the end of the page.
    public class ContactInfo {
        String address;
        List<String> phoneNumbers;
        ...
    }

    public static class Employee {
        int id;
        int salary;
        String firstName;
        String lastName;

        ContactInfo contactInfo = new ContactInfo();

        ...
     }


    public static class Department {
        private String name;

        private List<Employee> employees;

        ...

        //See NOTE below
        public Department add(Employee... employees) {
            this.employees = lazyAdd(this.employees, employees);
            return this;
        }
    }
    //NOTE: 
    // Utility function in Boon to only create a list if you add items to it.
    // Without lazy add, you need to check for null and then create the list, this
    // gets rid of 4 or 5 lines of boiler plate code every time you want to lazy init a list, set, map, etc.
    public static <T> List<T> lazyAdd(List<T> list, T... items) {
        list = list == null ? new ArrayList<T>() : list;

        for (T item : items) {
            list.add(item);
        }
        return list;
    }

Now I create a couple of departments with a few employees in each department as follows:
        List<Department> departments = list(
                new Department("Engineering").add(
                        new Employee(1, 100, "Rick", "Hightower", "555-555-1212"),
                        new Employee(2, 200, "John", "Smith", "555-555-1215", "555-555-1214", "555-555-1213"),
                        new Employee(3, 300, "Drew", "Donaldson", "555-555-1216"),
                        new Employee(4, 400, "Nick", "LaySacky", "555-555-1217")

                ),
                new Department("HR").add(
                        new Employee(1, 100, "Dianna", "Hightower", "555-555-1218"),
                        new Employee(2, 200, "Derek", "Smith", "555-555-1219"),
                        new Employee(3, 300, "Tonya", "Donaldson", "555-555-1220"),
                        new Employee(4, 400, "Sue", "LaySacky", "555-555-1221")

                )
        );

Now that we setup some objects, let's see how the path expressions work. Boon has the puts method like Ruby.

Path expression [0].name to grab department name from first item in list

        puts ( "get the name of the first department",
                indexOf( departments, "[0].name") );

The path expression "[0].name" evaluates to get the first item in the departments list ("[0]") and then get the department name (".name")property or field from that item.
The above outputs:
get the name of the first department Engineering 

[1].employees Get the employees from the second department

putl("get the employees from the second department",
                indexOf(departments, "[1].employees"));
Note that the putl command is like the puts, but it puts each item on its own line and if one of the items is a list it outputs that as well each on its own line.
The indexOf gets a list of employees from the second department (List employees).

get the employees from the second department
Employee{id=1, salary=100, firstName='Dianna', lastName='Hightower'}

Employee{id=2, salary=200, firstName='Derek', lastName='Smith'}

Employee{id=3, salary=300, firstName='Tonya', lastName='Donaldson'}

Employee{id=4, salary=400, firstName='Sue', lastName='LaySacky'}


this.employees to get all employees

        putl("get all employees in all departments",
                indexOf(departments, "this.employees"));
The expression this.employees to get all employees from every department. Ponder on that for a moment. It is an important concept.
The this is optional. It might make the code more readable if you have a root object. The indexOf in this example returns a List containing all of the employees from each department
get all employees in all departments
Employee{id=1, salary=100, firstName='Rick', lastName='Hightower'} 
Employee{id=2, salary=200, firstName='John', lastName='Smith'} 
Employee{id=3, salary=300, firstName='Drew', lastName='Donaldson'} 
Employee{id=4, salary=400, firstName='Nick', lastName='LaySacky'} 
Employee{id=1, salary=100, firstName='Dianna', lastName='Hightower'} 
Employee{id=2, salary=200, firstName='Derek', lastName='Smith'} 
Employee{id=3, salary=300, firstName='Tonya', lastName='Donaldson'} 
Employee{id=4, salary=400, firstName='Sue', lastName='LaySacky'} 

Getting the name of every department

        puts ( "Get the name of every department",
                indexOf(departments, "name") );
The indexOf returns a list of Strings.
Get the name of every department [Engineering, HR] 

employees.firstName Get the first name of every employee in every department

        puts ( "get the first name of every employee",
                indexOf(departments, "employees.firstName") );
The indexOf returns a list of strings of every firstName of every employee in each department.
get the first name of every employee [Rick, John, Drew, Nick, Dianna, Derek, Tonya, Sue] 

employees.contactInfo.phoneNumbers Get all phone numbers of all employees in each department

        putl("\n get the all of the phone numbers of all of the employees",
                indexOf(departments, "employees.contactInfo.phoneNumbers"));

The indexOf returns a list of strings with the phone number of every employee in every department.
get the all of the phone numbers of all of the employees
555-555-1212 
555-555-1215 
555-555-1214 
555-555-1213 
555-555-1216 
555-555-1217 
555-555-1218 
555-555-1219 
555-555-1220 
555-555-1221 
Now you say that is all well in good but I read in large JSON files of lists and maps and I need a way to slice and dice that JSON map. :)

Path Expressions with Lists and Maps

Boon does JSON too. Boon does slicing of lists and maps as well.
Boon allows you to create lists and maps on the fly with its "Gee I wish Java had Map and List literals" static utility functions. Boon is all about static utility functions. :)
So let's create the same structure, but this time let's use maps and lists instead of Java objects.
        List<?> list = list(
                    map(    "name", "Engineering",
                            "employees", list(
                               map("id", 1, "salary", 100, "firstName", "Rick", "lastName", "Hightower",
                                       "contactInfo", map("phoneNumbers",
                                                            list("555-555-1212")
                                                        )
                               ),
                               map("id", 2, "salary", 200, "firstName", "John", "lastName", "Smith",
                                       "contactInfo", map("phoneNumbers", list("555-555-1215",
                                                                    "555-555-1214", "555-555-1213"))),
                               map("id", 3, "salary", 300, "firstName", "Drew", "lastName", "Donaldson",
                                       "contactInfo", map("phoneNumbers", list("555-555-1216"))),
                               map("id", 4, "salary", 400, "firstName", "Nick", "lastName", "LaySacky",
                                       "contactInfo", map("phoneNumbers", list("555-555-1217")))

                            )
                    ),
                    map(    "name", "HR",
                        "employees", list(
                            map("id", 1, "salary", 100, "firstName", "Dianna", "lastName", "Hightower",
                                    "contactInfo",
                                        map("phoneNumbers", list("555-555-1218"))),
                            map("id", 2, "salary", 200, "firstName", "Derek", "lastName", "Smith",
                                    "contactInfo",
                                        map("phoneNumbers", list("555-555-1218"))),
                            map("id", 3, "salary", 300, "firstName", "Tonya", "lastName", "Donaldson",
                                    "contactInfo", map("phoneNumbers", list("555-555-1218"))),
                            map("id", 4, "salary", 400, "firstName", "Sue", "lastName", "LaySacky",
                                    "contactInfo", map("phoneNumbers", list("555-555-1218")))

                        )
                    )

        );

So how does indexOf work against this list of maps and lists... Let's see...

Same path expressions for lists and maps as Java instances

        puts ( "get the name of the first department",
                indexOf( departments, "[0].name") );


        putl("get the employees from the second department",
                indexOf(departments, "[1].employees"));

        puts();


        putl("get all employees in all departments",
                indexOf(departments, "this.employees"));

        puts();


        puts ( "Get the name of every department",
                indexOf(departments, "name") );

        puts();


        puts ( "get the first name of every employee",
                indexOf(departments, "employees.firstName") );

        puts();


        putl("get the all of the phone numbers of all of the employees",
                indexOf(departments, "employees.contactInfo.phoneNumbers"));

As you can see is the same and the output is very similar as well.

Same path expressions for lists and maps as Java instances begets almost same output

get the name of the first department Engineering 

get the employees from the second department
{id=1, salary=100, firstName=Dianna, lastName=Hightower, contactInfo={phoneNumbers=[555-555-1218]}} 
{id=2, salary=200, firstName=Derek, lastName=Smith, contactInfo={phoneNumbers=[555-555-1218]}} 
{id=3, salary=300, firstName=Tonya, lastName=Donaldson, contactInfo={phoneNumbers=[555-555-1218]}} 
{id=4, salary=400, firstName=Sue, lastName=LaySacky, contactInfo={phoneNumbers=[555-555-1218]}} 


get all employees in all departments
{id=1, salary=100, firstName=Rick, lastName=Hightower, contactInfo={phoneNumbers=[555-555-1212]}} 
{id=2, salary=200, firstName=John, lastName=Smith, contactInfo={phoneNumbers=[555-555-1215, 555-555-1214, 555-555-1213]}} 
{id=3, salary=300, firstName=Drew, lastName=Donaldson, contactInfo={phoneNumbers=[555-555-1216]}} 
{id=4, salary=400, firstName=Nick, lastName=LaySacky, contactInfo={phoneNumbers=[555-555-1217]}} 
{id=1, salary=100, firstName=Dianna, lastName=Hightower, contactInfo={phoneNumbers=[555-555-1218]}} 
{id=2, salary=200, firstName=Derek, lastName=Smith, contactInfo={phoneNumbers=[555-555-1218]}} 
{id=3, salary=300, firstName=Tonya, lastName=Donaldson, contactInfo={phoneNumbers=[555-555-1218]}} 
{id=4, salary=400, firstName=Sue, lastName=LaySacky, contactInfo={phoneNumbers=[555-555-1218]}} 


Get the name of every department [Engineering, Engineering] 

get the first name of every employee [Rick, John, Drew, Nick, Dianna, Derek, Tonya, Sue] 

get the all of the phone numbers of all of the employees
555-555-1212 
555-555-1215 
555-555-1214 
555-555-1213 
555-555-1216 
555-555-1217 
555-555-1218 
555-555-1218 
555-555-1218 
555-555-1218 

Using path expressions for JSON

Let's parse a JSON sting and then read then use the path expressions against the lists and maps that are returned:

JSON String

[
  {
    "name":"Engineering",
    "employees":[
      { "id":1, "salary":100, "firstName":"Rick", "lastName":"Hightower",
        "contactInfo":{
          "phoneNumbers":[
            "555-555-1212"
          ]
        }
      },
      {
        "id":2, "salary":200, "firstName":"John", "lastName":"Smith",
        "contactInfo":{
          "phoneNumbers":[
            "555-555-1215",
            "555-555-1214",
            "555-555-1213"
          ]
        }
      },
      {
        "id":3, "salary":300, "firstName":"Drew", "lastName":"Donaldson",
        "contactInfo":{
          "phoneNumbers":[
            "555-555-1216"
          ]
        }
      },
      {
        "id":4,
        "salary":400,
        "firstName":"Nick",
        "lastName":"LaySacky",
        "contactInfo":{
          "phoneNumbers":[
            "555-555-1217"
          ]
        }
      }
    ]
  },
  {
    "name":"HR",
    "employees":[
      {
        "id":1,
        "salary":100,
        "firstName":"Dianna",
        "lastName":"Hightower",
        "contactInfo":{
          "phoneNumbers":[
            "555-555-1218"
          ]
        }
      },
      {
        "id":2,
        "salary":200,
        "firstName":"Derek",
        "lastName":"Smith",
        "contactInfo":{
          "phoneNumbers":[
            "555-555-1219"
          ]
        }
      },
      {
        "id":3,
        "salary":300,
        "firstName":"Tonya",
        "lastName":"Donaldson",
        "contactInfo":{
          "phoneNumbers":[
            "555-555-1220"
          ]
        }
      },
      {
        "id":4,
        "salary":400,
        "firstName":"Sue",
        "lastName":"LaySacky",
        "contactInfo":{
          "phoneNumbers":[
            "555-555-1221"
          ]
        }
      }
    ]
  }
]
So what does the code look like.... :)
List<?> list = (List) fromJson(json); // where json is the above json String
Then the rest is the same as before.
   puts ( "get the name of the first department",
                indexOf( departments, "[0].name") );


        putl("get the employees from the second department",
                indexOf(departments, "[1].employees"));



        putl("get all employees in all departments",
                indexOf(departments, "this.employees"));



        puts ( "Get the name of every department",
                indexOf(departments, "name") );



        puts ( "get the first name of every employee",
                indexOf(departments, "employees.firstName") );




        putl("get the all of the phone numbers of all of the employees",
                indexOf(departments, "employees.contactInfo.phoneNumbers"));

Output for using indexOf against JSON

get the name of the first department Engineering 

get the employees from the second department
{id=1, lastName=Hightower, salary=100, contactInfo={phoneNumbers=[555-555-1218]}, firstName=Dianna} 
{id=2, lastName=Smith, salary=200, contactInfo={phoneNumbers=[555-555-1219]}, firstName=Derek} 
{id=3, lastName=Donaldson, salary=300, contactInfo={phoneNumbers=[555-555-1220]}, firstName=Tonya} 
{id=4, lastName=LaySacky, salary=400, contactInfo={phoneNumbers=[555-555-1221]}, firstName=Sue} 


get all employees in all departments
{id=1, lastName=Hightower, salary=100, contactInfo={phoneNumbers=[555-555-1212]}, firstName=Rick} 
{id=2, lastName=Smith, salary=200, contactInfo={phoneNumbers=[555-555-1215, 555-555-1214, 555-555-1213]}, firstName=John} 
{id=3, lastName=Donaldson, salary=300, contactInfo={phoneNumbers=[555-555-1216]}, firstName=Drew} 
{id=4, lastName=LaySacky, salary=400, contactInfo={phoneNumbers=[555-555-1217]}, firstName=Nick} 
{id=1, lastName=Hightower, salary=100, contactInfo={phoneNumbers=[555-555-1218]}, firstName=Dianna} 
{id=2, lastName=Smith, salary=200, contactInfo={phoneNumbers=[555-555-1219]}, firstName=Derek} 
{id=3, lastName=Donaldson, salary=300, contactInfo={phoneNumbers=[555-555-1220]}, firstName=Tonya} 
{id=4, lastName=LaySacky, salary=400, contactInfo={phoneNumbers=[555-555-1221]}, firstName=Sue} 


Get the name of every department [Engineering, HR] 

get the first name of every employee [Rick, John, Drew, Nick, Dianna, Derek, Tonya, Sue] 

get the all of the phone numbers of all of the employees
555-555-1212 
555-555-1215 
555-555-1214 
555-555-1213 
555-555-1216 
555-555-1217 
555-555-1218 
555-555-1219 
555-555-1220 
555-555-1221 

Here is the complete code listing for this example:

package com.examples;


import java.util.List;

import static org.boon.Boon.*;
import static org.boon.Lists.*;
import static org.boon.Maps.map;
import static org.boon.core.reflection.BeanUtils.*;
import static org.boon.primitive.Chr.multiply;

/**
 * Created by Richard on 3/8/14.
 */
public class PathExpressions {


    public static class ContactInfo {
        String address;
        List<String> phoneNumbers;



    }

    public static class Employee {
        int id;
        int salary;
        String firstName;
        String lastName;

        ContactInfo contactInfo = new ContactInfo();

        public Employee() {
        }

        public Employee(int id, int salary, String firstName, String lastName,
                        String... phoneNumbers) {
            this.id = id;
            this.salary = salary;
            this.firstName = firstName;
            this.lastName = lastName;

            for (String phone : phoneNumbers) {
                contactInfo.phoneNumbers = lazyAdd(contactInfo.phoneNumbers, phone);
            }
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public int getSalary() {
            return salary;
        }

        public void setSalary(int salary) {
            this.salary = salary;
        }

        public String getFirstName() {
            return firstName;
        }

        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }

        public String getLastName() {
            return lastName;
        }

        public void setLastName(String lastName) {
            this.lastName = lastName;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Employee employee = (Employee) o;

            if (id != employee.id) return false;
            if (salary != employee.salary) return false;
            if (firstName != null ? !firstName.equals(employee.firstName) : employee.firstName != null) return false;
            if (lastName != null ? !lastName.equals(employee.lastName) : employee.lastName != null) return false;

            return true;
        }

        @Override
        public int hashCode() {
            int result = id;
            result = 31 * result + salary;
            result = 31 * result + (firstName != null ? firstName.hashCode() : 0);
            result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
            return result;
        }

        @Override
        public String toString() {
            return "Employee{" +
                    "id=" + id +
                    ", salary=" + salary +
                    ", firstName='" + firstName + '\'' +
                    ", lastName='" + lastName + '\'' +
                    "}";
        }
    }
    public static class Department {
        private String name;

        private List<Employee> employees;

        public Department() {
        }

        public Department(String name ) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Department add(Employee... employees) {
            this.employees = lazyAdd(this.employees, employees);
            return this;
        }


        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Department that = (Department) o;

            if (employees != null ? !employees.equals(that.employees) : that.employees != null) return false;
            if (name != null ? !name.equals(that.name) : that.name != null) return false;

            return true;
        }

        @Override
        public int hashCode() {
            int result = name != null ? name.hashCode() : 0;
            result = 31 * result + (employees != null ? employees.hashCode() : 0);
            return result;
        }

        @Override
        public String toString() {
            return "Department{" +
                    "name='" + name + '\'' +
                    ", employees=" + employees +
                    '}';
        }
    }


    public static void main(String... args) {

        //int id, int salary, String firstName, String lastName

        puts (multiply('_', 30), "From JAVA Objects", multiply('_', 30), "\n");

        List<Department> departments = list(
                new Department("Engineering").add(
                        new Employee(1, 100, "Rick", "Hightower", "555-555-1212"),
                        new Employee(2, 200, "John", "Smith", "555-555-1215", "555-555-1214", "555-555-1213"),
                        new Employee(3, 300, "Drew", "Donaldson", "555-555-1216"),
                        new Employee(4, 400, "Nick", "LaySacky", "555-555-1217")

                ),
                new Department("HR").add(
                        new Employee(1, 100, "Dianna", "Hightower", "555-555-1218"),
                        new Employee(2, 200, "Derek", "Smith", "555-555-1219"),
                        new Employee(3, 300, "Tonya", "Donaldson", "555-555-1220"),
                        new Employee(4, 400, "Sue", "LaySacky", "555-555-1221")

                )
        );


        showDepartmentInfo(departments);



        puts (multiply('_', 30), "From LIST MAPS", multiply('_', 30), "\n");


        puts ("Now from lists and maps");

        List<?> list = list(
                    map(    "name", "Engineering",
                            "employees", list(
                               map("id", 1, "salary", 100, "firstName", "Rick", "lastName", "Hightower",
                                       "contactInfo", map("phoneNumbers",
                                                            list("555-555-1212")
                                                        )
                               ),
                               map("id", 2, "salary", 200, "firstName", "John", "lastName", "Smith",
                                       "contactInfo", map("phoneNumbers", list("555-555-1215",
                                                                    "555-555-1214", "555-555-1213"))),
                               map("id", 3, "salary", 300, "firstName", "Drew", "lastName", "Donaldson",
                                       "contactInfo", map("phoneNumbers", list("555-555-1216"))),
                               map("id", 4, "salary", 400, "firstName", "Nick", "lastName", "LaySacky",
                                       "contactInfo", map("phoneNumbers", list("555-555-1217")))

                            )
                    ),
                    map(    "name", "HR",
                        "employees", list(
                            map("id", 1, "salary", 100, "firstName", "Dianna", "lastName", "Hightower",
                                    "contactInfo",
                                        map("phoneNumbers", list("555-555-1218"))),
                            map("id", 2, "salary", 200, "firstName", "Derek", "lastName", "Smith",
                                    "contactInfo",
                                        map("phoneNumbers", list("555-555-1219"))),
                            map("id", 3, "salary", 300, "firstName", "Tonya", "lastName", "Donaldson",
                                    "contactInfo", map("phoneNumbers", list("555-555-1220"))),
                            map("id", 4, "salary", 400, "firstName", "Sue", "lastName", "LaySacky",
                                    "contactInfo", map("phoneNumbers", list("555-555-1221")))

                        )
                    )

        );


        showDepartmentInfo(list);



        puts (multiply('_', 30), "From JSON", multiply('_', 30), "\n");


        String json = toJson(list);
        puts (json);

        showDepartmentInfo((List) fromJson(json));


    }



    private static void showDepartmentInfo(List<?> departments) {
        puts ( "get the name of the first department",
                indexOf( departments, "[0].name") );


        putl("get the employees from the second department",
                indexOf(departments, "[1].employees"));

        puts();


        putl("get all employees in all departments",
                indexOf(departments, "this.employees"));

        puts();


        puts ( "Get the name of every department",
                indexOf(departments, "name") );

        puts();


        puts ( "get the first name of every employee",
                indexOf(departments, "employees.firstName") );

        puts();


        putl("get the all of the phone numbers of all of the employees",
                indexOf(departments, "employees.contactInfo.phoneNumbers"));
    }
}

Full output

______________________________ From JAVA Objects ______________________________ 

get the name of the first department Engineering 
get the employees from the second department
Employee{id=1, salary=100, firstName='Dianna', lastName='Hightower'} 
Employee{id=2, salary=200, firstName='Derek', lastName='Smith'} 
Employee{id=3, salary=300, firstName='Tonya', lastName='Donaldson'} 
Employee{id=4, salary=400, firstName='Sue', lastName='LaySacky'} 


get all employees in all departments
Employee{id=1, salary=100, firstName='Rick', lastName='Hightower'} 
Employee{id=2, salary=200, firstName='John', lastName='Smith'} 
Employee{id=3, salary=300, firstName='Drew', lastName='Donaldson'} 
Employee{id=4, salary=400, firstName='Nick', lastName='LaySacky'} 
Employee{id=1, salary=100, firstName='Dianna', lastName='Hightower'} 
Employee{id=2, salary=200, firstName='Derek', lastName='Smith'} 
Employee{id=3, salary=300, firstName='Tonya', lastName='Donaldson'} 
Employee{id=4, salary=400, firstName='Sue', lastName='LaySacky'} 


Get the name of every department [Engineering, HR] 

get the first name of every employee [Rick, John, Drew, Nick, Dianna, Derek, Tonya, Sue] 

get the all of the phone numbers of all of the employees
555-555-1212 
555-555-1215 
555-555-1214 
555-555-1213 
555-555-1216 
555-555-1217 
555-555-1218 
555-555-1219 
555-555-1220 
555-555-1221 

______________________________ From LIST MAPS ______________________________ 

Now from lists and maps 
get the name of the first department Engineering 
get the employees from the second department
{id=1, salary=100, firstName=Dianna, lastName=Hightower, contactInfo={phoneNumbers=[555-555-1218]}} 
{id=2, salary=200, firstName=Derek, lastName=Smith, contactInfo={phoneNumbers=[555-555-1219]}} 
{id=3, salary=300, firstName=Tonya, lastName=Donaldson, contactInfo={phoneNumbers=[555-555-1220]}} 
{id=4, salary=400, firstName=Sue, lastName=LaySacky, contactInfo={phoneNumbers=[555-555-1221]}} 


get all employees in all departments
{id=1, salary=100, firstName=Rick, lastName=Hightower, contactInfo={phoneNumbers=[555-555-1212]}} 
{id=2, salary=200, firstName=John, lastName=Smith, contactInfo={phoneNumbers=[555-555-1215, 555-555-1214, 555-555-1213]}} 
{id=3, salary=300, firstName=Drew, lastName=Donaldson, contactInfo={phoneNumbers=[555-555-1216]}} 
{id=4, salary=400, firstName=Nick, lastName=LaySacky, contactInfo={phoneNumbers=[555-555-1217]}} 
{id=1, salary=100, firstName=Dianna, lastName=Hightower, contactInfo={phoneNumbers=[555-555-1218]}} 
{id=2, salary=200, firstName=Derek, lastName=Smith, contactInfo={phoneNumbers=[555-555-1219]}} 
{id=3, salary=300, firstName=Tonya, lastName=Donaldson, contactInfo={phoneNumbers=[555-555-1220]}} 
{id=4, salary=400, firstName=Sue, lastName=LaySacky, contactInfo={phoneNumbers=[555-555-1221]}} 


Get the name of every department [Engineering, HR] 

get the first name of every employee [Rick, John, Drew, Nick, Dianna, Derek, Tonya, Sue] 

get the all of the phone numbers of all of the employees
555-555-1212 
555-555-1215 
555-555-1214 
555-555-1213 
555-555-1216 
555-555-1217 
555-555-1218 
555-555-1219 
555-555-1220 
555-555-1221 

______________________________ From JSON ______________________________ 

[{"name":"Engineering","employees":[{"id":1,"salary":100,"firstName":"Rick","lastName":"Hightower","contactInfo":{"phoneNumbers":["555-555-1212"]}},{"id":2,"salary":200,"firstName":"John","lastName":"Smith","contactInfo":{"phoneNumbers":["555-555-1215","555-555-1214","555-555-1213"]}},{"id":3,"salary":300,"firstName":"Drew","lastName":"Donaldson","contactInfo":{"phoneNumbers":["555-555-1216"]}},{"id":4,"salary":400,"firstName":"Nick","lastName":"LaySacky","contactInfo":{"phoneNumbers":["555-555-1217"]}}]},{"name":"HR","employees":[{"id":1,"salary":100,"firstName":"Dianna","lastName":"Hightower","contactInfo":{"phoneNumbers":["555-555-1218"]}},{"id":2,"salary":200,"firstName":"Derek","lastName":"Smith","contactInfo":{"phoneNumbers":["555-555-1219"]}},{"id":3,"salary":300,"firstName":"Tonya","lastName":"Donaldson","contactInfo":{"phoneNumbers":["555-555-1220"]}},{"id":4,"salary":400,"firstName":"Sue","lastName":"LaySacky","contactInfo":{"phoneNumbers":["555-555-1221"]}}]}] 
get the name of the first department Engineering 
get the employees from the second department
{id=1, lastName=Hightower, salary=100, contactInfo={phoneNumbers=[555-555-1218]}, firstName=Dianna} 
{id=2, lastName=Smith, salary=200, contactInfo={phoneNumbers=[555-555-1219]}, firstName=Derek} 
{id=3, lastName=Donaldson, salary=300, contactInfo={phoneNumbers=[555-555-1220]}, firstName=Tonya} 
{id=4, lastName=LaySacky, salary=400, contactInfo={phoneNumbers=[555-555-1221]}, firstName=Sue} 


get all employees in all departments
{id=1, lastName=Hightower, salary=100, contactInfo={phoneNumbers=[555-555-1212]}, firstName=Rick} 
{id=2, lastName=Smith, salary=200, contactInfo={phoneNumbers=[555-555-1215, 555-555-1214, 555-555-1213]}, firstName=John} 
{id=3, lastName=Donaldson, salary=300, contactInfo={phoneNumbers=[555-555-1216]}, firstName=Drew} 
{id=4, lastName=LaySacky, salary=400, contactInfo={phoneNumbers=[555-555-1217]}, firstName=Nick} 
{id=1, lastName=Hightower, salary=100, contactInfo={phoneNumbers=[555-555-1218]}, firstName=Dianna} 
{id=2, lastName=Smith, salary=200, contactInfo={phoneNumbers=[555-555-1219]}, firstName=Derek} 
{id=3, lastName=Donaldson, salary=300, contactInfo={phoneNumbers=[555-555-1220]}, firstName=Tonya} 
{id=4, lastName=LaySacky, salary=400, contactInfo={phoneNumbers=[555-555-1221]}, firstName=Sue} 


Get the name of every department [Engineering, HR] 

get the first name of every employee [Rick, John, Drew, Nick, Dianna, Derek, Tonya, Sue] 

get the all of the phone numbers of all of the employees
555-555-1212 
555-555-1215 
555-555-1214 
555-555-1213 
555-555-1216 
555-555-1217 
555-555-1218 
555-555-1219 
555-555-1220 
555-555-1221 

FAQ

What about XPath and GPath style expressions? Boon does not have those yet. If it added them, then it would be a different function name than indexOf (also called idx). Boon does have the DataRepo which uses Boon path expressions to query objects with all manners of criteria, but the criteria objects take path expression not the other way around. You can do the same sorts of things as XPath or GPath but the syntax is not as small. What Boon really needs is a small expression language of some sorts....

Thoughts

Thoughts? Write me at richard high tower AT g mail dot c-o-m (Rick Hightower).

Further Reading:

If you are new to boon start here:

Why Boon?

Easily read in files into lines or a giant string with one method call. Works with files, URLs, class-path, etc. Boon IO support will surprise you how easy it is. Boon has Slice notation for dealing with Strings, Lists, primitive arrays, Tree Maps, etc. If you are from Groovy land, Ruby land, Python land, or whatever land, and you have to use Java then Boon might give you some relief from API bloat. If you are like me, and you like to use Java, then Boon is for you too. Boon lets Java be Java, but adds the missing productive APIs from Python, Ruby, and Groovy. Boon may not be Ruby or Groovy, but its a real Boon to Java development.

Core Boon Philosophy

Core Boon will never have any dependencies. It will always be able to run as a single jar. This is not just NIH, but it is partly. My view of what Java needs is more inline with what Python, Ruby and Groovy provide. Boon is an addition on top of the JVM to make up the difference between the harder to use APIs that come with Java and the types of utilities that are built into Ruby, Python, PHP, Groovy etc. Boon is a Java centric view of those libs. The vision of Boon and the current implementation is really far apart.
Kafka and Cassandra support, training for AWS EC2 Cassandra 3.0 Training