BitterSweetJaVa

February 17, 2010

New Home…

Filed under: Uncategorized — .|2ic|K @ 11:11 PM

this blog is now hosted at http://www.bittersweetjava.com.ar/

January 7, 2010

JEXL Basic Example

Filed under: Java — Tags: , — .|2ic|K @ 12:39 PM

Java Expression Language (JEXL) is an expression language engine which can be embedded in applications and frameworks”.

Although the last time that the official site was generated was on march 08 (for version 1.1), there is recent activity on JIRA regarding the release of version 2.


import org.apache.commons.jexl.Expression;
import org.apache.commons.jexl.ExpressionFactory;
import org.apache.commons.jexl.JexlContext;
import org.apache.commons.jexl.JexlHelper;

public class JEXLExample {

public static void main(String[] args) {
MyObject myObject = new MyObject();

String expr;
expr = "(myObject.number1 + myObject.number2) / myObject.number3";
processExpression(myObject, expr);
expr = "(N1 + N2) / N3";
processExpression(myObject, expr);
expr = "myObject.itsTrue";
processExpression(myObject, expr);
expr = "myObject.itsFalse";
processExpression(myObject, expr);

expr = "myObject.getThePresident().equals('Barack Obama')";
processExpression(myObject, expr);
expr = "myObject.thePresident.equals(\"George Bush\")";
processExpression(myObject, expr);

}

/**
* @param containerObject
* @param expression
*/
private static void processExpression(MyObject containerObject, String expression) {
try {
Expression e = ExpressionFactory.createExpression(expression);
JexlContext jc = JexlHelper.createContext();
//"myObject" is the alias to be used for expression evaluation
jc.getVars().put("myObject", containerObject);
jc.getVars().put("N1", containerObject.getNumber1());
jc.getVars().put("N2", containerObject.getNumber2());
jc.getVars().put("N3", containerObject.getNumber3());
System.out.println("Evaluating: " + expression );
System.out.println(" \\--------> " + e.evaluate(jc) );
} catch (Exception e) {
e.printStackTrace();
}
}
}

Notice the method processExpression, inside is where our expression is evaluated and the result is printed in the console.
First, we create an Expression object using the ExpressionFactory provided by Jexl, passing our expression as parameter.

Expression e = ExpressionFactory.createExpression(expression);

Then, we create the context in which our expression is going to be evaluated:

JexlContext jc = JexlHelper.createContext();

And finally, we add the variables into our context. These are the ones that can be used inside the expression.

jc.getVars().put("myObject", containerObject);
jc.getVars().put("N1", containerObject.getNumber1());
jc.getVars().put("N2", containerObject.getNumber2());
jc.getVars().put("N3", containerObject.getNumber3());

In the first line, I’m adding my containerObject object using the alias myObject.
The last 3 lines just add a different alias for each one of the numbers stored in the containerObject.

Below is the (short) code for the class MyObject:


public class MyObject {
private String thePresident = "Barack Obama";
private Boolean itsTrue = true;
private Boolean itsFalse = false;
private Integer number1 = 15;
private Integer number2 = 13;
private Integer number3 = 2;

...Getters & Setters...
}

This should be the output once you execute the example from above:


Evaluating: (myObject.number1 + myObject.number2) / myObject.number3
\--------> 14.0
Evaluating: (N1 + N2) / N3
\--------> 14.0
Evaluating: myObject.itsTrue
\--------> true
Evaluating: myObject.itsFalse
\--------> false
Evaluating: myObject.getThePresident().equals('Barack Obama')
\--------> true
Evaluating: myObject.thePresident.equals("George Bush")
\--------> false

I used Jexl in a previous project that I was involved. It’s very useful when you need to let the users enter expressions for filtering and calculation purposes.

December 2, 2009

Spring Framework: Reference constants

Filed under: Java, Spring — Tags: , , — .|2ic|K @ 3:59 PM

First of all, add the util schema to the spring namespace:

< beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:util="http://www.springframework.org/schema/util"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
            http://www.springframework.org/schema/util
            http://www.springframework.org/schema/util/spring-util-2.0.xsd
">

then, we should be able to use it to bind static fields to a bean property:

<util:constant static-field="com.mycompany.myproject.myclass.STATIC_FIELD"/>

November 30, 2009

Retrieve DB Objects from a legacy system using Hibernate

Filed under: Java, ORM — Tags: , , , , , — .|2ic|K @ 4:22 PM

Problem: Load data from multiple tables into a single Java entity.

Approach 1: Use custom SQL loading


@Entity
// Class that will store the query result(s). Class field names are the same than database column names.
@SqlResultSetMapping(name = "customerMapping", entities = @EntityResult(entityClass = CustomerMapping.class))
// Using hibernate annotation to specify out custom SQL queries
@org.hibernate.annotations.NamedNativeQueries(
     {
      @NamedNativeQuery(name = "loadAllCustomers",
      query = "select a.col1,a.col2,b.col1 from table1 a, table2 b where a.col5=b.col5",
      resultSetMapping = "customerMapping"),
      @NamedNativeQuery(name = "loadByCustNum",
      query = "select a.col1,a.col2,b.col1 from table1 a, table2 b where a.col5=b.col5 and a.col1 = ?",
      resultSetMapping = "customerMapping")
     }
)
// Default SQL query to be used when loading this entity through Hibernate
@Loader(namedQuery = "loadByCustNum")
public class CustomerMapping implements Serializable {
... class body
}

Approach 2: Use one-to-one mapping approach


@Entity
@Table(catalog = "myDB", schema = "dbo", name = "customer_mapping")
public class CustomerMapping implements Serializable {
     @OneToOne
     // Foreign Key pointing to the corresponding CustomerMaster data.
     @JoinColumn(name = "gte_cust_num", unique = true, nullable = true)
     // Default hibernate action to be taken when the FK is not null and
     // it's not present in the secondary table.
     // Hibernate can ignore the error and do nothing or throw an exception.
     @NotFound(action=NotFoundAction.IGNORE)
     private CustomerMaster masterData;
... class body
}


@Entity
@Table(catalog="myDB", schema="dbo", name="customer_master")
public class CustomerMaster implements Serializable {
... class body
}

NOTE: Be careful when trying to retrieve the objects using HQL:

hql = "from CustomerMapping cmi where cmi.filterField = 'ABCXXX'";

The query above will result in a performance issue if we are retrieving several CustomerMapping objects. This is because hibernate will generate one query to get all the CustomerMapping objects and N queries to get the data to populate each CustomerMaster object (from the one-to-one relation).

SELECT A,B,C FROM CustomerMapping WHERE filterField = 'ABCXXX';
SELECT D,E,F FROM CustomerMaster WHERE id = ?;
SELECT D,E,F FROM CustomerMaster WHERE id = ?;
SELECT D,E,F FROM CustomerMaster WHERE id = ?;

In other words, if we are retrieving N objects, then we will have N+1 database queries.

In order to avoid this, we need to force Hibernate to use JOIN FETCH to retrieve the CustomerMaster data:

hql = "from CustomerMapping cmi left join fetch cmi.masterData where cmi.filterField = 'ABCXXX'";

The query above will produce only one sql query to retrieve CustomerMapping and CustomerMaster data using a join.

SELECT A,B,C FROM CustomerMapping LEFT JOIN CustomerMaster (....) WHERE filterField = 'ABCXXX';

November 29, 2009

Port forwarding in VirtualBox

Filed under: Operating Systems — Tags: , , — .|2ic|K @ 5:00 PM

Here are useful commands to setup the port forwarding in a VirtualBox VM.

-- Forward local port 8888 to VM port 80 (Apache httpd)
VBoxManage setextradata "Ubuntu" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/httpd/Protocol" TCP
VBoxManage setextradata "Ubuntu" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/httpd/GuestPort" 80
VBoxManage setextradata "Ubuntu" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/httpd/HostPort" 8888

-- Forward local port 9090 to VM port 8080 (Apache Tomcat)
VBoxManage setextradata "Ubuntu" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/tomcat/Protocol" TCP
VBoxManage setextradata "Ubuntu" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/tomcat/GuestPort" 8080
VBoxManage setextradata "Ubuntu" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/tomcat/HostPort" 9090

-- Forward local port 2222 to VM port 22 (SSH)
VBoxManage setextradata "Ubuntu" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/ssh/Protocol" TCP
VBoxManage setextradata "Ubuntu" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/ssh/GuestPort" 22
VBoxManage setextradata "Ubuntu" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/ssh/HostPort" 2222

  • Ubuntu: Represents the name of the VM.
  • pcnet: Represents the driver of the network interface configured in the VM:
    • pcnet corresponds to the PCnet FAST II and PCnet FAST III devices
    • e1000 corresponds to the Intel PRO/1000 devices
  • 0: Represent the network interface number (you can configure multiple network interfaces.
  • “httpd”, “tomcat”, “ssh” are custom (and identifier) names for a particular configuration.
  • Protocol: The protocol to be used, can be TCP or UDP
  • GuessPort: The target port (in our VM)
  • HostPort: The source port (in the PC hosting the VM)

Note: These commands need to be executed from the command line of the host operating system while the VM is off.

November 27, 2009

Proxy setup in Java / Maven / SVN project

Filed under: Java, Maven, S.C.M. — Tags: , , , , , — .|2ic|K @ 11:59 AM

To setup a proxy to be used by Maven only, you need to have it defined in the settings.xml file.
This file is located in [USR_HOME]\.m2 directory (C:\Documents and Settings\[USERNAME]\.m2 for Windows users).
Here’s an example of the file:


<settings>
  <proxies>
   <proxy>
      <active>true</active>
      <protocol>http</protocol>
      <host>[PROXY SERVER]</host>
      <port>[PROXY PORT]</port>
      <username>[PROXY USERNAME]</username>
      <password>[PROXY PASSWORD]</password>
      <nonProxyHosts>www.website1.com|*.website2.com</nonProxyHosts>
    </proxy>
  </proxies>
</settings>

To setup a proxy to be used for a Java application:


System.getProperties().put("http.proxyHost", [PROXY SERVER]);
System.getProperties().put("http.proxyPort", [PROXY PORT]);
System.getProperties().put("http.proxyUser", [PROXY USERNAME]);
System.getProperties().put("http.proxyPassword", [PROXY PASSWORD]);

To display the proxy server used for a particular URL:

URL url = new URL("http://www.treasurydirect.gov/xml/CPI_20090814.xml");
System.out.println(ProxySelector.getDefault().select(url.toURI()));

Update Dec. 7, 2009: Proxy setup for Subversion command line and subclipse plugin (eclipse).

You should have a file named ‘servers‘ under C:\Documents and Settings\[USR_HOME]\Application Data\Subversion.
The file has pretty good inline documentation.
In my case, at the end of the file, I modified the following lines under [global] group:

[global]
http-proxy-host = [PROXY SERVER]
http-proxy-port = [PROXY PORT]
#http-proxy-username = [PROXY USERNAME]
#http-proxy-password = [PROXY PASSWORD]
http-compression = no
http-auth-types = basic;digest;negotiate

October 30, 2009

September 23, 2009

Quartz Job

Filed under: Java — Tags: , , , , — .|2ic|K @ 1:32 PM

For one of the applications that I’m maintaining, I was performing several manual validations on the tables a few times a day; in order to facilitate this tasks, I created a stored procedure to handle them and then send an email with the results using MSSQL mail service.
Also, I wanted this procedure to be executed several times a day, that’s why I decided to use Quartz in order to create a scheduled job for my web application that will call my recently created procedure.

First, I created the class that will represent the Job I want to execute. This class must implement the class

org.quartz.Job, overriding the method execute(..)

package com.dashboard.util;
import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import com.dashboard.forms.DashboardForm;
import com.dashboard.services.IService;
import com.dashboard.services.ValuationHealthCheckService;

public class ValuationHealthCheckJob implements Job {
    private static final Logger logger = Logger.getLogger(ValuationHealthCheckService.class);

    @Override
    public void execute(JobExecutionContext arg0) throws JobExecutionException {
        DashboardForm form = new DashboardForm();
        form.setEmailTo("xxxxx.yyyyy@domain.com");
        IService service = new ValuationHealthCheckService();
        try {
            service.execute(form);
        } catch (Exception e) {
            logger.error(e);
        }
    }
}

As you can see, the body of the method execute is really simple. A DashboardForm class, which is simply a java bean with a field “emailTo” and then the creation and execution of my service class. The service class will take care of connecting to the database and execute the stored procedure that will verify the tables and send an email with the result.
Here’s the ValuationHealthCheckService class:


package com.dashboard.services;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import org.apache.log4j.Logger;
import com.dashboard.forms.DashboardForm;

public class ValuationHealthCheckService implements IService {

    private static final Logger logger = Logger.getLogger(ValuationHealthCheckService.class);

    @Override
    public void execute(Object o) throws NamingException, SQLException {
        DashboardForm form = (DashboardForm) o;
        Connection con = null;
        Context ctx = new InitialContext();

        DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/MarginDB");
        con = ds.getConnection();
        String populateAttrs = "{call p_ValuationHealthCheck(?,?)}";

        logger.info("{call p_ValuationHealthCheck(?,?)}");

        if (form.getEmailTo() == null || form.getEmailTo().equals("")) {
            throw new RuntimeException("You must specify at least one email recipient.");
        }

        PreparedStatement populateAttrsStmt = con.prepareStatement(populateAttrs);
        populateAttrsStmt.setString(1, form.getEmailTo());
        populateAttrsStmt.setString(2, form.getEmailCC());
        populateAttrsStmt.execute();
        con.close();
    }
}

I’m retrieving the database connection using the datasource I have defined in Tomcat.
After that, I needed to create the servlet in order to setup the schedule for the job.


import java.text.ParseException;
import javax.servlet.http.HttpServlet;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;
import com.dashboard.util.ValuationHealthCheckJob;

public class QuartzServlet extends HttpServlet {

    public QuartzServlet() throws SchedulerException, ParseException {
        SchedulerFactory sf = new StdSchedulerFactory();
        Scheduler sched = sf.getScheduler();
        // Specify the class of the job I want to execute
        JobDetail jd = new JobDetail("ValuationHealthCheck", "AppGroup", ValuationHealthCheckJob.class);
        // Create a CRON expression
        CronTrigger ct = new CronTrigger("cronTrigger", "cronTrigger", "0 0 15-19 * * ?");
        // Add into the Scheduler the job and the trigger
        sched.scheduleJob(jd, ct);
        sched.start();
    }

}

And as a final step, I needed to define the servlet in the web.xml file.

    <servlet>
        <servlet-name>quartz</servlet-name>
        <servlet-class>
            com.dashboard.servlets.QuartzServlet
        </servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

Just restart the Tomcat so the servlet (and our job) is loaded. From now on, our job will be executed using the cron expression we defined in the servlet: 0 0 15-19 . This means that the job will be executed everyday, every hour from 15 (3:00 PM) to 19 (7:00PM).

Just a note: Make sure you have the JAR file for Quartz in the WEB-INF/lib directory. I’m using maven for my web project so you just need to include the Quartz dependency in the pom.xml:

    <dependency>
        <groupId>opensymphony</groupId>
        <artifactId>quartz</artifactId>
        <version>1.6.0</version>
        <scope>compile</scope>
    </dependency>

That’s all. This was the simplest solution I found for my problem (due to lack of time). However, I will work on the integration with Spring as soon as I have free time.
For more information on Quartz: http://www.opensymphony.com/quartz/

August 25, 2009

Simple XML parser + SQL Generation

Filed under: Financial, Java, MSSQL — Tags: , , , — .|2ic|K @ 10:18 AM

Problem: Quick way to parse an XML stream from a website and generate a SQL script to populate a MSSQL table.

Solution:

import java.io.InputStream;
import java.net.URL;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class XMLReader {

public static void main(String argv[]) {

try {
URL url = new URL("http://www.treasurydirect.gov/xml/CPI_20090814.xml");
InputStream is = url.openStream();

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(is);
doc.getDocumentElement().normalize();
NodeList dailyIndexes = doc.getElementsByTagName("DailyIndexRatio");

/*
* <DailyIndexRatio>
*   <CUSIP>912810FD5</CUSIP>
*   <IssueDate>1998-04-15</IssueDate>
*   <Date>2009-09-01</Date>
*   <RefCPI>215.69300</RefCPI>
*   <IndexRatio>1.33358</IndexRatio>
* </DailyIndexRatio>
*/

for (int s = 0; s < dailyIndexes.getLength(); s++) {
    Node currentIndexNode = dailyIndexes.item(s);
    if (currentIndexNode.getNodeType() == Node.ELEMENT_NODE) {
    // DailyIndexRatio Element
    Element currentIndexElement = (Element) currentIndexNode;

    // List of CUSIP Nodes
    NodeList cusipNodeList = currentIndexElement.getElementsByTagName("CUSIP");
    // CUSIP Element (1st one)
    Element cusipElmnt = (Element) cusipNodeList.item(0);
    // List of child nodes for CUSIP Element
    NodeList cusipChildNodes = cusipElmnt.getChildNodes();
    // Get the value of the 1st node (Text of CUSIP Element)
    //((Node) cusipChildNodes.item(0)).getNodeValue()

    NodeList dateNodeList = currentIndexElement.getElementsByTagName("Date");
    Element dateElmnt = (Element) dateNodeList.item(0);
    NodeList dateChildNodes = dateElmnt.getChildNodes();

    NodeList indexRatioNodeList = currentIndexElement.getElementsByTagName("IndexRatio");
    Element indexRatioElmnt = (Element) indexRatioNodeList.item(0);
    NodeList indexRatioChildNodes = indexRatioElmnt.getChildNodes();

    // SQL SCRIPT GENERATION
    System.out.print("INSERT INTO [CPIData] (Date, CUSIP, CPI) VALUES ('"
    + ((Node) dateChildNodes.item(0)).getNodeValue() + "','");
    System.out.print(((Node) cusipChildNodes.item(0)).getNodeValue() + "',");
    System.out.println(((Node) indexRatioChildNodes.item(0)).getNodeValue() + ")");
    }

}
} catch (Exception e) {
    e.printStackTrace();
}
}
}

Basically, I just needed the Consumer Price Indexes (CPI) that needs to be applied to a particular security (TIPS).
This simple java app returns (console) the SQL script that we need to execute in order to have the CPI’s stored in the DB.

Note: This code has been tested using Eclipse 3.3 and JDK 6.

August 11, 2009

Property Reader in Spring Framework

Filed under: Java — Tags: , , — .|2ic|K @ 9:55 AM

In order to add support to this feature, we must add inside the Spring Context file, the following bean definition:


<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location">
        <value>/WEB-INF/classes/MyPropertyFile.properties</value>
    </property>
</bean>

Where MyPropertyFile.properties is the file that has stored the properties we need to get.
By adding the definition above, we would be able to bind each one of the properties from the file to a particular bean:

<bean id="MyAppService" class="com.application.MyAppService">
    <property name="fileNameProd">
        <value>${application.fileName.prod}</value>
    </property>
    <property name="fileNameQA">
        <value>${application.fileName.qa}</value>
    </property>
    <property name="fileNameUAT">
        <value>${application.fileName.uat}</value>
    </property>
</bean>

When we get the MyAppService Bean, the properties will be already loaded from our file.

Older Posts »

Theme: Shocking Blue Green. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.