Wednesday, September 21, 2011

BIRT: Using Resource Bundles

A question that has recently been posted on the BIRT Exchange has got me revisiting an old problem with BIRT, localization. BIRT has a localization mechanism built in, but this only works for labels with the UI. You can also use Javascript and the report context to access messages. But I wanted to look at another way to accomplish this same task? It would stand to reason that since BIRT is running inside OSGi, and OSGi is just a fancy layer on top of Java, that we should have access to the localization features in Java, right? That would be correct.

I prefer to use Java Event Handlers for this. It is possible using Javascript event handlers, but that is a bit of a pain. So, in the following example, I will show a simple Java Report Event Adapter that will load up a Resource Bundle based on the Locale passed in from BIRT, and initialize a HashMap that can be used in BIRT to retrieve those values.

The first thing I do is create a separate Java project, and extend the ReportEventAdapter class. I then created a initialize event, although this would work in the beforeFactory event as well. All you need to do is use the same coding you would use in Java to load the ResourceBundle, and retrieve your keys and values. Using the reportContext passed in, you can load the Locale, and set a global variable that can be used in the report design to retrieve those values. The Java code is below.

package com.digiassn.blogspot.birt.event.handlers;

import java.util.HashMap;
import java.util.ResourceBundle;

import org.eclipse.birt.report.engine.api.script.IReportContext;
import org.eclipse.birt.report.engine.api.script.ScriptException;
import org.eclipse.birt.report.engine.api.script.eventadapter.ReportEventAdapter;

public class ResourceReportEventAdapter extends ReportEventAdapter {
private static String LABEL_KEY = "myLabel";
private static String RESOURCE_NAME = "myResource";

@Override
public void initialize(IReportContext reportContext) throws ScriptException {
super.initialize(reportContext);

ResourceBundle resourceBundle = ResourceBundle.getBundle(RESOURCE_NAME, reportContext.getLocale());

String stringValue = resourceBundle.getString(LABEL_KEY);

HashMap<String, String> resourceValues = new HashMap<String, String>();
resourceValues.put(LABEL_KEY, stringValue);

reportContext.setGlobalVariable("resources", resourceValues);
}

}



The next piece of the puzzle is where to put the .properties files. You should put them into the projects /src folder. If you put them under a package, you would reflect that in the getBundle call above. I just kept mine at the root.



So now, how do you leverage this in a report? Create a new report project. Right-mouse click in the Navigator, and go to Properties. Select Report Design/Classpath. Click on the Add Projects button, and select the Java project with your Event Adapter.



In my example report, I dropped a Dynamic Text Element in, and used the following expression:

var resourceMap = reportContext.getGlobalVariable("resources");

resourceMap.get("myLabel");

And that’s it. Its read for preview. I can now localize this however I choose. If I wanted to, in my data set, I could have an additional column with the key to retrieve, and just retrieve it from my map. This allows for external localization.

Be sure to check the BIRT Internationalization FAQ at http://wiki.eclipse.org/BIRT/FAQ/Internationalization. You can use a standard reportContext.getMessage call in a similar manner.

Wednesday, June 22, 2011

BIRT 3.7 Released

Imagine my surprise, BIRT 3.7 was released today. I didn't even know until a client pointed it out to me =)

You can get it over at the Eclipse BIRT Homepage at http://www.eclipse.org/birt, along with a list of what is new and notable in this release.

Monday, March 28, 2011

Tech: Nintendo 3DS

I am once again crossing that threshold between professional writings and personal for this article. It has been over a day since I purchased the Nintendo 3DS, the newest hand held gaming device by big N. Let me cut to the chase. Is it worth it? In the short term, no. But this has nothing to do with the hardware, or the novelty of the 3D, which is, in a word, phenomenal. No, the shortcoming is with the game library that came out at launch. Don't get me wrong, Super Street Fighter 4 was the tipping point for me, but as of this writing, that all there really is. I'm thinking of getting Ridge Racer, and Pilotwings, but truth be told, I'm only considering that as a justification to use more of the 3D features. In the long run, this is more evolutionary than revolutionary, and when Zelda comes out, along with several other titles, this will be the device to be had, even if it will be in its inevitable 3Ds Lite form.

Now for the long description. I purchased the 3DS since I am a pretty heavy mobile gamer due to my traveling schedule. I usually carry on me my DS Lite, and my original PSP fat (hacked of course) so that I can keep myself entertained on planes, airports, and hotels. So the 3DS was an enticing option.

The 3DS is, in a nutshell, an updated version in the DS and DSi line. All titles for those platforms are playable, with the addition of the new 3DS titles. Covering 3 generations of the platform is pretty impressive, considering that the DS only covered the DS and Gameboy Advance, and the DSi dropped the Advance and only played DS and DSi titles. The problem for me, however, is that I do still have a good collection of Advance titles, such as the re-releases of Zelda 1 and 2, Phantasy Star, and several Final Fantasy installments. So, for me, it looks like I'll still be carrying around the DS Lite. Which brings up a major issue with the 3DS, the battery. The battery, for me, lasted around 3 - 4 hours. Of course, I did crank the 3D the entire time, but from what I have read, turning the 3D off doesn't make that big of a difference. So on a plane ride for me its no big deal, but I might be switching over to the Lite mid flight.

Once the 3Ds is turned on, it borrows a lot of its "feel" from the Wii. Thats hard to describe in words, but the overall tone, color schemes, and sound effects seemed very Wii'ish. Thats not a bad thing by any means, and navigating the menus is a very intuitive. The 3D camera is really slick, as is the AR games.

But the real meat is in the gaming. I spent all my time playing Street Fighter, of course. And to be honest, I was blown away by the 3D. It really is unlike any gaming experience I have ever had. Just something about landing that final special move, and the camera panning around with real perceived depth is just breath taking. I was a little disappointed that the two hood rats were missing from the background of the North American Diner stage, but I suppose there is only so much processing power in this handheld, and processing the "Oh Snaps" might have been too much.

There are several features that have a notice that it will be featured in some future update, such as the web browser, which means there are pieces of the entire 3DS experience that are missing. But I guess thats what I get for being an early adopter.

Like I said above, this is a really neat device. But the short term benefit just seems lacking. Long term this can really be THE device to have, especially once the game library grows, especially considering that DS and DSi titles cannot take advantage of the 3D capabilities. But once the Zelda, Mario, and Laytons come out that do take advantage of these features, this is going to be a great system. And something about the Professor Laytons stylized art might be really slick with the 3D option turned on =)

Wednesday, March 09, 2011

BIRT: Connecting to MS Sql Server Database

  1. Download the Microsoft JDBC driver from http://msdn.microsoft.com/en-us/sqlserver/aa937724
  2. Note: If youre using Java 1.5, you will use sqljdbc.jar, if your using Java 1.6, you will use sqljdbc4.jar.
  3. Open Eclipse
  4. Create a new Report or open an existing report
  5. Open the Data Explorer Tab
  6. If this is an existing report, Double Click on an existing Data Source, otherwise create a new Data Source. Call it whatever.
  7. From the Data Source editor, click on the Manage Drivers button.

  1. In the Manage JDBC Drivers Dialog, click on Add…

  1. Navigate to where you have either the sqljdbc.jar or sqljdbc4.jar file, and click Open. This will add the driver to the BIRT Designer.
  2. Now, click on the Drivers Tab.
  3. Double click on the SqlServerDriver entry to edit it. Put in a name, and a URL template that will prompt you on the correct URL pattern to use.

  1. Click on OK, and OK, until you get to the Data Source Editor Dialog.
  2. Select the SQL Server driver from the drop down list. It will automatically put in the template. Replace the IP Address, and Database name with the ip of your Sql Server Database, and the name of the database.

  1. Enter the correct User Name and Password.

That’s it, your done. Test Connection to make sure the information is correct, and hit OK.

Wednesday, March 02, 2011

Tech: Asus Motherboard Box Doubles as PC Case

In the "Why didn't they think of this before" category, Asus is beginning a trial where they ship some of their motherboards in a box that, when opened post shipping, just needs you to add components and doubles as the PC case itself. While not exactly the most visually appealing design, it REALLY is something that is worth looking into, especially if your building your own PC and aren't too concerned with the visuals of an all black case and adding "das blinking lights".

http://www.itworld.com/hardware/138740/asus-motherboard-box-doubles-a-pc-case

Monday, February 28, 2011

BIRT: The Arctorus BIRT Emitters

While doing some research for some work on an emitter for a client, I came across the Arctorus BIRT Emitters. I'd never heard of these guys, just the standard OSS BIRT Emitters, the Commercial BIRT Emitters, and the Tribix Emitters. While these are commercial emitters, and are not free, they do offer a 30 day trial. These are the formats that are supported.
  • DOCX
  • XLSX
  • PPTX
  • ODT
  • ODS
  • ODP


I intend to do a review of them and see how well they work.

Friday, January 28, 2011

BIRT: Chart DaVinci

I don't know how I missed this post over at the BIRT Exchange. This is a really great drop in script that you can use in your charts that will instantly spruce them up. Takes a lot of manual picking at charts to get that professional look out of the design process. Definitively well worth a look if your doing any kind of chart work.

Thursday, January 27, 2011

BIRT: Dynamically Adding a Data Set to a Report

So a co-worker asked me today to help him by dynamically adding a data set to a report. He ended up going a slightly different route using the StructureElementFactory class, but this is what I came up with using the reports existing ElementFactory, and dynamically adding in the parameters and query text. This example can be expanded upon of course to set this up in whatever way you need, in coordination with using the DEAPI to dynamically add a table for a more dynamic report. It will even save off the report design at the end for future reference. I used the beforeFactory event, but this will work just as well in the Initialize event as well.


public class ReportEventHandler extends ReportEventAdapter {

@Override
public void beforeFactory(IReportDesign report, IReportContext reportContext) {
super.beforeFactory(report, reportContext);

try {
ReportDesignHandle reportDesign = reportContext.getDesignHandle();
OdaDataSetHandle dataSet = reportDesign.getElementFactory().newOdaDataSet("Data Set", "org.eclipse.birt.report.data.oda.jdbc.JdbcSelectDataSet");

dataSet.setDataSource("Data Source");
dataSet.setQueryText("select employeenumber from employees where employeenumber = ?");

OdaDataSetParameter param = new OdaDataSetParameter();

param.setName("param_1");
param.setParamName("empNo");
param.setNativeName("");
param.setDataType("integer");
param.setNativeDataType(4);
param.setPosition(1);
param.setIsInput(true);
param.setIsOutput(false);

dataSet.getPropertyHandle(DataSetHandle.PARAMETERS_PROP).addItem(param);

OdaResultSetColumn result = new OdaResultSetColumn();
result.setColumnName("EMPLOYEENUMBER");
result.setNativeName("EMPLOYEENUMBER");
result.setDataType("integer");
result.setPosition(1);
result.setNativeDataType(4);
dataSet.getPropertyHandle(DataSetHandle.RESULT_SET_PROP).addItem(result);

ColumnHint resultHint = new ColumnHint();
resultHint.setProperty(ColumnHint.COLUMN_NAME_MEMBER, "EMPLOYEENUMBER");
resultHint.setProperty(ColumnHint.COLUMN_NAME_MEMBER, "integer");

dataSet.getPropertyHandle(DataSet.COLUMN_HINTS_PROP).addItem(resultHint);

//this works
reportDesign.getDataSets().add(dataSet);

//and so does this
//reportDesign.getSlot(ReportDesignHandle.DATA_SET_SLOT).add(dataSet);

//just saving for debug purposes, you can ignore this
reportDesign.saveAs("C:/TEMP/MyTestDesign.rptdesign");
} catch (ContentException e) {
e.printStackTrace();
} catch (NameException e) {
e.printStackTrace();
} catch (SemanticException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

Tuesday, January 25, 2011

BIRT: Connecting Data Elements to Existing Table Bindings

Not sure how I never knew this existed before, but I discovered a really cool little feature in BIRT. Lets say you have an existing table binding in a report. For me, I ran across this when I went into the XML source and copied a binding multiple times to duplicate it and make minor changes. Or, lets say you just added an Aggregation via the Property Editors binding tab instead of dragging and dropping. Now you want to add in a data element to display it. If you try to drop in a new Data Element, it will create a new binding, even if you are just referencing an existing table binding. Thats no good, you dont want duplicates, you just want to reference an existing binding. There is always the option of using a Dynamic Text element, but what if you want to change the underlying expression in the future, and you find the Property Editor tedious. Well, there is a quick way.

Add a Data element in the report designer. Do not change the name or add an expression, just his Escape. It will create a blank placeholder. Then, right-mouse click on this blank data element, and choose Change Data Column. The Select Data Binding dialog will pop up, and you can select which Data Binding to use. Once you hit OK, it will act just like an original Data Report Item. Again, not sure how I never came across that before...

Monday, January 24, 2011

BIRT: BIRT Helper Functions

The BIRT Functions provide a wealth of useful functionality that typically gets overlooked by developers. Simple operations such as compares, divides, string functions are handled by these functions with special handling for those really annoying gotchas that are typical.

Consider the following example. Lets say you have a real simple divide expression, such as:

numA / numB

That’s simple enough, right? But that’s assuming that numb is never 0, otherwise you have to worry about the dreaded divide by 0 error. Or better yet, what if one of the values is null because it is not present in the dataset? Normally you would need to change the expression to look like:

if ((numA != null) && (numB > 0))

{

numA / numB

}

else

{

null;

}

But that gets tedious, especially if you have a lot of divide expressions. That’s where the BIRT Functions come into play. In the above scenario, the BirtMath.safeDivide() method can help alleviate the need to do that. So, in the above example, I would basically just use the following:

BirtMath.safeDivide(numA, numB, 0);

BIRT is full of helpful functions such as this, such as Round, RoundUp, RoundDown, different comparison functions, and Date Time functions to work with anything from Years, Quarters, down to seconds. Plus, this functionality is expandable via the BIRT Script Library extension point. I typically recommend that most report writers use these functions in favor of the native Javascript functions.

Sunday, January 09, 2011

EclipseCon 2011: Getting Started with BIRT

I have been approved and scheduled for another year at EclipseCon. This year I only have 1 talk, despite having some really good proposals about writing plugins for BIRT. But the Getting Started with BIRT talk is always a good one for new users to BIRT, I always enjoy presenting it and getting to know the folks in the crowd, and I always welcome interaction during and after the talk from attendees.

With only 1 talk scheduled for me this year, this provides me with a great chance to attend a lot of talks. Last year the talks I attended steered me towards EMF, which was helpful in helping some of my paying clients. I am really looking forward to a lot of the talks scheduled for this year. I will probably continue my EMF studying by attending this talk by Kenn Hussey, who was helping with a BIRT ODA, and Ed Merks. since GWT is familiar territory for me already, I look forward to the marriage of these two to drive some EMF points home for me. There are some good Window Builder talks on the program, which is exciting for me since I have been a user of Window Builder for years, and this is the first year that they are doing talks after being bought by Google. My friend Benny has a great talk planned about GIT. Benny has had a lot of experience with GIT, and his involvement as a contributor stemmed from his frustration with shortcomings in the Eclipse implementation, so it will be interesting to hear what he has to say on progress with the plugins. Lots of good talks =)

If your planing on attending, feel free to mozy on by my talk or the BIRT booth and say hi!!