Tuesday, 30 October 2012

Spring and JSON

The integration between Spring and JSON objects is very strong and can be incredibly useful from a client web app.

Spring Setup

Spring requires very little setup.  Provided the Jackson classes are on the classpath

    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>1.9.7</version>
        <scope>compile</scope>
    </dependency>

Then spring is basically ready to go!

Returning JSON

Returning JSON to the client is the easiest part. Just return a class or list of classes from the spring MVC controller method and it will be transformed into JSON automagically and be available to the client.  The key piece of magic here is the @ResponseBody tag which tells spring that the return value should make up the whole of the response body of the Http Response. Also the produces = .. value tells spring to use the Jackson processor because we can the application/json mime type as the output.

Here is an example


    @RequestMapping(value = "/gettopics", method = RequestMethod.GET, produces = "application/json")
    @ResponseBody
    public List<String> getTopics(final HttpServletRequest request)
    {
        final List<String> topics = new ArrayList<String>();
        topics.add("topic1");
        topics.add("topic2");

        return topics;
    }


Here the topics List object gets changed to a javascript list.  This can be processed on the client side by getting a result object

    for (var i=0; i<result.length; i++){
        alert(result[i]);
    }

And that is basically it.  Obviously your choice of javascript library to do the ajax request will have an impact here.  JQuery or Dojo would be the most common.

Accepting JSON

Accepting an json object into a Spring MVC method is a little more tricky.  Firstly you have to create an object to marshal into such as

    public class JsonExample {

        /** Value 1. */
        private final String value1;

        /** Value 2. */
        private final String value2;

        /**
         * Construct this object.  The benefit here is that this object is now immutable.
         */
        @JsonCreator
        public JsonExample(@JsonProperty("value1") final String value1,
                           @JsonProperty("value2") final String value2){
            this.value1 = value1;
            this.value2 = value2;
        }

        /**
         * Get the first value
         */
        public String getValue1(){
            return value1;
        }
    }

The annotations here tell Jackson how to marshal the JSON into this java object.  However, if you don't want an immutable object you just create getters and setters and you don't need any annotations at all! In the MVC controller method we simply have a @RequestBody rather than @ResponseBody this time and it all just works.


    @RequestMapping(value = "/settopics", method = RequestMethod.POST)
    @ResponseBody
    public void setTopics(final HttpServletRequest request, @RequestBody final JsonExample jsonExample)
    {
        ...
    }

Here the @ResponseBody seems like it should be surplus to requirements but the client doesn't like it if it isn't there.

In the web client a Javascript object is created

    var topics = {
        value1 : 'my topic',
        value2 : 'another topic'
    };

    var stringToSend = json.stringify(topics);

Again the choice of javascript library to make this call is down to the user but here the dojo/json module has been used.  The content headers need to be set on the post request


    Content-Type : 'application/json'

Posting a List of Objects

You would think that if you posted a list of object then you could just declare List<JsonExample> in the spring method but unfortunately this doesn't work.  Instead you have to declare an extension to the List object such as

    public class JsonExampleList extends ArrayList<JsonExample> {
        private static final long serialVersionUID = 3412220511906097746L;
    }

It doesn't require anything in it at all but helps Jackson sort out what you really mean and then the marshalling can continue.  Without doing this Jackson will convert to a LinkedHashMap of values and you can process this manually if you want to but the tip above will help Jackson sort it out.

Oracle Spatial

Here are a few reminders for how to do the Oracle Spatial stuff

Using a Spatial Column

To use a spatial column in a table you need to create spatial metadata and a spatial index.  In SQL Developer you can do this by right clicking on the table and choosing Spatial - Update Spatial Metadata and Spatial - Create Spatial Index.  At this point many standard tools will be able to query and display the geometry out of the box.

Tools

uDig
http://udig.refractions.net/
Displays a Oracle Spatial Geometry by just choosing the column.  It is based on the Eclipse RCP (Rich Client Platform)

Georaptor
http://sourceforge.net/projects/georaptor/
A useful plugin for SQL Developer which makes the creation of the index and metadata more simple.  It has a viewer which is available within SQL Developer.

Validating Geometry

To validate a geometry column in a table you can use

    select sdo_geom.validate_geometry(<column_name>, 0.05) from <table_name>

where 0.05 is a tolerance value.


















Thursday, 4 October 2012

Dojo DataGrid

Dojo has a number of table type tools that can be used.  TableContainer helps with a table layout (see http://dojotoolkit.org/reference-guide/dojox/layout/TableContainer.html) but to display a genuine table of data the DataGrid is excellent.

Links / Docs

ItemFileWriteStore: http://dojotoolkit.org/reference-guide/dojo/data/ItemFileWriteStore.html
DataGrid: http://dojotoolkit.org/reference-guide/dojox/grid/DataGrid.html

Require / Define

Functionality required for the DataGrid is available in the following modules.

    dojo/data/ItemFileWriteStore
    dojox/grid/DataGrid

are needed to be able to use the DataGrid.  (I have in the past had some problems with the order of the require / define and putting the DataGrid towards the end of the list seemed to cure this).

ItemFileWriteStore / ItemFileReadStore

Both of these object back the DataGrid amongst other things (Tree for example).  They are relatively easy to configure.  In the most basic form just create a JSON object of rows such as


    var hardwareList = [
        { name: 'PC',          partNo: 'PC1',     available: true,  cost: 250.00},
        { name: 'Netbook', partNo: 'N1233', available: false, cost: 150.00},
        { name: 'Tablet',     partNo: 'IP3',       available: false, cost: 550.00},
        { name: 'Phone',     partNo: 'SGS3',   available: true,  cost: 350.00}    ];

Next create a wrapper JSON object which includes the name of the identifier here it is the 'name' attribute in the JSON data but it could be any attribute. Finally create the store

    var data = {identifier: "name", items: hardwareList};
    var store = new dojo.data.ItemFileWriteStore({data: data});

DataGrid

Now that we have the data we can create the DataGrid. We need to create the layout for this grid to say which bits of data make up with columns etc


    var layout = [[
        {'name': 'Name',    'field': 'name',   'width': '100px'},
        {'name': 'Part No', 'field': 'partNo', 'width': '70px'},
        {'name': 'Cost',    'field': 'cost',   'width': '70px'}
    ]];


Here the 'name' is the column name, the 'field' is the data attribute and 'width' is the column width.  This layout can then be used in the construction of the DataGrid


    var grid = new dojox.grid.DataGrid({
                                    id: 'myDataGridId',
                                    store: store,
                                    structure: layout,
                                    onRowClick: function(e){
                                        var rowIndex = e.rowIndex;
                                        var available = grid.store.getValue(grid.getItem(rowIndex), 'available');
                                            if (available){
                                                ...
                                            }
                                    }
    });

    grid.placeAt("myDivToReplace");
    grid.startup();



Here the id is the name of the DataGrid object in the html dom.  The store is the data created earlier, and the layout is the column information above.  There are a number of event handlers which can be added and the onRowClick is shown here.  Within the onRowClick is the call

    grid.store.getValue(grid.getItem(rowIndex), 'available')

which shows how to get the correct data out of the store irrespective of the sorting that is going on.  If you just use the rowIndex on the hardwareList object then a sort on the column will give you the wrong result so this has to be used.  Finally set the grid locaion and call startup.

NOTE:  If the 'myDivToReplace' has no height then the DataGrid will have no height and not appear.  Set the height of the div you are replacing and the DataGrid will occupy that space.

Tuesday, 25 September 2012

Dojo Topic

Dojo provides a really useful topic based messaging system that can be used to send messages between decoupled pieces of javascript.

require / define

To use the topic functionality just include

    "dojo/topic"

at the top of the javascript file in the require or define section


Subscribe / Publish

It is really easy to use this functionality.  Firstly subscribe to a topic where the topic has a particular string name and a function to call as a result of a message,


    topic.subscribe("/log/add", function(message) {
        console.log(message);
    });


Now everytime a publish is done to the /log/add topic the function will be called.

To publish to that topic

    topic.publish("/log/add", "the message");

The publish subscribe isn't limited to one variable and can be passed multiple values.

That's really all there is to it.  The functionality is incredibly useful for larger web apps and particularly where the app code has been split into different modules and not all modules know about each other.  It helps to keep the hierarchy correct.


Tuesday, 18 September 2012

Dojo Mouse and Keyboard Events

Keyboard events in dojo are pretty easy for the most part!  You can just use the on() function to attach them and you are done! The on function is part of the "dojo/on" module which will need to be part of the require or define declaration.

Example to catch mouse down events on a particular dom


    on(registry.byId("myDiv"), 'mousedown', function(evt){
        console.log("Mouse Down Event");
    });


Catch keyup events on an input area.


    on(registry.byId("search"), "keyup", function(evt) {                
        doSearch(registry.byId("search").get('value'));
    });


The biggest problem arises when you want to catch a keyboard event on a dom object which doesn't normally accept keyboard input such as a div, span etc.  In this case you need to make it focusable and by far the easiest way to do that is to add a tabIndex.

    dom.byId("myDiv").tabIndex = 0; // Allow key events
    on(dom.byId("myDiv"), 'keypress', function(evt){
        console.log("KeyPress Event");
    });

You can use the dojo/keys module to check for the key value just like in Java Swing.


    if (evt.keyCode == dojo.keys.LEFT_ARROW){

    } else if (evt.keyCode == dojo.keys.RIGHT_ARROW) {

    }




Thursday, 13 September 2012

Useful Tools

Here is a list of useful tools that I have come across.  I'm always forgetting what I've found so here is a list!

Development Tools

Toad
http://www.toadworld.com/
Brilliant SQL editor and database management tool.

Console
http://sourceforge.net/projects/console/
Really useful Windows Command wrapper with gives tabs, resizing, etc

MPutty
http://ttyplus.com/multi-tabbed-putty/
Manages multiple putty windows

SoapUI
http://www.soapui.org/
Tool for testing soap services.

IETester
http://www.my-debugbar.com/wiki/IETester/HomePage
Tester to allow rendering in multiple different IE versions.

SourceTree
https://www.sourcetreeapp.com/
Windows app for accessing Git repositories

Text Editors

JEdit
http://www.jedit.org/index.php?page=download
Great cross-platform tool.  Drag to select is cool as is the encoding support.

Textpad
http://www.textpad.com/
Good integration with windows.

Notepad++
http://notepad-plus-plus.org/download
Good general text editor.

Zip / Archive

7-zip
http://www.7-zip.org/
Easily the best free zipper around (IMHO!)

File Transfer

Filezilla
http://filezilla-project.org/
Free FTP file transfer tool - very good.

WinSCP
http://winscp.net/eng/index.php
Another good FTP / SFTP tool.

PC Cleanup

CCleaner
http://www.piriform.com/ccleaner/download
Cleans up temp files and scans and cleans registry.


Audio / Visual

HD Converter
www.koyotesoft.com

Converts HD formats.

Camstudio
http://camstudio.org/
Record video / audio from the activity on your computer.

GIMP
http://www.gimp.org/
GNU Image Manipulation Program.

Audacity
http://audacity.sourceforge.net/
Music file manipulation.

Virus / Malware

Malwarebytes
http://www.malwarebytes.org/
Good malware and virus scanner.

Spybot
http://www.safer-networking.org/dl/
Good spyware killer.

Sophos Anti-rootkit
http://www.sophos.com/en-us/products/free-tools/sophos-anti-rootkit.aspx
Tries to find and remote root-kits from your computer.

Wednesday, 12 September 2012

Dojo Layouts

There are a number of layout mechanisms in Dojo.  These allow layouts to be quite simply performed but to give great results.

ContentPane

This is a simple holder and can be used to hold any standard html or dijit widgets.  It is constructed by using,

    <div id="myContent" data-dojo-type="dijit.layout.ContentPane">

As with all widgets dojo will expand out this div into multiple layers.

Reference: http://dojotoolkit.org/reference-guide/dijit/layout/ContentPane.html for more details.

BorderContainer

The border container gives a top, bottom, left, right and center region that another pane can be added to.  This makes Headers, Menus and footers incredibly easy to create.  It works in a very similar way to the java swing BorderLayout.

    <div id="myContent" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="liveSplitters:true">
        <div id="myTop" data-dojo-type="dijit.layout.ContentPane"  data-dojo-props="region:'top', splitter:true">...</div>
        <div id="myCenter" data-dojo-type="dijit.layout.ContentPane"  data-dojo-props="region:'center'">...</div>
    </div>

Note the difference between 'Headline' and 'Sidebar' views. Headline has the top and bottom having 100% width but sidebar has the left and right having 100% height.

To allow the user to move the regions include data-dojo-props="liveSplitters:true" to the BorderContainer div and put data-dojo-props="splitters:true" on the regions you want to be able to resize.

Reference: http://dojotoolkit.org/reference-guide/dijit/layout/BorderContainer.html
Tests: http://archive.dojotoolkit.org/nightly/dojotoolkit/dijit/tests/layout/BorderContainer.html

AccordionPane

Accordions can make very useful tools for menus or tools.  They are easy to set up in Dojo.  Create a div element of type diji.layout.AccordionContainer.  Nested within this create some ContentPane div elements and each will be an accordion tab.


    <div id="accordionContainer" data-dojo-type="dijit.layout.AccordionContainer">
        <div id="menuPane" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title: 'Menu'">
            ...
        </div>
    </div>


Reference: http://dojotoolkit.org/reference-guide/dijit/layout/AccordionContainer.html
Tests: http://archive.dojotoolkit.org/nightly/dojotoolkit/dijit/tests/layout/AccordionContainer.html