/*
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 java.lang.reflect.*;
import java.io.IOException;
import java.net.*;
import java.rmi.RemoteException;
import visad.*;
import visad.data.*;
import visad.data.in.*;
/**
* Provides support for accessing the DODS form of data from VisAD.
*
* <P>Instances are mutable.</P>
*
* @author Steven R. Emmerson
*/
public class DODSForm
extends Form
implements FormFileInformer
{
/**
* The suffix in the path-component of a URL specification that identifies
* a dataset specification as being a DODS dataset specification. It
* doesn't have a leading period.
*/
public final static String SUFFIX = "dods";
private final static String periodSuffix = "." + SUFFIX;
private final static DODSForm instance = new DODSForm();
private final static String sourceMessage =
"DODS data-import capability is not available -- " +
"probably because the DODS package wasn't available when " +
"this package was compiled. If you want DODS data-import " +
"capability, then you'll have to first obtain the DODS " +
"package (see " +
"<http://www.unidata.ucar.edu/packages/dods/index.html>) and " +
"then recompile this package.";
private final static String contactMessage =
". This exception should not have occurred. Contact VisAD support.";
/**
* Constructs from nothing.
*/
protected DODSForm()
{
super("DODS");
}
/**
* Returns an instance of this class.
*
* @return An instance of this class.
*/
public static DODSForm dodsForm()
{
return instance;
}
/**
* Throws an exception.
*
* @param id An identifier.
* @param data A VisAD data object.
* @param replace Whether or not to replace an existing object.
* @throws UnimplementedException Always.
*/
public void save(String id, Data data, boolean replace)
throws BadFormException, IOException, RemoteException, VisADException
{
throw new UnimplementedException(
getClass().getName() + ".save(String,Data,boolean): " +
"Can't save data to a DODS server");
}
/**
* Throws an exception.
*
* @param id An identifier.
* @param data A VisAD data object.
* @param replace Whether or not to replace an existing object.
* @throws BadFormException Always.
*/
public void add(String id, Data data, boolean replace)
throws BadFormException
{
throw new BadFormException(
getClass().getName() + ".add(String,Data,boolean): " +
"Can't add data to a DODS server");
}
/**
* Opens an existing DODS dataset.
*
* @param id The URL for a DODS dataset. The path component
* should have a {@link #SUFFIX} suffix.
* @return The VisAD data object corresponding to the
* specified DODS dataset. Might be
* <code>null</code>.
* @throws BadFormException The DODS dataset is corrupt.
* @throws VisADException VisAD failure.
* @throws RemoteException Java RMI failure.
*/
public DataImpl open(String id)
throws BadFormException, IOException, VisADException
{
String header = getClass().getName() + ".open(String): ";
DataImpl data;
try
{
Class sourceClass =
Class.forName(
getClass().getPackage().getName() + ".DODSSource");
DataInputStream source = (DataInputStream)
sourceClass.getConstructor(new Class[0])
.newInstance(new Object[0]);
sourceClass.getMethod("open", new Class[] {String.class})
.invoke(source, new Object[] {id});
data = new Consolidator(new TimeFactorer(source)).readData();
}
catch (ClassNotFoundException e)
{
throw new VisADException(header + e + ". " + sourceMessage);
}
catch (NoSuchMethodException e)
{
throw new VisADException(header + e + contactMessage);
}
catch (SecurityException e)
{
throw new VisADException(header + e + contactMessage);
}
catch (InstantiationException e)
{
throw new VisADException(header + e + contactMessage);
}
catch (IllegalAccessException e)
{
throw new VisADException(header + e + contactMessage);
}
catch (IllegalArgumentException e)
{
throw new VisADException(header + e + contactMessage);
}
catch (InvocationTargetException e)
{
throw new VisADException(e.getTargetException().getMessage());
}
return data;
}
/**
* Opens an existing data object.
*
* @param url The URL for a DODS dataset. The path component
* should have a {@link #SUFFIX} suffix.
* @return The VisAD data object corresponding to the
* DODS dataset.
* @throws BadFormException The DODS dataset is corrupt.
* @throws VisADException VisAD failure.
* @throws RemoteException Java RMI failure.
*/
public DataImpl open(URL url)
throws BadFormException, VisADException, IOException
{
return open(url.toString());
}
/**
* Returns <code>null</code>.
*
* @param data A VisAD data object.
* @return <code>null</code>.
*/
public FormNode getForms(Data data)
{
return null; // can't save data to a DODS server
}
/*
* FormFileInformer method implementations:
*/
/**
* Indicates if a dataset specification is consistent with a DODS dataset
* specification.
*
* @param spec A dataset specification. NB: Not a URL.
* @return <code>true</code> if and only if the dataset
* specification is consistent with a DODS dataset
* specification.
*/
public boolean isThisType(String spec)
{
int i = spec.lastIndexOf('?');
if (i != -1)
spec = spec.substring(0, i);
return spec.toLowerCase().endsWith(periodSuffix);
}
/**
* Does nothing. Because the initial block of data in a DODS dataset can't
* be obtained from a DODS server, this routine does nothing and always
* returns false.
*
* @param block A block of data.
* @return <code>false</code> always.
*/
public boolean isThisType(byte[] block)
{
return false;
}
/**
* Returns the path-component suffixes that identifies a dataset
* specification as being a DODS dataset specification. The suffixes don't
* have a leading period. The returned array can be safely modified.
*
* @return A freshly-allocated array with the relevant
* suffixes.
*/
public String[] getDefaultSuffixes()
{
return new String[] {SUFFIX};
}
}