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

uk.ac.starlink.gbin.GbinTableBuilder Maven / Gradle / Ivy

There is a newer version: 4.3
Show newest version
package uk.ac.starlink.gbin;

import java.awt.datatransfer.DataFlavor;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import uk.ac.starlink.table.DefaultValueInfo;
import uk.ac.starlink.table.DescribedValue;
import uk.ac.starlink.table.RowSequence;
import uk.ac.starlink.table.StarTable;
import uk.ac.starlink.table.StoragePolicy;
import uk.ac.starlink.table.TableFormatException;
import uk.ac.starlink.table.TableSink;
import uk.ac.starlink.table.ValueInfo;
import uk.ac.starlink.table.WrapperRowSequence;
import uk.ac.starlink.table.formats.DocumentedTableBuilder;
import uk.ac.starlink.util.DataSource;

/**
 * TableBuilder implementation for GBIN files.
 *
 * @author   Mark Taylor
 * @since    14 Aug 2014
 */
public class GbinTableBuilder extends DocumentedTableBuilder {

    private final GbinTableProfile profile_;

    /** ValueInfo for GBIN row object classname. */
    public static final ValueInfo CLASSNAME_INFO =
        new DefaultValueInfo( "GbinClass", String.class,
                              "Classname of GBIN objects" );

    /** ValueInfo for well-known Gaia table name. */
    public static final ValueInfo GAIATABLENAME_INFO =
        new DefaultValueInfo( "GaiaTableName", String.class,
                              "Well-known name of Gaia table" );

    /** ValueInfo for Gaia table description string. */
    public static final ValueInfo DESCRIP_INFO =
        new DefaultValueInfo( "Description", String.class,
                              "Table description from Gaia data model" );

    /** ValueInfo for Gaia column detailed description string. */
    public static final ValueInfo COLDETAIL_INFO =
        new DefaultValueInfo( "GaiaDetail", String.class,
                              "Detailed column description"
                            + " from Gaia data model" );

    /** ValueInfo for GBIN build description string. */
    public static final ValueInfo BUILDDESCRIP_INFO =
        new DefaultValueInfo( "GbinDescription", String.class,
                              "GBIN build description" );

    /**
     * Constructs a builder with default options.
     */
    public GbinTableBuilder() {
        this( new DefaultGbinTableProfile() );
    }

    /**
     * Constructs a builder with custom options.
     *
     * @param  profile  configures how GBIN files will be mapped to a table
     */
    public GbinTableBuilder( GbinTableProfile profile ) {
        super( new String[] { "gbin" } );
        profile_ = profile;
    }

    /**
     * Returns the object configuring how GBIN files are mapped to tables.
     *
     * @return  configuration profile
     */
    public GbinTableProfile getProfile() {
        return profile_;
    }

    /**
     * Returns "GBIN".
     */
    public String getFormatName() {
        return "GBIN";
    }

    public boolean canImport( DataFlavor flavor ) {
        return false;
    }

    public void streamStarTable( InputStream in, TableSink sink, String pos )
            throws IOException {
        try {
            GbinObjectReader reader = GbinObjectReader.createReader( in );
            if ( ! reader.hasNext() ) {
                throw new IOException( "No objects in GBIN file" );
            }
            Object gobj0 = reader.next();
            GbinStarTable table =
                    new GbinStarTable( profile_, gobj0.getClass() ) {
                public long getRowCount() {
                    return -1;
                }
                public RowSequence getRowSequence() {
                    throw new UnsupportedOperationException();
                }
            };
            sink.acceptMetadata( table );
            RowSequence rseq = table.createRowSequence( reader, gobj0 );
            while ( rseq.next() ) {
                sink.acceptRow( rseq.getRow() );
            }
            sink.endRows();
            rseq.close();
        }
        finally {
            in.close();
        }
    }

    public StarTable makeStarTable( final DataSource datsrc, boolean wantRandom,
                                    StoragePolicy storage )
            throws IOException {

        /* If required, check the magic number of the input file. */
        if ( profile_.isTestMagic() &&
             ! GbinObjectReader.isMagic( datsrc.getIntro() ) ) {
            throw new TableFormatException( "Not GBIN" );
        }

        /* Read an object out of the file to find out the data type. */
        InputStream in = new BufferedInputStream( datsrc.getInputStream() );
        GbinObjectReader rdr = GbinObjectReader.createReader( in );
        if ( ! rdr.hasNext() ) {
            throw new IOException( "No objects in GBIN file" );
        }
        Class gobjClazz = rdr.next().getClass();
        in.close();

        /* If required, read the start of the file again to obtain
         * non-essential metadata.  This requires another read, since the
         * way GBIN files and the GaiaTools reader API are arranged,
         * pretty much anything you read from a GBIN file makes it
         * useless for reading anything else. */
        final long nrow;
        final List params = new ArrayList();
        if ( profile_.isReadMeta() ) {
            Long nrowObj;
            InputStream metaIn =
                new BufferedInputStream( datsrc.getInputStream() );
            try {
                Object gbinRdrObj =
                    GbinObjectReader.createGbinReaderObject( metaIn );
                GbinMeta meta =
                    GbinMetadataReader.attemptReadMetadata( gbinRdrObj );
                nrowObj = meta.getTotalElementCount();
                params.add(
                     new DescribedValue( BUILDDESCRIP_INFO,
                                         meta.buildDescription( false ) ) );
            }
            catch ( Throwable e ) {
                nrowObj = null;
                GbinObjectReader.logError( Level.WARNING,
                                           "Couldn't read GBIN metadata", e );
            }
            finally {
                metaIn.close();
            }
            nrow = nrowObj == null ? -1 : nrowObj.longValue();
        }
        else {
            nrow = -1;
        }

        /* Construct a table with the metadata we have obtained,
         * and return it. */
        final long nrow0 = nrow;
        StarTable table = new GbinStarTable( profile_, gobjClazz ) {
            public RowSequence getRowSequence() throws IOException {
                final InputStream in =
                    new BufferedInputStream( datsrc.getInputStream() );
                GbinObjectReader reader = GbinObjectReader.createReader( in );
                if ( ! reader.hasNext() ) {
                    throw new IOException( "No objects in GBIN file" );
                }
                Object gobj0 = reader.next();
                return new WrapperRowSequence( createRowSequence( reader,
                                                                  gobj0 ) ) {
                    @Override
                    public void close() throws IOException {
                        in.close();
                    }
                };
            }
            public long getRowCount() {
                return nrow0;
            }
        };
        for ( DescribedValue param : params ) {
            table.setParameter( param );
        }
        return table;
    }

    public boolean canStream() {
        return true;
    }

    public boolean docIncludesExample() {
        return false;
    }

    public String getXmlDescription() {
        return readText( "GbinTableBuilder.xml" );
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy