Showing posts with label web applications. Show all posts
Showing posts with label web applications. Show all posts

Tuesday, December 1, 2009

Presenting Business Objects Reports in PDF Format Using Web Services

Suppose you have a web application, whether of an RIA type or Web 1.0 type, that needs to present a report. One of the attractive options, is to have the report show in the browser as a PDF document. It seems an interesting option, because most users already have Adobe Acrobat Reader installed and are familiar with it. They usually know how to navigate through the document, print it or save it for emailing or just for later use.
If your organization is also one of the many that use Business Objects (BO) as their standard reporting technology, the solution presented below may be for you.

Since version XII, the Business Object Enterprise server is bundled and by default installs the web services module which allows to access reports via SOAP web services. Here's the solution:
  • The web application requests a report by calling the special reporting servlet, passing to it the report ID and required parameters.
  • The servlet uses web services to login to BO server and request the report, which then is returned to the client and displayed in a new browser tab or window in Acrobat Reader.
The example below, shows the solution for the case when the client is a Flex application and the servlet is implemented in Java.

Reporting Servlet
The servlet consists of the following modules:
  • login module (login to BO server)
  • report parms module (requests a list of the parameters required by the report and prepares them)
  • report viewer module (configures the request to return the report in PDF format)
  • retrieve and deliver module (requests the report from BO server and sends it on its way back to the client)
Login Module:

  SessionSoap session = new SessionSoapProxy("http://crystalbo:8080/dswsbobje/services/session");
  EnterpriseCredential credents = new EnterpriseCredential();
  credents.setLogin(businObjectsLoginName);
  credents.setPassword(businObjectsLoginPwd);
  SessionInfo si = session.login(credents);
  if( si == null ) { login failed... }
  // Instantiate Report Engine
  ReportEngineSoap rptEngine = new ReportEngineSoapProxy();

Thursday, September 3, 2009

Using FlexUnit to Unit Test Cairngorm Visual Objects

Introduction
In a RIA application a typical split of the source code (counted by code size, in bytes) is as follows:
  • 45-60% - client: visual objects like views and their sub-components with their logic
  • 15-20% - client: non-visual objects (primarily Cairngorm worker-to-service piping)
  • 30-35% - server: middle-tier code
In the couple medium-size business application, I have analyzed, the middle-tier was implemented in Java and the client was implemented in Flex using the Cairngorm architecture. So, I don't have verified numbers for other RIA configurations.

If we are determined to use TDD or simple just provide automated tests for our application and get the most coverage for the effort required to develop these tests, it seems we could use the following testing methodologies:
  • FlexUnit testing for the client, especially the client's visual objects
  • FlexMonkey tests for whole client's features
  • jUnit tests for the middle-tier code.
I another blog, I will touch on the FlexMonkey. In this one, I'd like to present how we can unit test the visual layer of the client using the FlexUnit framework. jUnit testing is well described in many other sources.

Testing Scenario
In the spirit of Cairngorm, a UI user gesture is directed to a handler which creates a Cairngorm message, attaches a payload to it (any relevant information) and dispatches it (event.dispatch()). Our test will mimic a user gesture (click a button) and will try to catch the dispatched Cairngorm event and verify its payload. We're using Flex 3 (ver. 3.2) and FlexUnit 4 beta 2.

Sample Application
To explain the topic, I'll be using the following sample application. The view (Main.mxml adds it to the ViewStack) is (to see the code in a new window, move your mouse pointer over the code and click the left of the icons that appear in upper-right corner):
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
width="400" height="300">

<mx:Script source="MyViewScript.as" />

<mx:HBox verticalAlign="middle" >
<mx:Text id="txtValue" text="Entry:" />
<mx:TextInput id="entryTextInput" />
<mx:Button id="btnSave" label="Save" click="onBtnSaveClick(event)" />
</mx:HBox>

</mx:VBox>

The script used bu the view is:
import gov.olcc.fishbait.events.SaveEntryEvent;
import gov.olcc.fishbait.model.ViewModelLocator;
import gov.olcc.fishbait.vo.EntryVO;

public var modelLocator:ViewModelLocator = ViewModelLocator.getInstance();

public function onBtnSaveClick(event):void
{
trace("clickHandler detected an event of type: " + event.type);

var entryVO: EntryVO = new EntryVO();
entryVO.text = entryTextInput.text;

var saveEvent: SaveEntryEvent = new SaveEntryEvent(entryVO);

saveEvent.dispatch();
}


and the TestRunner class to run the test is
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns="*"
xmlns:flexunit="http://www.adobe.com/2009/flexUnitUIRunner"
xmlns:business="gov.olcc.fishbait.business.*"
xmlns:control="gov.olcc.fishbait.control.*"
xmlns:view="gov.olcc.fishbait.view.*"
layout="vertical"
width="100%" height="100%"
creationComplete="runTests()">

<mx:Script>
<![CDATA[
import com.adobe.cairngorm.control.FrontController;
// import gov.olcc.fishbait.view.TestFishBaitView;
import gov.olcc.fishbait.view.MyView;
import org.flexunit.runner.FlexUnitCore;
import org.flexunit.flexui.TestRunnerBase;
import gov.olcc.fishbait.view.MainTest;
// import gov.olcc.fishbait.view.TestFishBait;

//Add an import statement(s) for the class(es) under test
private var core: FlexUnitCore;

private function runTests():void
{
core = new FlexUnitCore();
core.addListener(testRunner);
core.run(MainTest);
}

]]>
</mx:Script>

<!-- Cairngorm Controller and Service Locator -->
<control:FishBaitController id="controller" />
<business:Services id="services" />

<flexunit:TestRunnerBase id="testRunner" width="100%" height="100%" />
</mx:Application>

The trick is to be able to catch the Cairngorm event. What is not obvious, the event.dispatch() method uses a CairngormEventDispatcher, so we need to add our listener to it. The resulting test code is
package gov.olcc.fishbait.view {
import com.adobe.cairngorm.control.CairngormEventDispatcher;
import flash.events.MouseEvent;
import gov.olcc.fishbait.events.SaveEntryEvent;
import gov.olcc.fishbait.model.ViewModelLocator;
import gov.olcc.fishbait.vo.EntryVO;
import mx.automation.codec.AssetPropertyCodec;
import org.flexunit.Assert;
import org.fluint.uiImpersonation.UIImpersonator;
import org.flexunit.async.Async;

public class MainTest {
var myView: MyView;
public var modelLocator:ViewModelLocator = ViewModelLocator.getInstance();

[Before(async,ui)]
public function setUp():void {
myView = new MyView();
UIImpersonator.addChild(myView);
}

[After(async,ui)]
public function tearDown():void {
UIImpersonator.removeChild( myView );
}   

[Test(async,timeout="3000")]
public function testOnBtnSaveClick():void {
CairngormEventDispatcher.getInstance().
addEventListener(SaveEntryEvent.SAVE_TEXT,
Async.asyncHandler( this, handleTestOnBtnSaveClick, 3000 ),
false,0,true);

myView.entryTextInput.text = "Test Text";
var clickEvent: MouseEvent = new MouseEvent(MouseEvent.CLICK);
myView.btnSave.dispatchEvent(clickEvent);
}

private function handleTestOnBtnSaveClick(event:SaveEntryEvent,
passThroughData:Object):void {
var entry:EntryVO = event.text;
Assert.assertEquals("Test Text", entry.text);
}
}
}

Other points about this test:
  • We use FlexUnit UIImpersonator as a parent to our view. Without adding a view to a parent, the UI controlls are not initialized and can't be used.
  • To get the instance of the CairngormEventDispatcher, we use its static mathod getInstance().
  • Since the actual test happens in the event handler, we need to user an annotation [Test(async,timeout="xxx ms"] to request the Async support for the test.
  • Then, instead of providing just the handler method as an argument to the assEventListener(), we wrap this method in Async.asyncHandler(), which will wait for the handler to be called unless the handler will not be called within specified time, in which case the test will fail.
And this is it. Enjoy testing Cairngorm visual objects.

Tuesday, May 12, 2009

Developing Flex Applications with Java Middle-Tier

Intro
In my job we are using Flex with Java to develop web applications that support the activity of the agency I'm working for. It's my first experience with Flex and I'd say, I'm duly impressed. I had experience of developing using GWT and I must say, that Flex is an equally good tool.

A Simple Way
Just follow this tutorial.

Tools Used
We use the following toolset:

  • eclipse with FlexBuilder plugin (plugin is not free)
  • jBoss
  • Java for back-end
  • LCDS to communicate between Flex and Java (not free, but there are free alternatives: BlazeDS and the LCDS Express is also free, I think).
  • Cairngorm pattern for Flex client structure

Tips and Gotchas

  • A great intro to Cairngorm (and Flex itself) is one by David Tucker.
  • He is using ColdFusion for the back-end, so switch to this or this for how to do it with Java.
The Cairngorm pattern for calling a remote service is a bit complex. Here's how it goes:
  • In the main mxml file (the one where you define mx:Application): instantiate the ServiceLocator: . The id "services" is irrelevant, it seems. And instantiate the FrontController.
  • Let say, the command LOGIN is to be handled by the back-end. Dispatch the command by initiating the LoginEvent and calling dispatch() on it.
  • Each event is mapped onto a command in the FrontController. Let say, in this case, onto a LoginCommand.
  • In loginCommand, instantiate a delegate, say LoginDelegate and call the login(event)
  • In LoginDelegate, obtain the service proxy using:
    ServiceLocator.getInstance().getRemoteObject("myRemoteObject");
    and call the login(args) on it.
  • Now, two additional files need to be setup: Services.mxml and remoting-config.xml
  • In the first one, Services.mxml, define a mx:RemoteObject with id="myRemoteObject" and the destination="myRemoteClass".
  • In the second, the remoting-config.xml, define a destination with id="myRemoteClass" and the Java class package+classname in the source tag.
  • In the Flex Server properties (access through project properties), set the Root Context as the /YourProjectName.
If you need to pass an object between client and the server, create two corresponding value objects (usually named *VO, like LoginVO), one in ActionScript in flex branch and one in Java branch:

  • The ActionScript version, needs to have an annotation above the class definition: [RemoteClass(alias=org.sjb.LoginVO)].
  • The Java version needs to be public and have public setters.
If you want to debug not only Flex (which is done the usual "eclipse" way), stop the JBoss server and start it in Debug mode. That's all that is needed.

Conclusion
Altogether, using Flex with Java is very simple. Enjoy it!

Wednesday, April 29, 2009

How to Deploy a GWT Application to Tomcat?

Intro
OK, so you have tried the GWT (Google Web Toolkit), decided that it's cool, and you created your first application, precisely a module. You have tried it locally on your development machine, using the hosted mode and, may be, in the web mode by using the Compile/Browse button on the hosted-mode preview window. Now, you can either deploy it to Google App Engine, which is a way to try it online free and easily (make sure that your app doesn't become the IP of Google! I haven't looked at the terms of use myself.) or you decide yo want to go for it, and publish it for real. You purchase a Java hosting plan (google for it; you can find some within $12/mo.), and you're ready to deploy your application to your Tomcat server.

Deploying It
I used this re
source to help me with. Basically, follow the steps ( is the root of your GWT application,):
  • create a staging folder (let's call it deploy)
  • copy contents of /www/com.meography.EntryScreen into /deploy
  • create /WEB-INF with folders classes and lib in it
  • create web.xml file in WEB-INF. See the above resource for how to.
  • copy contents of /bin folder to deploy/WEB-INF/classes
  • copy all needed jars into deploy/WEB-INF/lib (you don't need gwt-user.jar nor gwt-dev-windows.jar, though)
  • compress all of the conents of deploy folder into a zip file and rename the file to .war.
  • upload the file to Tomcat, which can be done via browser using Tomcat manager, which is usually already installed for you by your Java hosting vendor. Once the upload finishes, the manager will show your application with options to Start, Stop, Reload and Undeploy it. The name of the app, is the base URL for your app.
Point your browser to the main .html file of the module (URL indicated by Tomcat manager + YourMainScreen.html). And, voila, you should be on. Well, if there are any problems, for example with your database setup, you'll find errors in the catalina.log file in the /tomcat/logs folder on your production server.

Re-Deploying It
To redeploy, after you have done some changes, simply repeat the steps above, but remember to preserve files you had to tweak or create for your production environment like web.xml and possibly hibernate.cfg.xml, if you happen to use Hibernate and use different database on your development machine and on your production server (Java hosting plan will usually have MySQL and PostgreSQL databases included). And, one more thing. I have found that I have to do Undeploy, upload the new .war file and then Deploy for the changes to post correctly. The reason may be, that GWT application is compiled into JavaScript cache files with random names, so the file names will be different each time you compile it, and so, just copying the new .war file over will not replace all of the old files.

Any feedback? Feel free to let me know.

Monday, December 29, 2008

Struts, Hibernate Development with Eclipse

I'm developing an web application to test algorithms for Romba-like devices. I have some algorithms in mind, that I want to test, so I decided I develop an application for the purpose of testing these algorithms or any algorithms.

I wanted to use Java standard frameworks, for now Struts and Hibernate and Eclipse as the. It took me some time to figure out what free plugins to use with Eclipse to add support to Struts and Hibernate. I looked for some time and finally found the following set of plugins:
For DB development support I have used three:
  • DB Development plugin (from Eclipse.org)
  • QuantumDB
  • Derby plugin (from Eclipse.org)
Probably the first of these would be enough.

A few notes:
  • Tomcat plugin doesn't come with a documentation, but the website has a decent one. Plugin works nicely. Starts Tomcat in debug mode, unless user disables this feature in plugin preferences. Switch to Debug perspective and you can debug your application.
  • QuantumDB is a well known plugin, but I had problems with it. I couldn't find in it the tables that were in the database. Possibly, I'll learn how to use it. DB Development plugin is easier to learn it.
I'm still in early phase of the development. I'll update this blog when I have more experience with these plugins.