com.opengamma.master.region.impl.RegionFileReader.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.master.region.impl.RegionFileReader.java

Source

/**
 * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
 *
 * Please see distribution for license.
 */
package com.opengamma.master.region.impl;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;

import au.com.bytecode.opencsv.CSVReader;

import com.google.common.base.Charsets;
import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.core.id.ExternalSchemes;
import com.opengamma.core.region.RegionClassification;
import com.opengamma.id.UniqueId;
import com.opengamma.master.region.ManageableRegion;
import com.opengamma.master.region.RegionDocument;
import com.opengamma.master.region.RegionMaster;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.i18n.Country;
import com.opengamma.util.money.Currency;

/**
 * Loads a CSV formatted region file
 * <p>
 * This populates a region master.
 */
public class RegionFileReader {

    /**
     * Path to the default regions file
     */
    private static final String REGIONS_RESOURCE = "/com/opengamma/region/regions.csv";
    /**
     * The name column header.
     */
    private static final String NAME_COLUMN = "Name";
    /**
     * The full name column header.
     */
    private static final String FORMAL_NAME_COLUMN = "Formal Name";
    /**
     * The type column header.
     */
    private static final String CLASSIFICATION_COLUMN = "Type";
    /**
     * The sovereignty column header.
     */
    private static final String SOVEREIGNITY_COLUMN = "Sovereignty";
    /**
     * The country code column header.
     */
    private static final String ISO_COUNTRY_2_COLUMN = "ISO 3166-1 2 Letter Code";
    /**
     * The currency code column header.
     */
    private static final String ISO_CURRENCY_3_COLUMN = "ISO 4217 Currency Code";
    /**
     * The sub regions column header
     */
    private static final String SUB_REGIONS_COLUMN = "Sub Regions";

    /**
     * The region master to populate.
     */
    private RegionMaster _regionMaster;

    /**
     * Creates a populated in-memory master and source.
     * <p>
     * The values can be extracted using the accessor methods.
     * 
     * @return the region reader, not null
     */
    public static RegionFileReader createPopulated() {
        return createPopulated0(new InMemoryRegionMaster());
    }

    /**
     * Populates a region master.
     * 
     * @param regionMaster  the region master to populate, not null
     * @return the master, not null
     */
    public static RegionMaster createPopulated(RegionMaster regionMaster) {
        return createPopulated0(regionMaster).getRegionMaster();
    }

    /**
     * Creates a populated file reader.
     * <p>
     * The values can be extracted using the accessor methods.
     * 
     * @param regionMaster  the region master to populate, not null
     * @return the region reader, not null
     */
    private static RegionFileReader createPopulated0(RegionMaster regionMaster) {
        RegionFileReader fileReader = new RegionFileReader(regionMaster);
        InputStream stream = regionMaster.getClass().getResourceAsStream(REGIONS_RESOURCE);
        try {
            fileReader.parse(stream);
        } finally {
            IOUtils.closeQuietly(stream);
        }
        UnLocodeRegionFileReader.populate(regionMaster);
        return fileReader;
    }

    //-------------------------------------------------------------------------
    /**
     * Creates an instance with a master to populate.
     * 
     * @param regionMaster  the region master, not null
     */
    public RegionFileReader(RegionMaster regionMaster) {
        ArgumentChecker.notNull(regionMaster, "regionMaster");
        _regionMaster = regionMaster;
    }

    //-------------------------------------------------------------------------
    /**
     * Gets the region master.
     * @return the region master, not null
     */
    public RegionMaster getRegionMaster() {
        return _regionMaster;
    }

    /**
     * Gets a {@code MasterRegionSource} for the master.
     * @return the region source, not null
     */
    public MasterRegionSource getRegionSource() {
        return new MasterRegionSource(getRegionMaster());
    }

    //-------------------------------------------------------------------------
    /**
     * Parses the specified file to populate the master.
     * 
     * @param in  the input stream to read, not null
     */
    public void parse(InputStream in) {
        InputStreamReader reader = new InputStreamReader(new BufferedInputStream(in), Charsets.UTF_8);
        try {
            parse(reader);
        } finally {
            IOUtils.closeQuietly(reader);
        }
    }

    /**
     * Parses the specified file to populate the master.
     * 
     * @param in  the input reader to read, not closed, not null
     */
    public void parse(Reader in) {
        String name = null;
        try {
            Map<String, ManageableRegion> regions = new HashMap<String, ManageableRegion>();
            Map<UniqueId, Set<String>> subRegions = new HashMap<UniqueId, Set<String>>();

            // open CSV file
            @SuppressWarnings("resource")
            CSVReader reader = new CSVReader(in);
            List<String> columns = Arrays.asList(reader.readNext());

            // identify columns
            final int nameColumnIdx = columns.indexOf(NAME_COLUMN);
            final int formalNameColumnIdx = columns.indexOf(FORMAL_NAME_COLUMN);
            final int classificationColumnIdx = columns.indexOf(CLASSIFICATION_COLUMN);
            final int sovereignityColumnIdx = columns.indexOf(SOVEREIGNITY_COLUMN);
            final int countryColumnIdx = columns.indexOf(ISO_COUNTRY_2_COLUMN);
            final int currencyColumnIdx = columns.indexOf(ISO_CURRENCY_3_COLUMN);
            final int subRegionsColumnIdx = columns.indexOf(SUB_REGIONS_COLUMN);

            // parse
            String[] row = null;
            while ((row = reader.readNext()) != null) {
                name = row[nameColumnIdx].trim(); // the primary key
                String fullName = StringUtils.trimToNull(row[formalNameColumnIdx]);
                if (fullName == null) {
                    fullName = name;
                }
                RegionClassification classification = RegionClassification
                        .valueOf(row[classificationColumnIdx].trim());
                String sovereignity = StringUtils.trimToNull(row[sovereignityColumnIdx]);
                String countryISO = StringUtils.trimToNull(row[countryColumnIdx]);
                String currencyISO = StringUtils.trimToNull(row[currencyColumnIdx]);
                Set<String> rowSubRegions = new HashSet<String>(Arrays.asList(row[subRegionsColumnIdx].split(";")));
                rowSubRegions = trim(rowSubRegions);

                ManageableRegion region = new ManageableRegion();
                region.setClassification(classification);
                region.setName(name);
                region.setFullName(fullName);
                if (countryISO != null) {
                    region.setCountry(Country.of(countryISO));
                    region.addExternalId(ExternalSchemes.financialRegionId(countryISO)); // TODO: looks odd
                }
                if (currencyISO != null) {
                    region.setCurrency(Currency.of(currencyISO));
                }
                if (sovereignity != null) {
                    ManageableRegion parent = regions.get(sovereignity);
                    if (parent == null) {
                        throw new OpenGammaRuntimeException(
                                "Cannot find parent '" + sovereignity + "'  for '" + name + "'");
                    }
                    region.getParentRegionIds().add(parent.getUniqueId());
                }
                for (Entry<UniqueId, Set<String>> entry : subRegions.entrySet()) {
                    if (entry.getValue().remove(name)) {
                        region.getParentRegionIds().add(entry.getKey());
                    }
                }

                // store
                RegionDocument doc = getRegionMaster().add(new RegionDocument(region));
                if (rowSubRegions.size() > 0) {
                    subRegions.put(doc.getUniqueId(), rowSubRegions);
                }
                regions.put(name, region);
            }
            for (Set<String> set : subRegions.values()) {
                if (set.size() > 0) {
                    throw new OpenGammaRuntimeException("Cannot find children: " + set);
                }
            }

        } catch (Exception ex) {
            String detail = (name != null ? " while processing " + name : "");
            throw new OpenGammaRuntimeException("Cannot open region data file (or file I/O problem)" + detail, ex);
        }
    }

    /**
     * Trim the contents of a set.
     * @param subRegions  the set to trim, not null
     * @return the trimmed set, not null
     */
    private Set<String> trim(Set<String> subRegions) {
        Set<String> result = new HashSet<String>();
        for (String subRegion : subRegions) {
            String trimmed = subRegion.trim();
            if (trimmed.isEmpty() == false) {
                result.add(trimmed);
            }
        }
        return result;
    }

}