Runtime Loading
These are the various classes that can be plugged in at runtime:
Register an IOServiceProvider
1) The recommended way is to use the Service Provider
mechanism and include your IOSP in a JAR on the classpath, where it is dynamically loaded at runtime. In your
JAR, include a file named META-INF/services/ucar.nc2.iosp.IOServiceProvider
containing the
name(s) of your implementations, eg:
ucar.nc2.iosp.fysat.Fysatiosp
ucar.nc2.iosp.gini.Giniiosp
2) Alternatively, from your code, register your IOSP by calling:
ucar.nc2.NetcdfFiles.registerIOProvider(classNameAsString);
In both cases, your class must implement ucar.nc2.iosp.IOServiceProvider
.
When NetcdfFiles.open()
is called, we call getIosp()
and loop through the IOServiceProvider
classes calling isValidFile()
on each until one returns true
. This method is fast and accurate to insure efficient registration.
Register a CoordSystemBuilder:
From your code, register your CoordSystemBuilder
by calling:
ucar.nc2.internal.dataset.CoordSystemFactory.registerConvention(conventionNameAsString,
yourCoordSystemBuilderFactory);
The registered class must implement ucar.nc2.dataset.CoordSystemFactory
. The NetcdfDataset
is checked if it has a Convention
attribute, and if so,
it is matched by conventionName
. If not, loop through the CoordSystemFactory
classes and call findConventionByIsMine()
on each, until one returns true
.
If none are found, use the default _Coordinate
convention.
Register a TransformBuilder:
ucar.nc2.dataset.CoordTransBuilder.registerTransform(transformNameAsString, classNameAsString);
The registered class must implement ucar.nc2.internal.dataset.CoordTransformFactory
. The Coordinate Transform Variable
must have the transform name as one of its parameters.
Register a FeatureDatasetFactory:
ucar.nc2.ft.FeatureDatasetFactoryManager.registerFactory(featureType, classNameAsString);
The registered class must implement ucar.nc2.ft.FeatureDatasetFactory
.
Register a GRIB1 table:
ucar.nc2.grib.grib1.tables.Grib1ParamTables.addParameterTable(centerAsInt, subcenterAsInt,
tableVersionAsInt, yourFileNameAsString);
This registers a single table for the given center/subcenter/version. See GribTables for more information about parameter tables. Note: GRIB2 table handling is still being developed.
Register a GRIB1 lookup table:
ucar.nc2.grib.grib1.tables.Grib1ParamTables.addParameterTableLookup(yourLookupFileNameAsString);
This registers one or more tables for different center/subcenter/versions. See GribTables for more information about lookup tables. Note: GRIB2 table handling is still being developed.
Register a BUFR Table lookup:
ucar.nc2.iosp.bufr.tables.BufrTables.addLookupFile(yourLookupFileNameAsString);
The file must be a BUFR table lookup file.
Register a Filter
implementation:
Users-supplied filters must be provided using the Service Provider
mechanism and included in a JAR on the classpath, where it is dynamically loaded at runtime.
In your JAR, include a file named META-INF/services/ucar.nc2.filter.FilterProvider
containing the name(s) of your implementations, eg:
ucar.nc2.filter.BloscFilter
ucar.nc2.filter.GZipFilter
Your FilterProvider
classes must implement the ucar.nc2.filter.FilterProvider
interface.
See here for details on implementing user-supplied filters.
Runtime Configuration
Instead of calling the above routines in your code, you can pass the CDM library an XML configuration file.
Note that your application must call ucar.nc2.util.xml.RuntimeConfigParser.read()
.
The configuration file looks like this:
<?xml version='1.0' encoding='UTF-8'?>
<runtimeConfig>
1) <ioServiceProvider class='edu.univ.ny.stuff.FooFiles'/>
2) <coordSystemBuilderFactory convention='foo' class='test.Foo'/>
3) <coordTransformFactory name='atmos_ln_sigma_coordinates' type='vertical' class='my.stuff.atmosSigmaLog'/>
4) <featureDatasetFactory featureType='Point' class='gov.noaa.obscure.file.Flabulate'/>
5) <gribParameterTable edition='1' center='58' subcenter='-1' version='128'>C:/grib/tables/ons288.xml</gribParameterTable>
6) <gribParameterTableLookup edition='1'>C:/grib/tables/ncepLookup.txt</gribParameterTableLookup>
7) <bufrtable filename='C:/my/files/lookup.txt' />
8) <grib1Table strict='false'/>
9) <Netcdf4Clibrary>
<libraryPath>/usr/local/lib</libraryPath>
<libraryName>netcdf</libraryName>
<useForReading>false</useForReading>
</Netcdf4Clibrary>
</runtimeConfig>
- Loads an
IOServiceProvider
with the given class name - Loads a
CoordSysBuilderIF
with the given class name, which looks for the givenConvention
attribute value. - Loads a
CoordTransformFactory
with the given class name, which looks for the giventransformName
in the dataset. The type must be vertical or projection. - Loads a
FeatureDatasetFactory
with the given class name which openFeatureDatasets
of the givenfeatureType
. - Load a GRIB-1 parameter table (as of version 4.3)
- Load a GRIB-1 parameter table lookup (as of version 4.3)
- Load a BUFR table lookup file.
- Turn strict GRIB1 table handling off.
- Configure how the NetCDF-4 C library is discovered and used.
libraryPath
: The directory in which the native library is installed.libraryName
: The name of the native library. This will be used to locate the proper.DLL
,.SO
, or.DYLIB
file within thelibraryPath
directory.useForReading
: By default, the native library is only used for writing NetCDF-4 files; a pure-Java layer is responsible for reading them. However, if this property is set totrue
, then it will be used for reading NetCDF-4 (and HDF5) files as well.
There are several ways pass the Runtime Configuration XML to the CDM library. From your application, you can pass a java.io.InputStream
(or JDOM element) to
ucar.nc2.util.xml.RuntimeConfigParser
, as in the following examples:
// Example 1: read from file
StringBuilder errlog = new StringBuilder();
InputStream is = new FileInputStream(yourFileNameAsString);
ucar.nc2.util.xml.RuntimeConfigParser.read(is, errlog);
System.out.println(errlog);
// Example 2: read from resource
ClassLoader cl = yourScriptThis.getClassLoader();
InputStream is2 = cl.getResourceAsStream("resources/nj22/configFile.xml");
ucar.nc2.util.xml.RuntimeConfigParser.read(is, errlog);
// Example 3: extract JDOM element from a larger XML document:
Document doc;
SAXBuilder saxBuilder = new SAXBuilder();
saxBuilder.setExpandEntities(false);
try {
doc = saxBuilder.build(yourFileNameAsString);
} catch (JDOMException | IOException e) {
throw new IOException(e.getMessage());
}
Element root = doc.getRootElement();
Element elem = root.getChild("nj22Config");
if (elem != null)
ucar.nc2.util.xml.RuntimeConfigParser.read(elem, errlog);
For example, the ToolsUI application allows you to specify this file on the command line with the -nj22Config
parameter:
for (int i = 0; i < args.length; i++) {
if (args[i].equalsIgnoreCase("-nj22Config") && (i < args.length - 1)) {
String runtimeConfig = args[i + 1];
i++;
try {
StringBuilder errlog = new StringBuilder();
FileInputStream fis = new FileInputStream(runtimeConfig);
ucar.nc2.util.xml.RuntimeConfigParser.read(fis, errlog);
System.out.println(errlog);
} catch (IOException ioe) {
System.out.println("Error reading " + runtimeConfig + "=" + ioe.getMessage());
}
}
}
If none is specified on the command line, it will look for the XML document in $USER_HOME/.unidata/nj22Config.xml
.