Wednesday, April 27, 2011

Currency converter using Web Services and JRapid

In this post I’m going to show you how to use JRapid to quickly create a form that converts amounts between currencies using a web service that provides live updated conversion rates.

For this example we’ll be using a free currency conversion rates service provided by http://www.webservicex.net.

Create a new JRapid project and select the empty template.


We’ll start by creating an Enumset to define the available currencies and their codes. Click on the new Enumset button shown below. Enumsets are global definitions of constant values that can be used in properties. Read more here.



Fill in the dialog as follows.




This defines four currency names and their corresponding codes as expected by the rates web service.

Next, we’ll create a new transient entity called CurrencyConverter. Transient entities behave just like normal entities except that they are not persisted to a database table. JRapid generates the form, routes and services for them just like it would for a persistent entity, but it does not generate the code to persist them. The developer is responsible for implementing the business logic that will take care once the form is submitted. Read more here.



Click on the new Entity button.


Enter the following definition for the entity. Note the transient checkbox is selected on the right and that the fromCurrency and toCurrency properties are of type enum.


Once the entity is created go to the entity diagram and click on the fromCurrency property to edit its properties.


Select the Currency value in the Enumset field. This tells the fromCurrency property of type enum to show the values of the Currency enumset as options.




Now click on the toCurrency property to edit its properties and, again, select Currency in the Enumset field.


One more time, click on the toAmount property.


Check the readonly field.


Switch to the second tab, Value. Check the Dynamic Value at the bottom of the window. This will enable the configuration of a dynamic value, used for setting the value to a property based on data retrieved from the server side. You can read more about this here.

In short, you define what values of the entity form to send as parameters and an EL expression to be resolved in the server side. We’ll send fromAmount, fromCurrency and toCurrency as parameters for our example.


For the expression, we will just return an empty string. This will make JRapid generate all the logic and let us overwrite the method that is responsible for the expression evaluation in order to include our customized logic that makes use of the web service.


The trigger field defines when this remote service is going to be executed. If left blank, the default is always. This means the value will be calculated whenever one of the parameters’ values is changed.

This is how the form looks.


Now, we have to write the Java code to perform the currency conversion. Using the JRapid Eclipse plugin we can synchronize the project on the cloud to our local workspace and get our modifications uploaded instantly. Keep in mind that projects running on a Shared development environment do not allow you to upload modified Java code. Anyway, you can go on running the web app in a local development environment. Check this tutorial to get a detailed description on how to do this.

Back to Eclipse, we need to edit CurrencyConverterServices.java and override the getDynamicValueForToAmount method. The code included below is just a quick example and should not be used in real life apps.




package com.service1.services;

import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class CurrencyConverterServices extends
  CurrencyConverterServicesAbstract {
 
 @Override
 public Object getDynamicValueForToAmount(String fromAmountParamId,
   String fromCurrencyParamId, String toCurrencyParamId) {
  double toAmount = 0;
  try {
   double fromAmount = Double.parseDouble(fromAmountParamId);
   
   String serviceUrl = "http://www.webservicex.net/CurrencyConvertor.asmx/ConversionRate?FromCurrency=" 
     + fromCurrencyParamId + "&ToCurrency=" + toCurrencyParamId;
   
   DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
   factory.setNamespaceAware(false);
   Document responseDoc = factory.newDocumentBuilder().parse(serviceUrl);
  
   NodeList nodes = responseDoc.getElementsByTagName("double");
   Node rateNode = nodes.item(0);
   rateNode.getTextContent();
   double rate = Double.parseDouble(rateNode.getTextContent());
   toAmount = new Double(100 * fromAmount * rate).intValue() / 100.0;
    
  } catch (Exception e) {
   e.printStackTrace();
  }
  return toAmount;
 }
}

Note: the web service used in this example is taking a long time to respond at the time of writing.

You may now point your browser to the Convert Currency test and give it a try. Note how the value of the toAmount property is calculated every time you change any of the other three properties.


Through this tutorial we used the GUI provided by the JRapid Designer to create and customize our application, but all this was just another way to generate the actual definition of the application, the AML code. This is an an XML file that defines our business models. Read this about modeling with JRapid. But we could have switched to the source view and typed the definition by ourselves.






This is the code for the Enumset and Entity that we defined.


<entity label="Currency Converter" menu="Menu" name="CurrencyConverter" transient="transient">
        <property enumset="Currency" label="From Currency" name="fromCurrency" required="required" type="enum"/>
        <property label="From Amount" name="fromAmount" type="double"/>
        <property enumset="Currency" label="To Currency" name="toCurrency" type="enum"/>
        <property label="To Amount" name="toAmount" readonly="readonly" type="double">
            <dynamicvalue expr="''">
                <param name="fromAmountParam" type="double" value="fromAmount"/>
                <param name="fromCurrencyParam" type="string" value="fromCurrency"/>
                <param name="toCurrencyParam" type="string" value="toCurrency"/>
            </dynamicvalue>
        </property>
    </entity>

    <enumset name="Currency">
        <enum value="EUR">Euro</enum>
        <enum value="USD">US Dollar</enum>
        <enum value="CNY">Chinese Yuan</enum>
        <enum value="BRL">Brazilian Real</enum>
    </enumset>

No comments:

Post a Comment