All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.sarxos.xchange.ExchangeCache Maven / Gradle / Ivy

package com.github.sarxos.xchange;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class ExchangeCache {

	/**
	 * I'm the logger.
	 */
	private static final Logger LOG = LoggerFactory.getLogger(ExchangeCache.class);

	private static final long DEFAULT_INTERVAL = 60 * 60 * 1000; // 1h

	private static final Map PARAMETERS = new HashMap();

	private final class Updater extends Thread {

		public Updater() {
			super("exchange-cache-updater");
			setDaemon(true);
			start();
		}

		@Override
		public void run() {
			while (true) {
				try {
					throttle();
					init();
				} catch (InterruptedException e) {
					return;
				} catch (Exception e) {
					LOG.error(e.getMessage(), e);
				}
			}
		}

		private void throttle() throws InterruptedException {
			Thread.sleep(interval);
		}
	}

	private final ConcurrentHashMap cache = new ConcurrentHashMap<>();
	private final String base;
	private final Collection currencies = new HashSet();
	private final long interval;
	private final Thread updater;

	public ExchangeCache(String base) {
		this(base, new ArrayList(1));
	}

	public ExchangeCache(String base, String... currencies) {
		this(base, Arrays.asList(currencies));
	}

	public ExchangeCache(String base, Collection currencies) {
		this(base, currencies, DEFAULT_INTERVAL);
	}

	public ExchangeCache(String base, Collection currencies, long interval) {
		this.base = base;
		this.currencies.addAll(currencies);
		this.interval = interval;
		this.init();
		this.updater = new Updater();
	}

	protected Thread getUpdaterThread() {
		return updater;
	}

	private void cache(ExchangeRate rate) {
		currencies.add(rate.getFrom());
		cache.put(rate.getFrom(), rate);
	}

	private synchronized void init() {

		LOG.info("Initializing forex data for {}", currencies);

		Collection rates = null;
		try {
			rates = new ExchangeQuery()
				.from(currencies)
				.to(base)
				.get();
		} catch (ExchangeException e) {
			LOG.error("Cannot initialize exchange cache", e);
		}

		if (rates == null) {
			return;
		}

		for (ExchangeRate rate : rates) {
			cache(rate);
		}
	}

	private ExchangeRate preload(String currency) throws ExchangeException {

		LOG.warn("Preloading currency {}", currency);

		Collection rates = new ExchangeQuery()
			.from(Arrays.asList(currency))
			.to(base)
			.get();

		// get first and the only one

		ExchangeRate rate = rates.iterator().next();

		// put it into the cache

		cache(rate);

		// and return

		return rate;
	}

	public ExchangeRate getRate(String currency) throws ExchangeException {

		ExchangeRate rate = cache.get(currency);
		if (rate == null) {
			rate = preload(currency);
		}

		return rate;
	}

	public static void setParameter(String key, Object value) {
		PARAMETERS.put(key, value);
	}

	public static Object getParameter(String key) {
		return PARAMETERS.get(key);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy