/* * 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; } }