thredds.featurecollection.FeatureCollectionConfig Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 1998 - 2010. University Corporation for Atmospheric Research/Unidata
* Portions of this software were developed by the Unidata Program at the
* University Corporation for Atmospheric Research.
*
* Access and use of this software shall impose the following obligations
* and understandings on the user. The user is granted the right, without
* any fee or cost, to use, copy, modify, alter, enhance and distribute
* this software, and any derivative works thereof, and its supporting
* documentation for any purpose whatsoever, provided that this entire
* notice appears in all copies of the software, derivative works and
* supporting documentation. Further, UCAR requests that the user credit
* UCAR/Unidata in any publications that result from the use of this
* software or in any product that includes this software. The names UCAR
* and/or Unidata, however, may not be used in any advertising or publicity
* to endorse or promote any products or commercial entity unless specific
* written permission is obtained from UCAR/Unidata. The user also
* understands that UCAR/Unidata is not obligated to provide the user with
* any support, consulting, training or assistance of any kind with regard
* to the use, operation and performance of this software nor to provide
* the user with any updates, revisions, new versions or "bug fixes."
*
* THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package thredds.featurecollection;
import org.jdom2.Element;
import org.jdom2.Namespace;
import thredds.inventory.*;
import ucar.nc2.time.CalendarPeriod;
import ucar.unidata.util.StringUtil2;
import java.util.*;
/**
* FeatureCollection configuration
*
* @author caron
* @since Mar 30, 2010
*/
public class FeatureCollectionConfig {
// keys for storing AuxInfo objects
// static public final String AUX_GRIB_CONFIG = "gribConfig";
static public final String AUX_CONFIG = "fcConfig";
public enum ProtoChoice {
First, Random, Latest, Penultimate, Run
}
public enum FmrcDatasetType {
TwoD, Best, Files, Runs, ConstantForecasts, ConstantOffsets
}
public enum PointDatasetType {
cdmrFeature, Files
}
public enum GribDatasetType {
TwoD, Best, Analysis, Files, Latest, LatestFile
}
public enum PartitionType {
none, directory, file, timePeriod, all
}
static private org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(FeatureCollectionConfig.class);
//////////////////////////////////////////////
public String name, path, spec, collectionName, dateFormatMark, olderThan;
private String rootDir, regExp;
public FeatureCollectionType type;
public PartitionType ptype = PartitionType.directory;
public CalendarPeriod timePeriod;
public UpdateConfig tdmConfig = new UpdateConfig();
public UpdateConfig updateConfig = new UpdateConfig();
public ProtoConfig protoConfig = new ProtoConfig();
public FmrcConfig fmrcConfig = new FmrcConfig();
public PointConfig pointConfig = new PointConfig();
public GribConfig gribConfig = new GribConfig();
public Element innerNcml = null;
public Optional filesSortIncreasing = Optional.empty();
public FeatureCollectionConfig() {
}
public FeatureCollectionConfig(String name, String path, FeatureCollectionType fcType, String spec, String collectionName,
String dateFormatMark, String olderThan, String timePartition, Element innerNcml) {
this.name = name;
this.path = StringUtil2.trim(path, '/');
this.type = fcType;
this.spec = spec;
this.collectionName = collectionName == null ? name : collectionName;
this.dateFormatMark = dateFormatMark;
this.olderThan = olderThan;
if (null != timePartition) {
if (timePartition.equalsIgnoreCase("none")) ptype = PartitionType.none;
else if (timePartition.equalsIgnoreCase("directory")) ptype = PartitionType.directory;
else if (timePartition.equalsIgnoreCase("file")) ptype = PartitionType.file;
else if (timePartition.equalsIgnoreCase("all")) ptype = PartitionType.all;
else {
timePeriod = CalendarPeriod.of(timePartition);
ptype = PartitionType.timePeriod;
if (timePeriod == null)
throw new IllegalArgumentException("Illegal timePeriod= " + timePartition);
}
}
this.innerNcml = innerNcml;
}
public void setFilter(String rootDir, String regExp) {
this.rootDir = rootDir;
this.regExp = regExp;
}
public void setFilesSort(Element filesSortElem) {
if (filesSortElem == null) return;
String increasingS = filesSortElem.getAttributeValue("increasing");
if (increasingS != null) {
if (increasingS.equalsIgnoreCase("true"))
filesSortIncreasing = Optional.of(true);
else if (increasingS.equalsIgnoreCase("false"))
filesSortIncreasing = Optional.of(false);
}
}
public boolean getSortFilesAscending() {
if (filesSortIncreasing.isPresent()) return filesSortIncreasing.get();
if (gribConfig != null && gribConfig.filesSortIncreasing.isPresent()) return gribConfig.filesSortIncreasing.get();
return true; // default true
}
public CollectionSpecParser getCollectionSpecParser(Formatter errlog) {
if (rootDir != null)
return new CollectionSpecParser(rootDir, regExp, errlog);
else
return new CollectionSpecParser(spec, errlog);
}
public String getCollectionName() {
return collectionName;
}
public boolean isTrigggerOk() {
return updateConfig.triggerOk || (tdmConfig != null) && tdmConfig.triggerOk;
}
@Override
public String toString() {
Formatter f = new Formatter();
f.format("FeatureCollectionConfig name ='%s' collectionName='%s' type='%s'%n", name, collectionName, type);
f.format(" spec='%s'%n", spec);
if (rootDir != null)
f.format(" rootDir= '%s' regExp= '%s'%n", rootDir, regExp);
if (dateFormatMark != null)
f.format(" dateFormatMark ='%s'%n", dateFormatMark);
if (olderThan != null)
f.format(" olderThan =%s%n", olderThan);
f.format(" timePartition =%s%n", ptype);
if (updateConfig != null)
f.format(" updateConfig =%s%n", updateConfig);
if (tdmConfig != null)
f.format(" tdmConfig =%s%n", tdmConfig);
if (protoConfig != null)
f.format(" %s%n", protoConfig);
f.format(" hasInnerNcml =%s%n", innerNcml != null);
if (type != null) {
switch (type) {
case GRIB1:
case GRIB2:
f.format(" %s%n", gribConfig);
break;
case FMRC:
f.format(" fmrcConfig =%s%n", fmrcConfig);
break;
case Point:
case Station:
case Station_Profile:
f.format(" pointConfig =%s%n", pointConfig);
break;
}
}
return f.toString();
}
public void show(Formatter f) {
f.format("FeatureCollectionConfig name= '%s' collectionName= '%s' type= '%s'%n", name, collectionName, type);
f.format(" spec= '%s'%n", spec);
if (rootDir != null)
f.format(" rootDir= '%s' regExp= '%s'%n", rootDir, regExp);
if (dateFormatMark != null)
f.format(" dateFormatMark='%s'%n", dateFormatMark);
if (olderThan != null)
f.format(" olderThan= %s%n", olderThan);
if (ptype == PartitionType.timePeriod)
f.format(" timePartition= %s %n", timePeriod);
else
f.format(" timePartition= %s%n", ptype);
if (type != null) {
switch (type) {
case GRIB1:
case GRIB2:
gribConfig.show(f);
break;
case FMRC:
f.format(" fmrcConfig= %s%n", fmrcConfig);
break;
case Point:
case Station:
case Station_Profile:
f.format(" pointConfig= %s%n", pointConfig);
break;
}
}
}
// finished reading - do anything needed
public void finish() {
// if tdm element was not specified, default is test
if (!tdmConfig.userDefined) tdmConfig.updateType = CollectionUpdateType.test;
// if update element was not specified, set default
if (!updateConfig.userDefined) {
// if tdm working, default tds is never, otherwise nocheck
updateConfig.updateType = tdmConfig.userDefined ? CollectionUpdateType.never : CollectionUpdateType.nocheck;
}
// startupType allows override on tdm command line
updateConfig.startupType = updateConfig.updateType;
tdmConfig.startupType = tdmConfig.updateType;
}
public DateExtractor getDateExtractor() {
if (dateFormatMark != null)
return new DateExtractorFromName(dateFormatMark, false);
else {
CollectionSpecParser sp = getCollectionSpecParser(null);
if (sp.getDateFormatMark() != null)
return new DateExtractorFromName(sp.getDateFormatMark(), true);
}
return new DateExtractorNone();
}
//
static public class UpdateConfig {
public String recheckAfter; // used by non-GRIB FC
public String rescan;
public boolean triggerOk = true;
public boolean userDefined = false;
public CollectionUpdateType startupType = CollectionUpdateType.never; // same as updateType, except may be overridden on the command line, for startup only
public CollectionUpdateType updateType = CollectionUpdateType.never; // this is what the user entered in config
public String deleteAfter = null; // not implemented yet
public UpdateConfig() { // defaults
}
public UpdateConfig(String startupS, String rewriteS, String recheckAfter, String rescan, String triggerS, String deleteAfter) {
this.rescan = rescan; // may be null
if (recheckAfter != null) this.recheckAfter = recheckAfter; // in case it was set in collection element
if (rescan != null) this.recheckAfter = null; // both not allowed
this.deleteAfter = deleteAfter; // may be null
if (triggerS != null)
this.triggerOk = triggerS.equalsIgnoreCase("allow");
// rewrite superceeds startup
if (rewriteS == null) rewriteS = startupS;
if (rewriteS != null) {
rewriteS = rewriteS.toLowerCase();
if (rewriteS.equalsIgnoreCase("true"))
this.updateType = CollectionUpdateType.test;
else try {
this.updateType = CollectionUpdateType.valueOf(rewriteS);
} catch (Throwable t) {
log.error("Bad updateType= {} in {}", rewriteS);
}
// user has placed an update/tdm element in the catalog
userDefined = true;
}
}
@Override
public String toString() {
return "UpdateConfig{" +
"userDefined=" + userDefined +
", recheckAfter='" + recheckAfter + '\'' +
", rescan='" + rescan + '\'' +
", triggerOk=" + triggerOk +
", updateType=" + updateType +
'}';
}
}
//
static public class ProtoConfig {
public ProtoChoice choice = ProtoChoice.Penultimate;
public String param = null;
public String change = null;
public Element outerNcml = null;
public boolean cacheAll = true;
public ProtoConfig() { // defaults
}
public ProtoConfig(String choice, String change, String param, Element ncml) {
if (choice != null) {
try {
this.choice = ProtoChoice.valueOf(choice);
} catch (Exception e) {
log.warn("Dont recognize ProtoChoice " + choice);
}
}
this.change = change;
this.param = param;
this.outerNcml = ncml;
}
@Override
public String toString() {
return "ProtoConfig{" +
"choice=" + choice +
", change='" + change + '\'' +
", param='" + param + '\'' +
", outerNcml='" + outerNcml + '\'' +
", cacheAll=" + cacheAll +
'}';
}
}
////////////////////////////////////////////////
//
public static void setRegularizeDefault(boolean t) {
regularizeDefault = t;
}
// public static boolean getRegularizeDefault() {
// return regularizeDefault;
//}
static private boolean regularizeDefault = false;
static private Set defaultFmrcDatasetTypes =
Collections.unmodifiableSet(EnumSet.of(FmrcDatasetType.TwoD, FmrcDatasetType.Best, FmrcDatasetType.Files, FmrcDatasetType.Runs));
static public class FmrcConfig {
public boolean regularize = regularizeDefault;
public Set datasets = defaultFmrcDatasetTypes;
private boolean explicit = false;
private List bestDatasets = null;
public FmrcConfig() { // defaults
}
public FmrcConfig(String regularize) {
this.regularize = (regularize != null) && (regularize.equalsIgnoreCase("true"));
}
public void addDatasetType(String datasetTypes) {
// if they list datasetType explicitly, remove defaults
if (!explicit) datasets = EnumSet.noneOf(FmrcDatasetType.class);
explicit = true;
String[] types = StringUtil2.splitString(datasetTypes);
for (String type : types) {
try {
FmrcDatasetType fdt = FmrcDatasetType.valueOf(type);
datasets.add(fdt);
} catch (Exception e) {
log.warn("Dont recognize FmrcDatasetType " + type);
}
}
}
public void addBestDataset(String name, double greaterEqual) {
if (bestDatasets == null) bestDatasets = new ArrayList<>(2);
bestDatasets.add(new BestDataset(name, greaterEqual));
}
public List getBestDatasets() {
return bestDatasets;
}
@Override
public String toString() {
Formatter f = new Formatter();
f.format("FmrcConfig: regularize=%s datasetTypes=%s", regularize, datasets);
if (bestDatasets != null)
for (BestDataset bd : bestDatasets)
f.format("best = (%s, %f) ", bd.name, bd.greaterThan);
return f.toString();
}
}
static public class BestDataset {
public String name;
public double greaterThan;
public BestDataset(String name, double greaterThan) {
this.name = name;
this.greaterThan = greaterThan;
}
}
static private Set defaultPointDatasetTypes =
Collections.unmodifiableSet(EnumSet.of(PointDatasetType.cdmrFeature, PointDatasetType.Files));
static public class PointConfig {
public Set datasets = defaultPointDatasetTypes;
protected boolean explicit = false;
public PointConfig() { // defaults
}
public void addDatasetType(String datasetTypes) {
// if they list datasetType explicitly, remove defaults
if (!explicit) datasets = EnumSet.noneOf(PointDatasetType.class);
explicit = true;
String[] types = StringUtil2.splitString(datasetTypes);
for (String type : types) {
try {
PointDatasetType fdt = PointDatasetType.valueOf(type);
datasets.add(fdt);
} catch (Exception e) {
log.warn("Dont recognize PointDatasetType " + type);
}
}
}
@Override
public String toString() {
Formatter f = new Formatter();
f.format("PointConfig: datasetTypes=%s", datasets);
return f.toString();
}
}
// GribConfig
static private final Set defaultGribDatasetTypes =
Collections.unmodifiableSet(EnumSet.of(GribDatasetType.TwoD, GribDatasetType.Best, GribDatasetType.Files, GribDatasetType.Latest));
static public boolean useGenTypeDef = false, useTableVersionDef = false, intvMergeDef = true, useCenterDef = false;
static public class GribConfig {
public Map gdsHash; // map one gds hash to another
public Map gdsNamer; // hash, group name
public boolean useGenType = useGenTypeDef;
public boolean useTableVersion = useTableVersionDef;
public boolean intvMerge = intvMergeDef;
public boolean useCenter = useCenterDef;
public boolean unionRuntimeCoord;
public GribIntvFilter intvFilter;
public TimeUnitConverterHash tuc;
public CalendarPeriod userTimeUnit;
// late binding
public String latestNamer, bestNamer;
private Optional filesSortIncreasing = Optional.empty();
public Set datasets = defaultGribDatasetTypes;
public String lookupTablePath, paramTablePath; // user defined tables
public Element paramTable; // ??
private boolean explicitDatasets = false;
public GribConfig() { // defaults
}
public TimeUnitConverter getTimeUnitConverter() {
return tuc;
}
public void configFromXml(Element configElem, Namespace ns) {
String datasetTypes = configElem.getAttributeValue("datasetTypes");
if (null != datasetTypes)
addDatasetType(datasetTypes);
List gdsElems = configElem.getChildren("gdsHash", ns);
for (Element gds : gdsElems)
addGdsHash(gds.getAttributeValue("from"), gds.getAttributeValue("to"));
List tuElems = configElem.getChildren("timeUnitConvert", ns);
for (Element tu : tuElems)
addTimeUnitConvert(tu.getAttributeValue("from"), tu.getAttributeValue("to"));
gdsElems = configElem.getChildren("gdsName", ns);
for (Element gds : gdsElems)
addGdsName(gds.getAttributeValue("hash"), gds.getAttributeValue("groupName"));
if (configElem.getChild("parameterMap", ns) != null)
paramTable = configElem.getChild("parameterMap", ns);
if (configElem.getChild("gribParameterTable", ns) != null)
paramTablePath = configElem.getChildText("gribParameterTable", ns);
if (configElem.getChild("gribParameterTableLookup", ns) != null)
lookupTablePath = configElem.getChildText("gribParameterTableLookup", ns);
if (configElem.getChild("latestNamer", ns) != null)
latestNamer = configElem.getChild("latestNamer", ns).getAttributeValue("name");
if (configElem.getChild("bestNamer", ns) != null)
bestNamer = configElem.getChild("bestNamer", ns).getAttributeValue("name");
// old way - filesSort element inside the gribConfig element
Element filesSortElem = configElem.getChild("filesSort", ns);
if (filesSortElem != null) {
//String orderByS = filesSortElem.getAttributeValue("orderBy"); // filename vs date ??
String increasingS = filesSortElem.getAttributeValue("increasing");
if (increasingS != null) {
if (increasingS.equalsIgnoreCase("true"))
filesSortIncreasing = Optional.of(true);
else if (increasingS.equalsIgnoreCase("false"))
filesSortIncreasing = Optional.of(false);
} else { // older way
Element lexigraphicByName = filesSortElem.getChild("lexigraphicByName", ns);
if (lexigraphicByName != null) {
increasingS = lexigraphicByName.getAttributeValue("increasing");
if (increasingS != null) {
if (increasingS.equalsIgnoreCase("true"))
filesSortIncreasing = Optional.of(true);
else if (increasingS.equalsIgnoreCase("false"))
filesSortIncreasing = Optional.of(false);
}
}
}
}
List intvElems = configElem.getChildren("intvFilter", ns);
for (Element intvElem : intvElems) {
if (intvFilter == null) intvFilter = new GribIntvFilter();
String excludeZero = intvElem.getAttributeValue("excludeZero");
if (excludeZero != null) setExcludeZero(!excludeZero.equals("false"));
String intervalS = intvElem.getAttributeValue("interval");
if (intervalS != null) intvFilter.addInterval(intervalS);
String intvLengthS = intvElem.getAttributeValue("intvLength");
if (intvLengthS != null) {
int intvLength = Integer.parseInt(intvLengthS);
List varElems = intvElem.getChildren("variable", ns);
for (Element varElem : varElems)
intvFilter.addVariable(intvLength, varElem.getAttributeValue("id"), varElem.getAttributeValue("prob"));
}
}
List paramElems = configElem.getChildren("option", ns);
if (paramElems.size() == 0)
paramElems = configElem.getChildren("parameter", ns); // backwards compatible
for (Element param : paramElems) {
String name = param.getAttributeValue("name");
String value = param.getAttributeValue("value");
if (name != null && value != null) {
setOption(name, value);
}
}
Element pdsHashElement = configElem.getChild("pdsHash", ns);
useGenType = readValue(pdsHashElement, "useGenType", ns, useGenTypeDef);
useTableVersion = readValue(pdsHashElement, "useTableVersion", ns, useTableVersionDef);
intvMerge = readValue(pdsHashElement, "intvMerge", ns, intvMergeDef);
useCenter = readValue(pdsHashElement, "useCenter", ns, useCenterDef);
}
public boolean setOption(String name, String value) {
if (name == null || value == null) return false;
if (name.equalsIgnoreCase("timeUnit")) {
setUserTimeUnit(value); // eg "10 min" or "minute"
return true;
}
if (name.equalsIgnoreCase("runtimeCoordinate") && value.equalsIgnoreCase("union")) {
unionRuntimeCoord = true;
return true;
}
return false;
}
public void setUserTimeUnit(String value) {
if (value != null)
userTimeUnit = CalendarPeriod.of(value); // eg "10 min" or "minute
}
public void setExcludeZero(boolean val) {
if (intvFilter == null) intvFilter = new GribIntvFilter();
intvFilter.isZeroExcluded = val;
}
public void setUseTableVersion(boolean val) {
useTableVersion = val;
}
public void setIntervalLength(int intvLength, String varId) {
if (intvFilter == null) intvFilter = new GribIntvFilter();
intvFilter.addVariable(intvLength, varId, null);
}
private boolean readValue(Element pdsHashElement, String key, Namespace ns, boolean value) {
if (pdsHashElement != null) {
Element e = pdsHashElement.getChild(key, ns);
if (e != null) {
value = true; // no value means true
String t = e.getTextNormalize();
if (t != null && t.equalsIgnoreCase("true")) value = true;
if (t != null && t.equalsIgnoreCase("false")) value = false;
}
}
return value;
}
public void addDatasetType(String datasetTypes) {
// if they list datasetType explicitly, remove defaults
if (!explicitDatasets) datasets = EnumSet.noneOf(GribDatasetType.class);
explicitDatasets = true;
String[] types = StringUtil2.splitString(datasetTypes);
for (String type : types) {
try {
GribDatasetType fdt = GribDatasetType.valueOf(type);
if (fdt == GribDatasetType.LatestFile) fdt = GribDatasetType.Latest;
datasets.add(fdt);
} catch (Exception e) {
log.warn("Dont recognize GribDatasetType {}", type);
}
}
}
public boolean hasDatasetType(GribDatasetType type) {
return datasets.contains(type);
}
public void addGdsHash(String fromS, String toS) {
if (fromS == null || toS == null) return;
if (gdsHash == null) gdsHash = new HashMap<>(10);
try {
int from = Integer.parseInt(fromS);
int to = Integer.parseInt(toS);
gdsHash.put(from, to);
} catch (Exception e) {
log.warn("Failed to parse as Integer = {} {}", fromS, toS);
}
}
public void addTimeUnitConvert(String fromS, String toS) {
if (fromS == null || toS == null) return;
if (tuc == null) tuc = new TimeUnitConverterHash();
try {
int from = Integer.parseInt(fromS);
int to = Integer.parseInt(toS);
tuc.map.put(from, to);
} catch (Exception e) {
log.warn("Failed to parse as Integer = {} {}", fromS, toS);
}
}
public void addGdsName(String hashS, String name) {
if (hashS == null || name == null) return;
if (gdsNamer == null) gdsNamer = new HashMap<>(5);
try {
int hash = Integer.parseInt(hashS);
gdsNamer.put(hash, name);
} catch (Exception e) {
log.warn("Failed to parse as Integer = {} {}", hashS, name);
}
}
public void show(Formatter f) {
f.format("GribConfig= ");
if (useGenType != useGenTypeDef) f.format(" useGenType=%s", useGenType);
if (useTableVersion != useTableVersionDef) f.format(" useTableVersion=%s", useTableVersion);
if (intvMerge != intvMergeDef) f.format(" intvMerge=%s", intvMerge);
if (useCenter != useCenterDef) f.format(" useCenter=%s", useCenter);
if (userTimeUnit != null) f.format(" userTimeUnit= %s", userTimeUnit);
f.format("%n");
if (gdsHash != null) f.format(" gdsHash=%s%n", gdsHash);
if (gdsNamer != null) f.format(" gdsNamer=%s%n", gdsNamer);
if (intvFilter != null) f.format(" intvFilter=%s%n", intvFilter);
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("GribConfig{");
sb.append("datasets=").append(datasets);
if (gdsHash != null) sb.append(", gdsHash=").append(gdsHash);
if (gdsNamer != null) sb.append(", gdsNamer=").append(gdsNamer);
sb.append(", useGenType=").append(useGenType);
sb.append(", useTableVersion=").append(useTableVersion);
sb.append(", intvMerge=").append(intvMerge);
sb.append(", useCenter=").append(useCenter);
if (lookupTablePath != null) sb.append(", lookupTablePath='").append(lookupTablePath).append('\'');
if (paramTablePath != null) sb.append(", paramTablePath='").append(paramTablePath).append('\'');
if (latestNamer != null) sb.append(", latestNamer='").append(latestNamer).append('\'');
if (bestNamer != null) sb.append(", bestNamer='").append(bestNamer).append('\'');
if (paramTable != null) sb.append(", paramTable=").append(paramTable);
if (filesSortIncreasing != null) sb.append(", filesSortIncreasing=").append(filesSortIncreasing);
if (intvFilter != null) sb.append(", intvFilter=").append(intvFilter);
if (userTimeUnit != null) sb.append(", userTimeUnit='").append(userTimeUnit).append('\'');
sb.append('}');
return sb.toString();
}
public Object getIospMessage() {
if (lookupTablePath != null) return "gribParameterTableLookup=" + lookupTablePath;
if (paramTablePath != null) return "gribParameterTable=" + paramTablePath;
return null;
}
public int convertGdsHash(int hashcode) {
if (gdsHash == null) return hashcode;
Integer convertedValue = gdsHash.get(hashcode);
if (convertedValue == null) return hashcode;
return convertedValue;
}
} // GribConfig
//////////////////////////////////////////////////////////////////////////
interface IntvFilter {
// true means discard
boolean filter(int id, int intvStart, int intvEnd, int prob);
}
static class IntvLengthFilter implements IntvFilter {
public final int id;
public final int intvLength;
public final int prob; // none = Integer.MIN_VALUE;
public IntvLengthFilter(int id, int intvLength, int prob) {
this.id = id;
this.intvLength = intvLength;
this.prob = prob;
}
public boolean filter(int id, int intvStart, int intvEnd, int prob) {
int intvLength = intvEnd - intvStart;
boolean needProb = (this.prob != Integer.MIN_VALUE); // filter uses prob
boolean hasProb = (prob != Integer.MIN_VALUE); // record has prob
boolean isMine = !needProb || hasProb && (this.prob == prob);
if (this.id == id && isMine) { // first match in the filter list is used
if (this.intvLength != intvLength)
return true; // remove the ones whose intervals dont match
}
return false;
}
}
static class IntervalFilter implements IntvFilter {
public final int start, end;
public IntervalFilter(int start, int end) {
this.start = start;
this.end = end;
}
public boolean filter(int id, int intvStart, int intvEnd, int prob) {
boolean match = (this.start == intvStart) && (this.end == intvEnd); // remove ones that match
if (match) {
log.info("interval filter applied id="+id);
}
return match;
}
}
static public class GribIntvFilter {
public List filterList = new ArrayList<>();
public boolean isZeroExcluded = true; // default is true 3/2/2015
public boolean isZeroExcluded() {
return isZeroExcluded;
}
public boolean hasFilter() {
return (filterList.size() > 0);
}
// true means discard
public boolean filter(int id, int intvStart, int intvEnd, int prob) {
int intvLength = intvEnd - intvStart;
if (intvLength == 0 && isZeroExcluded()) return true;
for (IntvFilter filter : filterList) {
if (filter.filter(id, intvStart, intvEnd, prob)) return true;
}
return false;
}
//
void addInterval(String intervalS) {
if (intervalS == null) {
log.warn("Error on interval attribute: must not be empty");
return;
}
String[] s = intervalS.split(",");
if (s.length != 2) {
log.warn("Error on interval attribute: must be of form 'start,end'");
return;
}
try {
int start = Integer.parseInt(s[0]);
int end = Integer.parseInt(s[1]);
filterList.add(new IntervalFilter(start, end));
} catch (NumberFormatException e) {
log.info("Error on intvFilter element - attribute must be an integer");
}
}
/*
*/
void addVariable(int intvLength, String idS, String probS) {
if (idS == null) {
log.warn("Error on intvFilter: must have an id attribute");
return;
}
String[] s = idS.split("-");
if (s.length != 3 && s.length != 4) {
log.warn("Error on intvFilter: id attribute must be of form 'discipline-category-number' (GRIB2) or 'center-subcenter-version-param' (GRIB1)");
return;
}
try {
int id;
if (s.length == 3) { // GRIB2
int discipline = Integer.parseInt(s[0]);
int category = Integer.parseInt(s[1]);
int number = Integer.parseInt(s[2]);
id = (discipline << 16) + (category << 8) + number;
} else { // GRIB1
int center = Integer.parseInt(s[0]);
int subcenter = Integer.parseInt(s[1]);
int version = Integer.parseInt(s[2]);
int param = Integer.parseInt(s[3]);
id = (center << 8) + (subcenter << 16) + (version << 24) + param;
}
int prob = (probS == null) ? Integer.MIN_VALUE : Integer.parseInt(probS);
filterList.add(new IntvLengthFilter(id, intvLength, prob));
} catch (NumberFormatException e) {
log.info("Error on intvFilter element - attribute must be an integer");
}
}
}
public static class TimeUnitConverterHash implements TimeUnitConverter {
public Map map = new HashMap<>(5);
public int convertTimeUnit(int timeUnit) {
if (map == null) return timeUnit;
Integer convert = map.get(timeUnit);
return (convert == null) ? timeUnit : convert;
}
}
}