/** * Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.integration.tool.portfolio.xml; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Iterator; import com.google.common.base.Function; import com.google.common.collect.Iterables; import com.opengamma.OpenGammaRuntimeException; import com.opengamma.integration.copier.portfolio.reader.PositionReader; /** * Parses an XML file and if the file is valid, generates a collection * of Portfolio readers (one for each portfolio in the file). Note that * as the class implements Iterable, it is stateful and not thread safe. */ public class XmlFileReader implements Iterable<PositionReader> { /** * The portfolio readers available after the file has been successfully parsed. */ private final Iterable<PositionReader> _readers; /** * Constructs the reader from the supplied location. The following validation * steps are performed: * <ul> * <li>Check the file is valid xml and contains a schemaVersion attribute</li> * <li>Check that a converter is available for the schema version</li> * <li>Check the file validates against the required schema</li> * <li>Check the portfolio, position, trade, security details are valid</li> * </ul> * * @param inputStream the input stream of the file, must not be null * @param schemaRegister the schema register, use to determine what xml * versions can be handled */ public XmlFileReader(InputStream inputStream, SchemaRegister schemaRegister) { // Create a ByteArrayInputStream to ensure reset() is available ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { org.apache.commons.io.IOUtils.copy(inputStream, baos); } catch (IOException e) { throw new OpenGammaRuntimeException("Unable to read xml", e); } byte[] bytes = baos.toByteArray(); ByteArrayInputStream bais = new ByteArrayInputStream(bytes); SchemaVersion version = extractSchemaVersion(bais); PortfolioConversion converter = schemaRegister.getConverterForSchema(version); //reset after schema version is extracted bais.reset(); if (converter != null) { Iterable<VersionedPortfolioHandler> handlers = converter.convertPortfolio(bais); _readers = Iterables.transform(handlers, new Function<VersionedPortfolioHandler, PositionReader>() { @Override public PositionReader apply(final VersionedPortfolioHandler vph) { return new XmlPositionReader(vph); } }); } else { throw new OpenGammaRuntimeException("Unable to process schema version: " + version + " as no converter is available"); } } @Override public Iterator<PositionReader> iterator() { return _readers.iterator(); } private SchemaVersion extractSchemaVersion(InputStream inputStream) { return new SchemaVersionParser(new InputStreamReader(inputStream)).parseSchemaVersion(); } }