com.opengamma.integration.copier.portfolio.reader.ZippedPortfolioReader.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.integration.copier.portfolio.reader.ZippedPortfolioReader.java

Source

/**
 * Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies
 * 
 * Please see distribution for license.
 */
package com.opengamma.integration.copier.portfolio.reader;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.apache.commons.lang.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.integration.copier.portfolio.rowparser.JodaBeanRowParser;
import com.opengamma.integration.copier.portfolio.rowparser.RowParser;
import com.opengamma.integration.copier.sheet.reader.CsvSheetReader;
import com.opengamma.integration.copier.sheet.reader.SheetReader;
import com.opengamma.master.position.ManageablePosition;
import com.opengamma.master.security.ManageableSecurity;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.tuple.ObjectsPair;

/**
 * Portfolio reader that reads multiple CSV files within a ZIP archive, identifies the correct parser class for each,
 * using the file name, and persists all loaded trades/entries using the specified portfolio writer. Folder structure
 * in the ZIP archive is replicated in the portfolio node structure.
 */
public class ZippedPortfolioReader implements PortfolioReader {

    private static final Logger s_logger = LoggerFactory.getLogger(ZippedPortfolioReader.class);

    private static final String SHEET_EXTENSION = ".csv";

    private ZipFile _zipFile;
    private Map<String, Integer> _versionMap = new HashMap<String, Integer>();

    private Enumeration<ZipEntry> _zipEntries;
    private PortfolioReader _currentReader;
    private String[] _currentPath = new String[0];
    private boolean _ignoreVersion;

    @SuppressWarnings("unchecked")
    public ZippedPortfolioReader(String filename, boolean ignoreVersion) {

        ArgumentChecker.notNull(filename, "filename");

        try {
            _zipFile = new ZipFile(filename);
            _zipEntries = (Enumeration<ZipEntry>) _zipFile.entries();
        } catch (IOException ex) {
            throw new OpenGammaRuntimeException("Could not open " + filename);
        }

        _ignoreVersion = ignoreVersion;

        if (!_ignoreVersion) {
            // Retrieve security hashes listed in config file
            readMetaData("METADATA.INI");
        }

        s_logger.info("Using ZIP archive " + filename);
    }

    @Override
    public ObjectsPair<ManageablePosition, ManageableSecurity[]> readNext() {

        while (true) {
            // Try to get the next row from the current csv in the zip archive
            ObjectsPair<ManageablePosition, ManageableSecurity[]> next = _currentReader == null ? null
                    : _currentReader.readNext();

            if (next != null) {
                return next;

                // If no more rows to get in the current csv, and no more zip entries, then we've reached the end
            } else if (!_zipEntries.hasMoreElements()) {
                return null;

                // More zip entries, try get another csv and return a row from it
            } else {
                // Get the portfolio reader for this csv file
                _currentReader = getReader(_zipEntries.nextElement());
            }
        }
    }

    private PortfolioReader getReader(ZipEntry entry) {

        if (!entry.isDirectory()
                && entry.getName().substring(entry.getName().lastIndexOf('.')).equalsIgnoreCase(SHEET_EXTENSION)) {
            try {
                // Extract full path
                String[] fullPath = entry.getName().split("/");

                // Extract security name
                String secType = fullPath[fullPath.length - 1].substring(0,
                        fullPath[fullPath.length - 1].lastIndexOf('.'));

                _currentPath = (String[]) ArrayUtils.subarray(fullPath, 0, fullPath.length - 1);

                // Set up a sheet reader and a row parser for the current CSV file in the ZIP archive
                SheetReader sheet = new CsvSheetReader(_zipFile.getInputStream(entry));

                RowParser parser = JodaBeanRowParser.newJodaBeanRowParser(secType);
                if (parser == null) {
                    s_logger.error("Could not build a row parser for security type '" + secType + "'");
                    return null;
                }
                if (!_ignoreVersion) {
                    if (_versionMap.get(secType) == null) {
                        s_logger.error("Versioning hash for security type '" + secType + "' could not be found");
                        return null;
                    }
                    if (parser.getSecurityHashCode() != _versionMap.get(secType)) {
                        s_logger.error("The parser version for the '" + secType + "' security (hash "
                                + Integer.toHexString(parser.getSecurityHashCode())
                                + ") does not match the data stored in the archive (hash "
                                + Integer.toHexString(_versionMap.get(secType)) + ")");
                        return null;
                    }
                }

                s_logger.info("Processing rows in archive entry " + entry.getName() + " as " + secType);

                // Create a simple portfolio reader for the current sheet
                return new SingleSheetSimplePortfolioReader(sheet, parser);

            } catch (Throwable ex) {
                s_logger.warn(
                        "Could not import from " + entry.getName() + ", skipping file (exception is " + ex + ")");
                return null;
            }
        } else {
            return null;
        }
    }

    private void readMetaData(String filename) {

        InputStream cfgInputStream;
        ZipEntry cfgEntry = _zipFile.getEntry(filename);
        if (cfgEntry != null) {
            try {
                cfgInputStream = _zipFile.getInputStream(cfgEntry);
                BufferedReader cfgReader = new BufferedReader(new InputStreamReader(cfgInputStream));

                String input;
                while ((input = cfgReader.readLine()) != null && !input.equals("[securityHashes]"))
                    ; // CSIGNORE

                while ((input = cfgReader.readLine()) != null) {
                    String[] line = input.split("=", 2);
                    if (line.length == 2) {
                        try {
                            _versionMap.put(line[0].trim(), (int) Long.parseLong(line[1].trim(), 16));
                        } catch (NumberFormatException e) {
                            continue;
                        }
                    } else if (input.contains("[]")) {
                        break;
                    } else {
                        continue;
                    }
                }

            } catch (IOException ex) {
                throw new OpenGammaRuntimeException("Could not open METADATA.INI");
            }
        } else {
            throw new OpenGammaRuntimeException("Could not find METADATA.INI");
        }
    }

    @Override
    public String[] getCurrentPath() {
        return _currentPath;
    }

    @Override
    public void close() {
        try {
            _zipFile.close();
        } catch (IOException ex) {
        }
    }

    @Override
    public String getPortfolioName() {
        return null;
    }
}