com.webbfontaine.valuewebb.timer.RatesUpdater.java Source code

Java tutorial

Introduction

Here is the source code for com.webbfontaine.valuewebb.timer.RatesUpdater.java

Source

package com.webbfontaine.valuewebb.timer;

import com.webbfontaine.valuewebb.model.constants.Constants;
import com.webbfontaine.valuewebb.model.rimm.Rate;
import com.webbfontaine.valuewebb.model.util.Utils;
import com.webbfontaine.valuewebb.startup.ProxyConfiguration;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.hibernate.Transaction;
import org.jboss.seam.annotations.Transactional;
import org.jboss.seam.annotations.async.Asynchronous;
import org.jboss.seam.annotations.async.Expiration;
import org.jboss.seam.annotations.async.IntervalCron;
import org.jboss.seam.async.QuartzTriggerHandle;
import org.jboss.seam.log.Log;
import org.jboss.seam.log.Logging;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import javax.persistence.EntityManager;
import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * Copyrights 2002-2009 Webb Fontaine
 * Developer: Grisha Arzumanyan
 * Date: 12/17/10
 * This software is the proprietary information of Webb Fontaine.
 * Its use is subject to License terms.
 */

public class RatesUpdater {
    private static Log LOGGER = Logging.getLog(RatesUpdater.class);

    private String bankPageUrl;

    public String getBankPageUrl() {
        return bankPageUrl;
    }

    public void setBankPageUrl(String bankPageUrl) {
        this.bankPageUrl = bankPageUrl;
    }

    public HashMap<String, BigDecimal> ratesFromBank() {
        HashMap<String, BigDecimal> rates = new HashMap<String, BigDecimal>();

        Document doc = getPage();
        Elements tables = doc.getElementsByTag("table");
        Element tableOfRates = null;
        Elements trs;
        int pairsCodeIndex = 0;
        int sellingIndex = 0;

        for (Element table : tables) {
            if (table.text().contains("Dollar")) {
                tableOfRates = table;
                break;
            }
        }

        if (tableOfRates != null) {
            trs = tableOfRates.getElementsByTag("tr");
        } else {
            LOGGER.error("Error reading rates from URL");
            return rates;
        }

        Elements columns = trs.get(0).getElementsByTag("th");

        for (int i = 0; i < columns.size(); ++i) {
            if (columns.get(i).text().equalsIgnoreCase("Pairs Code")) {
                pairsCodeIndex = i;
            }

            if (columns.get(i).text().equalsIgnoreCase("Selling")) {
                sellingIndex = i;
            }
        }

        for (Element tr : trs) {
            Elements tds = tr.getElementsByTag("td");

            if (tds.size() != 0) {
                String currPair = tds.get(pairsCodeIndex).text().trim();
                String rateText = tds.get(sellingIndex).text().trim().replace(",", "");
                BigDecimal rate = new BigDecimal(rateText);
                String curr;

                if (currPair.startsWith("GHS")) {
                    curr = currPair.substring(3);
                    rate = new BigDecimal(1).divide(rate, Constants.FRACTION_DIGITS_NUMBER_4,
                            Utils.getRoundingMode());
                } else {
                    curr = currPair.substring(0, currPair.lastIndexOf("GHS"));
                }

                rates.put(curr, rate);
            }
        }
        return rates;
    }

    private Document getPage() {

        Document doc = null;

        DefaultHttpClient httpClient = new DefaultHttpClient();

        ProxyConfiguration.getInstance().addProxy(httpClient);

        HttpGet httpGet = new HttpGet(bankPageUrl);

        try {
            HttpResponse response = httpClient.execute(httpGet);
            if (200 == response.getStatusLine().getStatusCode()) {
                ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
                IOUtils.copy(response.getEntity().getContent(), baos);

                doc = Jsoup.parse(new String(baos.toByteArray(), "UTF-8"));
            }
        } catch (Exception e) {
            LOGGER.error("", e);
        }
        return doc;
    }

    @Asynchronous
    @Transactional
    public QuartzTriggerHandle scheduleTask(@Expiration Date when, @IntervalCron String interval) {

        HashMap<String, BigDecimal> ratesFromBank = ratesFromBank();
        if (ratesFromBank.isEmpty()) {
            LOGGER.error("No rates passed to update, check web site and source code!");
            return null;
        }

        EntityManager entityManager = Utils.getEntityManager();

        List<Rate> existingRates = entityManager.createQuery("from Rate r where r.eov is null").getResultList();

        Transaction tx = ((org.jboss.seam.persistence.HibernateSessionProxy) entityManager.getDelegate())
                .getTransaction();

        try {

            tx.begin();

            for (Rate existingRecord : existingRates) {

                BigDecimal latestRateForCurrency = ratesFromBank.get(existingRecord.getCod());

                if (latestRateForCurrency == null) {
                    LOGGER.warn("Currency code '{0}' exists but absent in updates", existingRecord.getCod());
                    continue;
                }

                if (existingRecord.getExch().doubleValue() != latestRateForCurrency.doubleValue()) { //i get double value because bigdecimal can return 0.2240 which is not equal to 0.224 when comparing BD values
                    /* close existing rate and open new one from today */
                    Date tomorrowDate = Utils.getTomorrowDate();
                    existingRecord.setEov(tomorrowDate); // since scheduler works at 21:00
                    Rate newRecord = new Rate(null, existingRecord.getCod(), 1, latestRateForCurrency, tomorrowDate,
                            null);
                    entityManager.persist(existingRecord);
                    entityManager.persist(newRecord);
                    LOGGER.info("Updated Exchange rate for {0}, old: {1}, new: {2}", newRecord.getCod(),
                            existingRecord.unitRate(), newRecord.unitRate());
                }
            }

            entityManager.flush();
            tx.commit();

        } catch (Exception e) {
            LOGGER.error("Exception on updating rates", e);
            if (tx != null) {
                tx.rollback();
            }
        }

        return null;
    }
}