Zafu: KendoUI JSP taglib + Couchbase (1)


A couple a days ago I attended KendoUI Q3 announcement. Being more in the Java than C# side I was very excited about JSP taglib (again, zillions of thanks).

Just one hour after finishing the presentation I connected to Couchbase 2.0 webinar on Couchbase App Development.

Few hours latter (about 4 working hours) I finished writing some code using both together.

Why took me almost 4 hours?

  1. Just as a little of feedback I admit that before this I didn’t write a single line of code for Couchbase (many for CouchDB using Java Client libraries as well as CouchApp) but they are not the same and they do not use the same Java Client library.
  2. I have written many lines of code for KendoUI using HTML5 + JavaScript (never ASP and C#), created new KendoUI widgets (and even fixed some bugs in KendoUI). BUT KendoUI JSP taglib is new, so I did not have experience on KendoUI JSP taglib neither on the server side, so a little of challenge.
  3. But this was not where I spend most of the time 😦 It was because Couchbase Java Client (plus the libraries that come with it), is for Java 6 while KendoUI JSP taglib is for Java 7 so I had to figure out how to run both together under Apache Tomcat (and this took me more than 2 hours).

@toddanglin,@BrandonSatrom,@JohnBristowe,@burkeholland,@alex_gyoshev Would be possible to have your taglib **officially** release for Java 6 too? You just need to change a couple of lines of code 😉

What I did in the remaining two hours was…

When you install Couchbase 2.0, you are prompted (at least I was) about installing a sample database (a list of almos 6000 beers!!!).

So, I’ve decide to display in a grid those (almost) 6000 records (name, abv, category and style) and being able to navigate them. NOTE: For this first example I will not be doing server side paging, filtering,… By the end of the experiment (I live in Europe) it was almost 1am and I went to sleep.

What did I need to write:

  1. Java Server Page (JSP) using KendoUI taglib (not much documentation on how to use it but looking their example was enough for me).
  2. Servlet invoked by KendoUI DataSource transport read for retrieving the data, this is Java and uses Couchbase Java Client Library.
  3. Couchbase view for extracting the list of beers (this is a MapReduce function).

Kendo UI JSP taglib

This is what I wrote.

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="kendo" uri="http://www.kendoui.com/jsp/tags" %>
<html>
<head>
    <title>Powered by Zafu: OnaBai 2012 (c)</title>
    <!-- Kendo UI Web styles-->
    <link href="styles/kendo.common.min.css" rel="stylesheet" type="text/css"/>
    <link href="styles/kendo.silver.min.css" rel="stylesheet" type="text/css"/>

    <!-- Kendo UI Web scripts-->
    <script src="js/jquery.min.js" type="text/javascript"></script>
    <script src="js/kendo.web.min.js" type="text/javascript"></script>

    <style type="text/css">
        html {
            font-family: "Arial", sans-serif;
            font-weight: 300;
            font-variant: normal;
            font-style: normal;
            font-size: 12px;
        }

        table[role="grid"] {
            font-size: 1em;
        }
    </style>
</head>
<body>
<kendo:window name="main" title="Powered by Zafu: OnaBai 2012 (c)" minHeight="450" minWidth="700" maxWidth="700">

    <kendo:grid name="grid" pageable="true" sortable="true" filterable="false" groupable="false">
        <kendo:grid-columns>
            <kendo:grid-column title="Name" field="name"/>
            <kendo:grid-column title="ABV" field="abv" format="{0:n1}" width="50px"/>
            <kendo:grid-column title="Style" field="style"/>
            <kendo:grid-column title="Category" field="category"/>
        </kendo:grid-columns>
        <kendo:dataSource pageSize="10">
            <kendo:dataSource-transport>
                <kendo:dataSource-transport-read url="/ListBeer" type="GET" contentType="application/json"/>
            </kendo:dataSource-transport>
            <kendo:dataSource-schema data="data" total="total" groups="data">
                <kendo:dataSource-schema-model>
                    <kendo:dataSource-schema-model-fields>
                        <kendo:dataSource-schema-model-field name="name" type="string"/>
                        <kendo:dataSource-schema-model-field name="abv" type="number"/>
                        <kendo:dataSource-schema-model-field name="style" type="string"/>
                        <kendo:dataSource-schema-model-field name="category" type="string"/>
                    </kendo:dataSource-schema-model-fields>
                </kendo:dataSource-schema-model>
            </kendo:dataSource-schema>
        </kendo:dataSource>
    </kendo:grid>
    <div style="position: absolute; bottom: 5px;">Powered by Zafu, Couchbase 2.0 & KendoUI</div>
</kendo:window>
</body>
</html>

This JSP is equivalent to this HTML (what I have had to write in the past).

<html>
<head>
    <title>Powered by Zafu: OnaBai 2012 (c)</title>
    <!-- Kendo UI Web styles-->
    <link href="styles/kendo.common.min.css" rel="stylesheet" type="text/css"/>
    <link href="styles/kendo.black.min.css" rel="stylesheet" type="text/css"/>

    <!-- Kendo UI Web scripts-->
    <script src="js/jquery.min.js" type="text/javascript"></script>
    <script src="js/kendo.web.min.js" type="text/javascript"></script>

    <style type="text/css">
        html {
            font-family: "Arial", sans-serif;
            font-weight: 300;
            font-variant: normal;
            font-style: normal;
            font-size: 12px;
        }

        table[role="grid"] {
            font-size: 1em;
        }
    </style>
    <script type="text/javascript">
        $(document).ready(function () {
            $("#main").kendoWindow({
                title:    "Powered by Zafu: OnaBai 2012 (c)",
                minHeight:450,
                minWidth: 700,
                maxWidth: 700
            });

            $("#grid").kendoGrid({
                columns:   [
                    { field:"name", title:"Name" },
                    { field:"abv", title:"ABV", format:"{0:n1}", width:"50" },
                    { field:"style", title:"Style", format:"{0:n1}" },
                    { field:"category", title:"Category", format:"{0:n1}" }
                ],
                pageable:  true,
                sortable:  true,
                filterable:false,
                groupable: false,
                dataSource:{
                    pageSize: 10,
                    transport:{
                        read:{
                            url:        "/ListBeer",
                            type:       "GET",
                            contentType:"application/json"
                        }
                    },
                    schema:   {
                        data:  "data",
                        total: "total",
                        groups:"data",
                        model: {
                            fields:{
                                name:    { type:"string" },
                                abv:     { type:"number" },
                                style:   { type:"string" },
                                category:{ type:"string" }
                            }
                        }
                    }
                }
            })
        });
    </script>
</head>
<body>
<div id="main">
    <div id="grid"></div>
    <div style="position: absolute; bottom: 5px;">Powered by Zafu, Couchbase 2.0 & KendoUI</div>
</div>
</body>
</html>

MapReduce

function (doc, meta) {
  if (doc.type && doc.type == "beer" && doc.name) {
     emit(doc.name, doc.id);
  }
}

Couchbase 2.0 Java Client: View invocation

    public List read(String key) throws Exception {
        View view = client.getView(ViewDocument, ViewName);

        if (view == null) {
            throw new Exception("View is null");
        }

        Query query = new Query();
        // Set the key for the query based on beer name
        if (key != null) {
            query.setKey(key);
        }
        query.setStale(Stale.FALSE);
        query.setIncludeDocs(true);
        query.setDescending(false);

        ViewResponse result = client.query(view, query);
        Iterator<ViewRow> itr = result.iterator();
        return IteratorUtils.toList(itr);
    }

Conclusion

Positive

  1. It works!
  2. It was not that hard!
  3. Both fit pretty nice and both are easy to start with!
  4. Even that tag libraries are pretty verbose having snippets you can type it quite fast.
  5. My IDE recognized KendoUI taglib and coloring and typing was pretty fast.

Negative

  1. KendoUI, please release Java 6 version (I know that it is pretty old but as you can see there people developing new products and  still using it).
  2. Couchbase, please upgrade to Java 7. Java 6 is pretty old otherwise it will look like Windows XP.

Pending

  1. Play with more widgets and server side paging / filtering / …
  2. See how it fits (if it actually does, I don’t think so) with my own Widgets (I have a few that I use a lot).

Neutral

  1. I think that would be nice a series of blogs exploiting the idea of JSP taglib… maybe I start one… is not that much the question of documentation as writing Guides on how to use if for practical cases.