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

org.knowm.xchange.BaseExchange Maven / Gradle / Ivy

package org.knowm.xchange;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.knowm.xchange.currency.CurrencyPair;
import org.knowm.xchange.dto.meta.ExchangeMetaData;
import org.knowm.xchange.exceptions.ExchangeException;
import org.knowm.xchange.service.BaseExchangeService;
import org.knowm.xchange.service.account.AccountService;
import org.knowm.xchange.service.marketdata.MarketDataService;
import org.knowm.xchange.service.trade.TradeService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class BaseExchange implements Exchange {

  protected final Logger logger = LoggerFactory.getLogger(getClass());
  protected ExchangeSpecification exchangeSpecification;
  protected ExchangeMetaData exchangeMetaData;
  protected MarketDataService marketDataService;
  protected TradeService tradeService;
  protected AccountService accountService;

  protected abstract void initServices();

  @Override
  public void applySpecification(ExchangeSpecification exchangeSpecification) {

    ExchangeSpecification defaultSpecification = getDefaultExchangeSpecification();

    // Check if default is for everything
    if (exchangeSpecification == null) {
      this.exchangeSpecification = defaultSpecification;
    } else {
      // Using a configured exchange
      // fill in null params with the default ones
      if (exchangeSpecification.getExchangeName() == null) {
        exchangeSpecification.setExchangeName(defaultSpecification.getExchangeName());
      }
      if (exchangeSpecification.getExchangeDescription() == null) {
        exchangeSpecification.setExchangeDescription(defaultSpecification.getExchangeDescription());
      }
      if (exchangeSpecification.getSslUri() == null) {
        exchangeSpecification.setSslUri(defaultSpecification.getSslUri());
      }
      if (exchangeSpecification.getHost() == null) {
        exchangeSpecification.setHost(defaultSpecification.getHost());
      }
      if (exchangeSpecification.getPlainTextUri() == null) {
        exchangeSpecification.setPlainTextUri(defaultSpecification.getPlainTextUri());
      }
      if (exchangeSpecification.getExchangeSpecificParameters() == null) {
        exchangeSpecification.setExchangeSpecificParameters(
            defaultSpecification.getExchangeSpecificParameters());
      } else {
        // add default value unless it is overridden by current spec
        for (Map.Entry entry :
            defaultSpecification.getExchangeSpecificParameters().entrySet()) {
          if (exchangeSpecification.getExchangeSpecificParametersItem(entry.getKey()) == null) {
            exchangeSpecification.setExchangeSpecificParametersItem(
                entry.getKey(), entry.getValue());
          }
        }
      }

      this.exchangeSpecification = exchangeSpecification;
    }

    if (this.exchangeSpecification.getMetaDataJsonFileOverride()
        != null) { // load the metadata from the file system

      try (InputStream is =
          new FileInputStream(this.exchangeSpecification.getMetaDataJsonFileOverride())) {
        loadExchangeMetaData(is);
      } catch (IOException e) {
        throw new ExchangeException(e);
      }

    } else if (this.exchangeSpecification.getExchangeName()
        != null) { // load the metadata from the classpath

      try (InputStream is =
          BaseExchangeService.class
              .getClassLoader()
              .getResourceAsStream(getMetaDataFileName(this.exchangeSpecification) + ".json")) {

        loadExchangeMetaData(is);
      } catch (IOException e) {
        throw new ExchangeException(e);
      }

    } else {
      logger.warn(
          "No \"exchange name\" found in the ExchangeSpecification. The name is used to load the meta data file from the classpath and may lead to unexpected results.");
    }

    initServices();

    if (this.exchangeSpecification.isShouldLoadRemoteMetaData()) {
      try {
        logger.info("Calling Remote Init...");
        remoteInit();
      } catch (IOException e) {
        throw new ExchangeException(e);
      }
    }
  }

  @Override
  public void remoteInit() throws IOException, ExchangeException {

    logger.info(
        "No remote initialization implemented for {}. The exchange meta data for this exchange is loaded from a json file containing hard-coded exchange meta-data. This may or may not be OK for you, and you should understand exactly how this works. Each exchange can either 1) rely on the hard-coded json file that comes packaged with XChange's jar, 2) provide your own override json file, 3) properly implement the `remoteInit()` method for the exchange (please submit a pull request so the whole community can benefit) or 4) a combination of hard-coded JSON and remote API calls. For more info see: https://github.com/timmolter/XChange/wiki/Design-Notes#exchange-metadata",
        exchangeSpecification.getExchangeName());
  }

  protected void loadExchangeMetaData(InputStream is) {

    exchangeMetaData = loadMetaData(is, ExchangeMetaData.class);
  }

  protected  T loadMetaData(InputStream is, Class type) {

    // Use Jackson to parse it
    ObjectMapper mapper = new ObjectMapper();

    try {
      T result = mapper.readValue(is, type);
      logger.debug(result.toString());
      return result;
    } catch (Exception e) {
      logger.warn(
          "An exception occured while loading the metadata file from the file system. This is just a warning and can be ignored, but it may lead to unexpected results, so it's better to address it.",
          e);
      return null;
    }
  }

  @Override
  public List getExchangeSymbols() {

    return new ArrayList<>(getExchangeMetaData().getCurrencyPairs().keySet());
  }

  public String getMetaDataFileName(ExchangeSpecification exchangeSpecification) {

    return exchangeSpecification
        .getExchangeName()
        .toLowerCase()
        .replace(" ", "")
        .replace("-", "")
        .replace(".", "");
  }

  @Override
  public ExchangeSpecification getExchangeSpecification() {

    return exchangeSpecification;
  }

  @Override
  public ExchangeMetaData getExchangeMetaData() {

    return exchangeMetaData;
  }

  public MarketDataService getMarketDataService() {

    return marketDataService;
  }

  public TradeService getTradeService() {

    return tradeService;
  }

  public AccountService getAccountService() {

    return accountService;
  }

  @Override
  public String toString() {

    String name =
        exchangeSpecification != null
            ? exchangeSpecification.getExchangeName()
            : getClass().getName();
    return name + "#" + hashCode();
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy