/*
 * Copyright 2000, University Corporation for Atmospheric Research
 * All Rights Reserved.
 * See file LICENSE for copying and redistribution conditions.
 *
 * $Id: DataFactory.java,v 1.4 2002-10-21 20:07:45 donm Exp $
 */

package visad.data.netcdf.in;

import java.io.IOException;
import java.rmi.RemoteException;
import visad.*;


/**
 * Provides support for creating VisAD Data objects from VirtualData objects.
 *
 * @author Steven R. Emmerson
 */
public class
DataFactory
{
    private static DataFactory  instance;

    static
    {
        instance = new DataFactory();
    }


    protected DataFactory()
    {}


    /**
     * Returns an instance of this class.
     *
     * @return                  An instance of this class.
     */
    public static DataFactory instance()
    {
        return instance;
    }


    /**
     * Creates a VisAD Data object from a netCDF indicial context and a 
     * VirtualData object.
     *
     * @param context           The netCDF indicial context.
     * @param virtualData       The virtual data.
     * @return                  The VisAD Data object corresponding to the
     *                          input.
     * @throws InvalidContextException
     *                          Invalid indicial context.
     * @throws VisADException   VisAD failure.
     * @throws RemoteException  Java RMI failure.
     * @throws IOException      I/O failure.
     */
    public DataImpl newData(Context context, VirtualData virtualData)
        throws RemoteException, VisADException, InvalidContextException,
            IOException
    {
        /*
         * If the types of virtual data proliferate, then the following may be
         * replaced by implementing the Visitor design pattern in VirtualData
         * (e.g. VirtualData.accept(DataFactory)) and using double dispatch to
         * invoke the proper method of this class.
         */
        return
            virtualData instanceof VirtualScalar
                ? (DataImpl)newData(context, (VirtualScalar)virtualData)
                : virtualData instanceof VirtualFlatField
                    ? (DataImpl)newData(context, (VirtualFlatField)virtualData)
                    : virtualData instanceof VirtualField
                        ? (DataImpl)newData(context, (VirtualField)virtualData)
                        : (DataImpl)newData(context, (VirtualTuple)virtualData);
    }


    /**
     * Creates a VisAD Scalar object from a netCDF indicial context and a 
     * VirtualScalar.
     *
     * @param context           The netCDF indicial context.
     * @param virtualScalar     The virtual data.
     * @return                  The VisAD Real corresponding to the input.
     * @throws InvalidContextException
     *                          Invalid indicial context.
     * @throws VisADException   VisAD failure.
     * @throws IOException      I/O failure.
     */
    public Scalar newData(Context context, VirtualScalar virtualScalar)
        throws VisADException, InvalidContextException, IOException
    {
        return virtualScalar.getScalar(context);
    }

    /**
     * Creates a VisAD FlatField object from a netCDF indicial context and a 
     * VirtualFlatField.
     *
     * @param context           The netCDF indicial context.
     * @param virtualField      The virtual data.
     * @return                  The VisAD FlatField corresponding to the input.
     * @throws VisADException   VisAD failure.
     * @throws RemoteException  Java RMI failure.
     * @throws IOException      I/O failure.
     */
    public FlatField newData(Context context, VirtualFlatField virtualField)
        throws VisADException, RemoteException, IOException
    {
        FunctionType    funcType = virtualField.getFunctionType();
        SampledSet      domainSet = virtualField.getDomainSet();
        VirtualTuple    rangeTuple = virtualField.getRangeTuple();
        int             componentCount = rangeTuple.size();
        Set[]           rangeSets = new Set[componentCount];
        Unit[]          rangeUnits = new Unit[componentCount];

        for (int i = 0; i < componentCount; ++i)
        {
            VirtualScalar       component = (VirtualScalar)rangeTuple.get(i);

            rangeSets[i] = component.getRangeSet();
            rangeUnits[i] = component.getUnit();
        }

        FlatField       field =
            new FlatField(
                funcType,
                domainSet,
                (CoordinateSystem)null,
                rangeSets,
                rangeUnits);

        double[][]      values = new double[componentCount][];

        for (int i = 0; i < componentCount; ++i)
            values[i] = ((VirtualScalar)rangeTuple.get(i)).getDoubles(context);

        field.setSamples(values, /*copy=*/false);

        return field;
    }


    /**
     * Creates a VisAD Field object from a netCDF indicial context and a 
     * VirtualField.
     *
     * @param context           The netCDF indicial context.
     * @param virtualField      The virtual data.
     * @return                  The VisAD Field corresponding to the input.
     * @throws VisADException   VisAD failure.
     * @throws RemoteException  Java RMI failure.
     * @throws IOException      I/O failure.
     */
    public FieldImpl newData(Context context, VirtualField virtualField)
        throws VisADException, RemoteException, IOException
    {
        FieldImpl       field;
        if (virtualField instanceof VirtualFlatField)
        {
            field = newData(context, (VirtualFlatField)virtualField);
        }
        else
        {
            FunctionType        funcType = virtualField.getFunctionType();
            SampledSet          domainSet = virtualField.getDomainSet();
            VirtualTuple        rangeTuple = virtualField.getRangeTuple();
            int                 sampleCount = domainSet.getLength();

            field = new FieldImpl(funcType, domainSet);
            context = context.newSubContext();
            for (int i = 0; i < sampleCount; ++i)
            {
                context.setSubContext(i);
                field.setSample(
                    i, newData(context, rangeTuple), /*copy=*/false);
            }
        }
        return field;
    }


    /**
     * Creates a VisAD Data object from a netCDF indicial context and a 
     * VirtualTuple.
     *
     * @param context           The netCDF indicial context.
     * @param virtualTuple      The virtual data.
     * @return                  The VisAD Tuple corresponding to the input.
     * @throws VisADException   VisAD failure.
     * @throws RemoteException  Java RMI failure.
     * @throws IOException      I/O failure.
     */
    public DataImpl newData(Context context, VirtualTuple virtualTuple)
        throws RemoteException, VisADException, IOException
    {
        DataImpl        data = null;
        int             size = virtualTuple.size();

        if (size == 1)
        {
            data = newData(context, virtualTuple.get(0));
        }
        else if (size > 1)
        {
            MathType    type = virtualTuple.getType();

            if (type instanceof RealTupleType)
            {
                Real[]  reals = new Real[size];

                for (int i = 0; i < size; ++i)
                    reals[i] = (Real)
                        newData(context, (VirtualScalar)virtualTuple.get(i));

                data = new RealTuple((RealTupleType)type, reals,
                                     /*(CoordinateSystem)*/null);
            }
            else if (type instanceof TupleType)
            {
                DataImpl[]      datas = new DataImpl[size];

                for (int i = 0; i < datas.length; ++i)
                    datas[i] = newData(context, virtualTuple.get(i));

                data = new Tuple((TupleType)type, datas, /*copy=*/false);
            }
        }

        return data;
    }
}

 

Ads help maintain this website.