Weblog

Creating charts using Jquery, flot and some grails

I’m getting more and more impressed by the combination of jquery and grails. Doing SOFEA/SOUI this way is in my opinion way more productive and less restrictive than using server-side generated webpages.

In a previous post i illustrated how you can implement ajax autosuggest using jquery and grails. In this post i’ll show a simple charting example.

For charting i’m using a jquery plugin called flot. Float is a javascript library which draws charts on the canvas tag.

First a grails controller which returns some data to be charted. The query returns the number of candidates per year per week. I’m using the sessionFactory to get direct access to the jdbc connection, as this kind of sql isn’t support by grails’ gorm. The sessionFactory is set by the application server using dependency injection. The results are returned to the browser in JSON format.

def sessionFactory

def kandidatenPerWeek ={
def sql = """select year, week, count(*)
from
( select extract(week from inschrijf_datum) as week
,      extract(year from inschrijf_datum) as year
,      id from kandidaat
) as kw
group by year,week
order by year, week
"""
def session = sessionFactory.getCurrentSession()
def result = session.createSQLQuery(sql).list()
render result as JSON
}

I also need an URL mapping to be able to call the controller function.

static mappings = {
"/kandidaat/aantalPerWeek/"(controller:"kandidaat"){
action = [GET:"kandidatenPerWeek"]
}
}

Next, some html code where the chart will be drawn. The div with id chartPlaceholder will contain the canvas.

<div id="kandidatenPerWeekChart">
<h2>Kandidaten per week</h2>
<div id="chartPlaceholder"></div>
</div>

And finally some javascript code to call the REST service in the grails controller, move the results into the correct javascript arrays needed for flot, and then the flot plot call to generate the chart. In the code below, i’m drawing two lines, one for the number of candidates per week in 2007 and one for candidates per week in 2008.

$.getJSON("kandidaat/aantalPerWeek/", null, function(json){
var yrs =[[],[]];
for(var i = 0; i<json.length;i++){
var year = json[i][0];
if(!yrs[year]){ yrs[year] = []; }
yrs[year].push([json[i][1],json[i][2]]);
}
$.plot($("#kandidatenPerWeekChart #chartPlaceholder"),
[ {data:yrs[2007], lines: {show:true}, label: "Kandidaten per week in 2007"},
{data:yrs[2008], lines: {show:true}, label: "Kandidaten per week in 2008"} ]
, {legend: {show:true}, xaxis:{min:0,max:53}, yaxis:{min:0,max:5}});
})

The combination of jquery and grails completely eliminates the need for server-side generated html. You just create some html pages, which get their data through ajax calls of grails rest services. The result is very much like a GWT application, but instead of writing java which is converted to javascript, you directly program using html and javascript. JQuery takes away most of the cross-browser pain.

Why you should use html header tags for titles

Here’s a nice example of what happens when you style your text to look like titles, but forget to use the semantically correct html tags. The following press-release by sony looks alright, and it’s easy to see what the title of the press-release is.
Sony press release

But techmeme seems to think that the article is called: “Resize text: A A A” as you can see in this screenshot:

Techmeme summary of the press-release

How did this happen? Well, visually it’s easy to determine what the press-releases title is, but computer programs do not really see what the page looks like. Instead they read the source code, and try to determine the title of the article from the code. And in this case, the source code is pretty bad.

Html has an easy way to specify what your headings are: h1 through h6. But some people seem to think that using divs with classes to style them as headers are better. But you loose something valueable doing this: headers are mini-summaries for your content. By using divs instead of header tags, it becomes harder to find these mini-summaries in your page source-code. And there really is no reason why you should use divs. Headers tags can be styled just as easy as div tags.

You might think, why do i care? You might even like it this way, thinking that it prevents other sites from stealing your content. But that’s a very narrow minded point of view. Links are what makes the internet work. For one, they bring you visitors. And good links bring you more visitors. And having good titles ensures that automatically generated links have good text.

But more importantly, links are really important for search engines. Every link to your sites is a vote for the content on your site. And the text in a link tells a search engine what the link author thinks the linked page is about. And it the case above, search engines will think the link points to a page about “Resize text AAA”. That will not help when people are searching cybershot camera’s.

So links tell search engines what other people think your page is about. Header tags tell search engines what you think your webpage is about. And if both are screw-up, it’s really hard for search engines to determine what your page is about. Using semantically correct tags will bring more visitors to your webpage.

Using JQuery autocomplete with Grails and JSON

It seems the documentation for this JQuery autocomplete plugin isn’t uptodate. Using a remote JSON call is actually easier that you might think from reading the docs.

In this example i’m using a Grails controller class called KandidaatController. It contains one method to find Kandidaat objects having a lastname starting with the entered string. The objects found are returned in JSON format.

def searchByNaam = {
  def kandidaat = Kandidaat.findAllByAchternaamIlike(params.q + "%")
  if ( kandidaat ) {
    render kandidaat as JSON
  } else {
    response.sendError(400, "Kandidaat niet gevonden");
  }
}

This method is made available as a REST service using the following configuration in UrlMappings:

"/kandidaat/naam/$q?"(controller:"kandidaat"){
  action = [GET:"searchByNaam"]
}

Enabling autocomplete on an input field looks like the code below. You need to specify the url of your rest service, and specify that you are using JSON. Using the function parse you need to parse the received JSON data and return an array containing objects for every row to be displayed. Every object in this array contains three properties: data (all the data for the row), value (just the value displayed), and result (the formatted value). I found that i also needed to implement formatItem, which returns the value as displayed in the autocomplete dropdown list.

  $("#zoekKandidaat_naam").autocomplete(
      // rest url
      "kandidaat/naam"
    , { dataType:"json"
      , formatItem: function(data,i,max,value,term){
          return value;
        }
      , parse: function(data){
          var acd = new Array();
          for(var i=0;i<data.length;i++){
            acd[acd.length] = { data:data[i], value:data[i].achternaam, result:data[i].achternaam };
          }
          return acd;
        }
      }
  );

Maybe it’s possible to do this with even less code, but i’m really impressed by what you can do with JQuery and Grails.

Ibatis, mapping Calendar to date

We use the genValueTypes ant-task from Oracle to generate our pojo model.

<oracle :genValueTypes schema="@{schema}" debug="true"
output="${srcgen.dir}"/>

If I create some elements of type date in my xsd and let the task generate my pojos it will generate attributes of type Calendar for me.

protected java.util.Calendar startDatum;

I’m using the next ibatis config to call a stored procedure with an inputvariable of type date :

<resultmap id="result5"
class="nl.iteye.model.Employee">
<result property="startDatum" column=" startDatum"/>
</resultmap>
<parametermap id="parameters5" class="map">
<parameter property="startDatumBegin" jdbcType="DATE"
javaType="java.util.Date" mode="IN"/>
<parameter property=" startDatumEind" jdbcType="DATE"
javaType="java.util.Date" mode="IN"/>
<parameter property="refIdBegin" jdbcType="NUMERIC"
javaType="java.lang.Integer" mode="IN"/>
<parameter property=" refIdEind" jdbcType="NUMERIC"
javaType="java.lang.Integer" mode="IN"/>
<parameter property="employees" javaType="java.sql.ResultSet"
jdbcType="ORACLECURSOR" mode="OUT" resultMap="result5"/>
<parameter property="resultaat" jdbcType="STRUCT" typeName="T_RESULTAAT"
javaType="nl.iteye.model.algemeen.ServiceResult"
mode="OUT"
typeHandler="nl.iteye.model.algemeen.typehandler.AlgemeenHandlerCallback"/>
</parametermap>
<procedure id="listEmployees" parameterMap="parameters5">
< ![CDATA[
{ call mypackage.getEmployeeList(?,?,?,?,?,?) }
]]>
</procedure>

Ibatis code :

SqlMapClient sqlMap = CustomSqlMapClient.getSqlMap(CustomSqlMapClient.LV_RESOURCE);

Map pars = new HashMap();
pars.put("startDatumBegin", startDatumBegin);
pars.put("startDatumEind", startDatumEind);
pars.put("refIdBegin", refIdBegin);
pars.put("refIdBegin", refIdBegin);

sqlMap.queryForObject("listEmployees", pars);

Ibatis won’t be able to map the startDatum from my resultMap to the startDatum of my pojo. The next error will be generated


--- Cause: com.ibatis.sqlmap.client.SqlMapException: No type handler could be found to map the property 'startDatum' to the column 'startDatum'.  One or both of the types, or the combination of types is not supported.

You could write your own serializer and i assume there will be several other solutions available. The solution I picked was to write a Calendar typehandler for ibatis.

public class CalendarTypeHandlerCallback implements TypeHandlerCallback {

public Object getResult(ResultGetter getter) throws SQLException {
Date date = getter.getDate();
Calendar calendar = null;

if (date != null) {
calendar = Calendar.getInstance();
calendar.setTime(date);
}

return calendar;
}

public void setParameter(ParameterSetter setter, Object parameter)
throws SQLException {
GregorianCalendar calendar = (GregorianCalendar) parameter;
Date date = new Date(calendar.getTimeInMillis());
setter.setDate(date);
}

public Object valueOf(String s) {
return s;
}
}

Just an easy conversion of the date to calendar.

The resultMap will now look like :

<resultmap id="result5"
class="nl.iteye.model.Employee">
<result property="startDatum" column=" startDatum"
javaType="java.util.Calendar" jdbcType="DATE" typeHandler="nl.iteye.model.algemeen.typehandler.CalendarTypeHandlerCallback"/>
</resultmap>

After running the code, ibatis will be able to do the mapping the between the date and the calendar.

Oracle releases BEA Workshop as a free eclipse plugin

Oracle Workshop has been made available as a free plugin for Eclipse. Apparently, this news has already been announced some time ago, but i just noticed it today on the serverside.com. Some interesting links: Oracle Workshop highlights, Oracle Workshop Datasheet, and Oracle BEA Products download page.

Regarding the price, the datasheet just mentions that Oracle Workshop is free of charge. It doesn’t mention any restrictions on use, eg, if you need a license of Oracle Weblogic to use it. From the info i’ve read i have concluded that it’s free for everybody.

Workshop has some interesting features missing from a standard JDeveloper installation: Maven, Spring and Hibernate support for example.

BI Publisher Pivot Table

Yesterday, when I was using the cross table functionality in Oracle BI Publisher, I retrieved an unexpected result. I had a simple dataset that contains the information of persons with their salary and office location. A simple overview where the a pivot table is very useful. The result of the report was not what I expected:
PivotTableResult1.PNG

See the first row and column containing only 0. The xml data used in this report is not strange at all. Here a small sample of the dataset:
<PERSON_SALARY>
<EUROPE>
<PERSON_SALARY>
<FUNCTION>
Administrator</FUNCTION>
<SALARY>
40000</SALARY>
<OFFICE>
Amsterdam</OFFICE>
</PERSON_SALARY>
<PERSON_SALARY>
<FUNCTION>
Administrator</FUNCTION>
<SALARY>
35000</SALARY>
<OFFICE>
Paris</OFFICE>
</PERSON_SALARY>
...
<PERSON_SALARY>
<FUNCTION>
Administrator</FUNCTION>
<SALARY>
40000</SALARY>
<OFFICE>
London</OFFICE>
</PERSON_SALARY>
<PERSON_SALARY>
<FUNCTION>
Accountant</FUNCTION>
<SALARY>
30000</SALARY>
<OFFICE>
London</OFFICE>
</PERSON_SALARY>
</EUROPE>
</PERSON_SALARY>

If you look careful at the xml you see double use of the element ‘PERSON_SALARY’. This is the reason that the result of the cross table is what we would expect. If we take a look at the xpath querys in the rtf we see the following:

pivottablefieldbrowser.PNG

There we see that all elements of ‘PERSON_SALARY’ are included in the result of the cross table. In the dataset we discovered already the double existence of this element. To validate our analysis, we renamed the root element to LIST_PERSON_SALARY and regenerated the report with the following result:

PivotTableResult2.PNG

And now we have the expected result. This example shows that the names of elements have to be rightly chosen, to avoid problems of this kind.

Update 11-08-2008:

How to create a pivot table in a BI Publisher report.

Install the BI Publisher Desktop software available from the oracle website. This installation requires also the installation of the .NET framework 2.0.

When you start MS Word you see that there is a new menu item available. Load first an xml file with data (you can use the provided xml from the blog).
BIPublisherPluginLoadData

Insert a pivot table (in older plug-ins this option was called cross table)
bipublisherplugininsertpivottable

Then drag and drop the elements from the xml structure shown on the left to the place that you want.
bipublisherpivottable

Oracle ESB, to processmodel or not!

In one of my latest project i was trying to get a simple processflow modeled in the Oracle ESB. Indeed trying. I wasn’t really reaching the boundaries of an ESB, but i guess the simple functionality i needed wasn’t straightforward in the Oracle ESB.

Examples

The examples i see coming by on the web mostly have patterns like :

One-way

one-way
No response is needed back to the ‘caller’ and an easy fit in the oracle esb.

Request/response

request-response
The esb will expose the routingservice as external service. We will call this service, with the employee information, the consumer will process the data and will reply back with some sort of servicecode and message if the operation is completed, the next easy fit in the oracle esb.

One-way with Forward and Route Response

forward
We’re getting close to what i tried to achive. In this case we can define the routingservice one-way

    <operation name="execute">
        <input message="tns:inputESB_request"/>
    </operation>

The routingservice will send data to the convertservice, the service will give the converted string as output and send it back on the bus. In the routingservice we will not send the reply back to the caller on the routingservice but will forward it to the consumerservice. Since the routingservice is one-way it will not wait on any response, and the process is done. See the oracle site for an example ( Oracle ESB Samples (ZIP) > Forward and Route Response) of this pattern.

Components

For the esb project I created a simple xsd for the input and the output. The routingservice will be synchronious.

< ?xml version="1.0" encoding="windows-1252" ?>
<xsd :schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns="http://iteye.nl/soa/esb/SimpleEsbModel"
            targetNamespace="http://iteye.nl/soa/esb/SimpleEsbModel"
            elementFormDefault="qualified">
  <xsd :element name="inputESB" type="xsd:string"/>
  <xsd :element name="outputESB" type="xsd:string"/>
</xsd>

We will start with creating a routingservice based on this xsd.
routingservice

For this blog i created 2 dummy services, with both input and output as a string.
The first service, convertService, will supply us some extra functionality in the esb process to convert the messageFormat1 which gets into the routingservice and convert this into messageFormat2. After this the converted response from the convertService needs to get routed to the Consumer-service. The consumer will do his thing with it and after a succesfull completion it will give some sort of notification back on the bus, back to the routingservice. Sounds easy, too bad this esb wouldn’t allow me to get the job done the way i wanted.

After the process is modeled we ended with the next :
forward-response

The process works ok and we can route from the routingservice to the consumer after the message is converted by the convertservice. The only problem which lasts is we need a notification back from the consumerservice back to the SimpleRoutingService. If we look at the picture i added the red lines/arrows to identify what extra is needed to make this work.

So….is it me, or is this just not possible in the Oracle ESB?
I posted this situation on the Oracle forum (soa suite) too, to see what ideas the other developers had. To conclude the comments : “You’re trying to processmodel in the esb, it’s not ment for these things, do this in for example bpel”.

abc-a

It works when i model this functionality in the bpel, but the negative part of it is….i need to registrate the consumers in the bpel instead of the bus.

Some other solution i was thinking of :

call the convert-service from the xsl-mapping by adding a custom xslt extension and just call the java classes instead of the ejb.
No go :
The convert service will be used by other parts of the organization too, so i don’t just want to put some classes on the classpath but rather use the webservice interface.

Because i’m not sure wheither it’s possible with the Oracle ESB, i will evaluate the BEA AquaLogic ServiceBus, to see if this situation is supported in it.

My colleague John Copier will give some extra info about the project on the Oracle OpenWorld in San Francisco.

To be continued!

Statement of direction Oracle Forms, Reports and Designer July 2008

I just read the new statement of direction for oracle forms, reports and designer.

Not many new things. Most important conclusion : “.. New version of Oracle Forms, Oracle Reports and Oracle Designer will continue to be released and integrated with the future versions of Oracle Application Server and Oracl eDeveloper Suite..”.

For the latest versions the application server (10gR2 (10.1.2) & V11 there will be support until 2017 & beyond ! And Oracle will support forms in later versions of the application server too (including bug fixes and new features). However Oracle Designer will not include new features anymore.

Reinventing the wheel

Reinventing the wheel is usually considered a bad thing, a waste of time. I think that’s complete nonsense. Without it there would be no usable products. Have you ever liked a version 1.0 of anything? Innovation is build on people reinventing the wheel. Imagine what would happen if we didn’t reinvent the wheel…
Reinvent the wheel: new car, old wheels

Technology
Ben jij slim genoeg voor IT-eye