/*
VisAD system for interactive analysis and visualization of numerical
data. Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA
*/
package visad.data.dods;
import dods.dap.*;
import visad.*;
import visad.data.*;
import visad.data.units.Parser;
/**
* Provides support for adapting DODS objects to the VisAD data-import context.
*
* <P>Instances are immutable.</P>
*
* @author Steven R. Emmerson
*/
public abstract class Adapter
{
private static final CacheStrategy cacheStrategy = new CacheStrategy();
/**
* Returns the VisAD scalar-name equivalent to a DODS name.
*
* @param name The DODS name.
* @return The VisAD scalar-name equivalent to the DODS
* name.
* @see ScalarType
*/
protected static String scalarName(String name)
{
return name
.replace('.', '-')
.replace(' ', '_')
.replace('(', '<')
.replace(')', '>');
}
/**
* Indicates if a given VisAD {@link MathType} is "flat" (i.e. comprises a
* {@link Real}, a {@link RealTuple}, or a {@link Tuple} of {@link Real}s
* and {@link RealTuple}s.
*
* @param mathType The VisAD mathtype to be investigated.
* @return <code>true</code> if and only if the given
* mathtype is "flat".
*/
protected static boolean isFlat(MathType mathType)
{
return
mathType instanceof RealType ||
mathType instanceof RealTupleType ||
(mathType instanceof TupleType && ((TupleType)mathType).getFlat());
}
/**
* Returns the VisAD {@link RealType} corresponding to a DODS variable.
*
* @param variable The DODS variable. Must be one for which a
* RealType is possible.
* @param das The DODS DAS in which the attribute
* table for the DODS variable is embedded.
* @return The VisAD RealType corresponding to the
* variable and attribute table.
*/
protected static RealType realType(BaseType variable, DAS das)
{
return realType(variable.getName(), attributeTable(das, variable));
}
/**
* Returns the VisAD {@link RealType} corresponding to a DODS variable.
*
* @param variable The DODS variable. Must be one for which a
* RealType is possible.
* @param table The DODS attribute table for the variable.
* May be <code>null</code>.
* @return The VisAD RealType corresponding to the
* variable and attribute table.
*/
protected static RealType realType(BaseType variable, AttributeTable table)
{
return realType(variable.getName(), table);
}
/**
* Returns the VisAD {@link RealType} corresponding to a name.
*
* @param name The name.
* @param das The DODS DAS in which the information on the
* name is embedded.
* @return The VisAD RealType corresponding to the
* name and metadata.
*/
protected static RealType realType(String name, DAS das)
{
return realType(name, attributeTable(das, name));
}
/**
* Returns the VisAD {@link RealType} corresponding to a name.
*
* @param name The name.
* @param table The DODS attribute table for the name.
* May be <code>null</code>.
* @return The VisAD RealType corresponding to the
* name and attribute table.
*/
protected static RealType realType(String name, AttributeTable table)
{
Unit unit;
if (table == null)
{
unit = null;
}
else
{
Attribute attr = table.getAttribute("units");
if (attr == null)
{
attr = table.getAttribute("unit");
if (attr == null)
{
attr = table.getAttribute("UNITS");
if (attr == null)
attr = table.getAttribute("UNIT");
}
}
if (attr == null)
{
unit = null;
}
else
{
if (attr.getType() != Attribute.STRING)
{
unit = null;
}
else
{
String unitSpec = attr.getValueAt(0);
/*
* Remove extraneous quotes.
*/
if (unitSpec.startsWith("\"") && unitSpec.endsWith("\""))
unitSpec = unitSpec.substring(1, unitSpec.length()-1);
try
{
unit = Parser.instance().parse(unitSpec);
}
catch (Exception e)
{
System.err.println(
"visad.data.dods.Adapter.realType(String,...): " +
"Ignoring non-decodable unit-specification \"" +
unitSpec + "\" of variable \"" + name + "\"");
unit = null;
}
}
}
}
return RealType.getRealType(scalarName(name), unit);
}
/**
* Returns the attribute table corresponding to a DODS variable.
*
* @param das The DODS DAS in which the attribute
* table for the DODS variable is embedded.
* @param baseType The type of the sub-component. May not be
* <code>null</code>.
* @return The attribute table corresponding to the
* variable. Will be <code>null</code> if no such
* table exists.
*/
protected static AttributeTable attributeTable(DAS das, BaseType baseType)
{
return das.getAttributeTable(baseType.getName());
}
/**
* Returns the attribute table corresponding to a name.
*
* @param das The DODS DAS in which information on the name
* is embedded.
* @param name The name to lookup in the DAS.
* @return The attribute table corresponding to the
* name. Will be <code>null</code> if no such
* table exists.
*/
protected static AttributeTable attributeTable(DAS das, String name)
{
return das.getAttributeTable(name);
}
/**
* Returns the VisAD {@link MathType} corresponding to an array of
* MathTypes.
*
* @param mathTypes The array of mathTypes.
* @return The MathType of the input aggregate. Will be
* <code>null</code> if the array has zero length.
* Will be the first element of a one-element
* array. Will be either a {@link RealTuple} or a
* {@link Tuple} -- as appropriate -- for a
* multi-element array.
* @throws VisADException VisAD failure.
*/
protected static MathType mathType(MathType[] mathTypes)
throws VisADException
{
MathType mathType;
if (mathTypes.length == 0)
{
mathType = null;
}
else if (mathTypes.length == 1)
{
mathType = mathTypes[0];
}
else
{
boolean allReals = true;
for (int i = 0; i < mathTypes.length && allReals; ++i)
allReals &= mathTypes[i] instanceof RealType;
if (allReals)
{
RealType[] realTypes = new RealType[mathTypes.length];
for (int i = 0; i < realTypes.length; ++i)
realTypes[i] = (RealType)mathTypes[i];
mathType = new RealTupleType(realTypes);
}
else
{
mathType = new TupleType(mathTypes);
}
}
return mathType;
}
/**
* Returns the {@link visad.data.FileFlatField} cacheing strategy for DODS
* adapters. This may be used by DODS adapters during the creation of
* FileFlatField-s.
*
* @return The FileFlatField cacheing strategy.
*/
protected CacheStrategy getCacheStrategy()
{
return cacheStrategy;
}
}