/*
* Copyright 1998, University Corporation for Atmospheric Research
* All Rights Reserved.
* See file LICENSE for copying and redistribution conditions.
*
* $Id: VirtualScalar.java,v 1.7 2002-10-21 20:07:47 donm Exp $
*/
package visad.data.netcdf.in;
import java.lang.reflect.Array;
import java.io.IOException;
import java.rmi.RemoteException;
import ucar.netcdf.Variable;
import visad.*;
/**
* Provides support for a virtual VisAD Scalar.
*/
public abstract class
VirtualScalar
extends VirtualData
{
/**
* The factory for creating VisAD data objects.
*/
private DataFactory dataFactory = DataFactory.instance();
/**
* The VisAD MathType of the scalar.
*/
private ScalarType type;
/**
* The netCDF variable that constitutes the scalar.
*/
private final Variable var;
/**
* Constructs from a scalar type, a 1-D netCDF variable, a range set,
* a unit, and a value vetter.
*
* @param type The type of the nested scalar.
* @param var The 1-D netCDF variable.
* @param rangeSet The range set of the values.
* @param unit The unit of the values.
* @param vetter The value vetter.
*/
public
VirtualScalar(ScalarType type, Variable var, SimpleSet rangeSet,
Unit unit, Vetter vetter)
{
this(type, var);
}
/**
* Constructs from a scalar type and a 1-D netCDF variable
*
* @param type The type of the nested scalar.
* @param var The 1-D netCDF variable.
*/
public
VirtualScalar(ScalarType type, Variable var)
{
this.type = type;
this.var = var;
}
/**
* Gets the ScalarType of this scalar.
*
* @return The ScalarType of this scalar.
*/
public ScalarType
getScalarType()
{
return type;
}
/**
* Gets the MathType of this scalar.
*
* @return The ScalarType of this scalar.
*/
public MathType
getType()
{
return getScalarType();
}
/**
* Determines if this is a VirtualReal or not.
*
* @return true if this is a VirtualReal
*/
public boolean
isReal()
{
return false;
}
/**
* Gets the range set of this scalar.
*
* @return The range set of this scalar.
* @throws RuntimeException if class doesn't support this.
*/
public SimpleSet
getRangeSet()
{
throw new RuntimeException();
}
/**
* Gets the unit of the value.
*
* @return The unit of the value.
* @throws RuntimeException if class doesn't support this.
*/
public Unit
getUnit()
{
throw new RuntimeException();
}
/**
* Gets the netCDF variable.
*
* @return The netCDF variable.
*/
public Variable
getVariable()
{
return var;
}
/**
* Gets the value vetter.
*
* @return The value vetter.
* @throws RuntimeException if class doesn't support this.
*/
public Vetter
getVetter()
{
throw new RuntimeException();
}
/**
* Gets the VisAD data object corresponding to this virtual, data
* object.
*
* @return The VisAD Scalar corresponding to this
* virtual, data object.
* throws InvalidContextException
* Invalid context.
* @throws InvalidContextException
* if the indicial context is invalid.
* @throws VisADException Couldn't create necessary VisAD object.
* @throws RemoteException if a Java RMI failure occurs.
* @throws IOException I/O failure.
*/
public DataImpl getData(Context context)
throws InvalidContextException, VisADException, RemoteException, IOException
{
return getDataFactory().newData(context, this);
}
/**
* Gets the Scalar object corresponding to this virtual, data
* object.
*
* @return The VisAD Scalar corresponding to this
* virtual, data object.
* @throws InvalidContextException
* if the indicial context is invalid.
* @throws VisADException Couldn't create necessary VisAD object.
* @throws RemoteException if a Java RMI failure occurs.
* @throws IOException I/O failure.
*/
protected abstract Scalar getScalar(Context context)
throws VisADException, InvalidContextException, IOException;
/**
* Gets the double values corresponding to this virtual, data
* object at a given context.
*
* @return The double values of this virtual, data object.
* @throws VisADException Couldn't create necessary VisAD object.
* @throws IOException I/O failure.
* @throws RuntimeException if class doesn't support this.
*/
public double[]
getDoubles(Context context)
throws IOException, VisADException
{
throw new RuntimeException();
}
/**
* Gets data values of a netCDF variable and performs type conversion.
*
* @param var A netCDF variable.
* @param values The destination array for the data values.
* <code>values.length</code> must be >=
* the number of points represented by
* <code>shape</code>.
* @param origin The origin vector for the values.
* @param shape The shape of the I/O transfer.
* @return <code>values</code>.
* @throws IOException I/O failure.
* @see ucar.netcdf.Variable#toArray(Object, int[], int[])
*/
static Object
toArray(Variable var, double[] values, int[] origin, int[] shape)
throws IOException
{
// TODO: support text
if (var.getRank() == 0)
{
values[0] = var.getDouble(new int[] {});
}
else
{
Class fromClass = var.getComponentType();
if (fromClass.equals(double.class))
{
var.toArray(values, origin, shape);
}
else
{
int length = 1;
for (int i = 0; i < shape.length; ++i)
length *= shape[i];
Object dst = Array.newInstance(fromClass, length);
var.toArray(dst, origin, shape);
if (fromClass.equals(byte.class))
{
byte[] fromArray = (byte[])dst;
for (int i = 0; i < fromArray.length; ++i)
values[i] = fromArray[i];
}
else if (fromClass.equals(short.class))
{
short[] fromArray = (short[])dst;
for (int i = 0; i < fromArray.length; ++i)
values[i] = fromArray[i];
}
else if (fromClass.equals(int.class))
{
int[] fromArray = (int[])dst;
for (int i = 0; i < fromArray.length; ++i)
values[i] = fromArray[i];
}
else if (fromClass.equals(float.class))
{
float[] fromArray = (float[])dst;
for (int i = 0; i < fromArray.length; ++i)
values[i] = fromArray[i];
}
}
}
return values;
}
/**
* Sets the factory used to create VisAD data objects.
*
* @param factory The factory for creating VisAD data objects.
*/
public void setDataFactory(DataFactory factory)
{
dataFactory = factory;
}
/**
* Returns the factory used to create VisAD data objects.
*
* @return factory The factory for creating VisAD data objects.
*/
public DataFactory getDataFactory()
{
return dataFactory;
}
}