diff --git a/bufr/src/main/java/ucar/nc2/iosp/bufr/Construct2.java b/bufr/src/main/java/ucar/nc2/iosp/bufr/Construct2.java index 3932a6fbe5..cb768431d0 100644 --- a/bufr/src/main/java/ucar/nc2/iosp/bufr/Construct2.java +++ b/bufr/src/main/java/ucar/nc2/iosp/bufr/Construct2.java @@ -299,7 +299,7 @@ else if (nbytes == 4) Group g = struct.getParentGroupOrRoot(); if (g == null) log.warn("Struct parent group is null."); - EnumTypedef enumTypedef = g.findEnumeration(ct.getName()); + EnumTypedef enumTypedef = g.findEnumeration(ct.getName(), false); if (enumTypedef == null) { enumTypedef = new EnumTypedef(ct.getName(), ct.getMap()); g.addEnumeration(enumTypedef); diff --git a/cdm/core/src/main/java/ucar/nc2/Attribute.java b/cdm/core/src/main/java/ucar/nc2/Attribute.java index b8dca41f7a..b8ab59955d 100644 --- a/cdm/core/src/main/java/ucar/nc2/Attribute.java +++ b/cdm/core/src/main/java/ucar/nc2/Attribute.java @@ -38,7 +38,7 @@ public class Attribute extends CDMNode { /** @deprecated move to jni.Nc4Iosp */ @Deprecated - static final String[] SPECIALS = + static public final String[] SPECIALS = {CDM.NCPROPERTIES, CDM.ISNETCDF4, CDM.SUPERBLOCKVERSION, CDM.DAP4_LITTLE_ENDIAN, CDM.EDU_UCAR_PREFIX}; /** diff --git a/cdm/core/src/main/java/ucar/nc2/Group.java b/cdm/core/src/main/java/ucar/nc2/Group.java index e73edd8277..8ebb113285 100755 --- a/cdm/core/src/main/java/ucar/nc2/Group.java +++ b/cdm/core/src/main/java/ucar/nc2/Group.java @@ -2,8 +2,10 @@ * Copyright (c) 1998-2018 University Corporation for Atmospheric Research/Unidata * See LICENSE for license information. */ + package ucar.nc2; +import static java.util.Optional.ofNullable; import static ucar.nc2.NetcdfFiles.reservedFullName; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; @@ -295,7 +297,7 @@ public Dimension findDimensionLocal(String shortName) { /** The attributes contained by this Group. */ public AttributeContainer attributes() { - return attributes; + return AttributeContainer.filter(attributes, Attribute.SPECIALS); } /** Find the attribute by name, return null if not exist */ @@ -374,20 +376,29 @@ public boolean removeAttributeIgnoreCase(String attName) { //////////////////////////////////////////////////////////////////////// - /** Find a Enumeration in this or a parent Group, using its short name. */ + /** Find a Enumeration in this Group, using its short name. */ @Nullable public EnumTypedef findEnumeration(String name) { + // Keep the old behavior + return findEnumeration(name, false); + } + + /** Find a Enumeration in this or optionally the parent Groups, using its short name. */ + @Nullable + public EnumTypedef findEnumeration(String name, boolean searchup) { if (name == null) return null; // name = NetcdfFile.makeNameUnescaped(name); - for (EnumTypedef d : enumTypedefs) { + // search this group's EnumTypedefs + for (EnumTypedef d : this.getEnumTypedefs()) { if (name.equals(d.getShortName())) return d; } - Group parent = getParentGroup(); - if (parent != null) - return parent.findEnumeration(name); - + if (searchup) { + Group parent = getParentGroup(); + if (parent != null) + return parent.findEnumeration(name, searchup); + } return null; } @@ -1114,6 +1125,52 @@ public Group.Builder commonParent(Group.Builder other) { return other; } + public Optional findSimilarEnumTypedef(EnumTypedef template, boolean searchup, boolean anyname) { + Optional ed = Optional.empty(); + assert (template != null); + // search this group builders's EnumTypedefs but with constraint on name + ed = this.enumTypedefs.stream() + .filter(e -> (anyname || !template.getShortName().equals(e.getShortName())) && e.equalsMapOnly(template)) + .findFirst(); + if (ed.isPresent()) + return ed; + // Optionally search parents + if (searchup) { + Group.Builder gb = getParentGroup(); + if (gb != null) + ed = gb.findSimilarEnumTypedef(template, searchup, anyname); + if (ed.isPresent()) + return ed; + } + return Optional.empty(); + } + + /** Find a Enumeration in this Group Builder, using its short name. */ + public Optional findEnumTypedef(String name) { + // Keep the old behavior + return findEnumTypedef(name, false); + } + + /** Find a Enumeration in this or a parent Group Builder, using its short name. */ + public Optional findEnumTypedef(String name, boolean searchup) { + if (name == null) + return Optional.empty(); + // name = NetcdfFile.makeNameUnescaped(name); + // search this group builders's EnumTypedefs + Optional ed = this.enumTypedefs.stream().filter(e -> e.shortName.equals(name)).findFirst(); + if (ed.isPresent()) + return ed; + // Optionally search parents + if (searchup) { + Group.Builder gb = getParentGroup(); + if (gb != null) + ed = gb.findEnumTypedef(name, searchup); + if (ed.isPresent()) + return ed; + } + return Optional.empty(); + } + public Builder addEnumTypedef(EnumTypedef typedef) { Preconditions.checkNotNull(typedef); enumTypedefs.add(typedef); @@ -1131,7 +1188,7 @@ public Builder addEnumTypedefs(Collection typedefs) { * Return new or existing. */ public EnumTypedef findOrAddEnumTypedef(String name, Map map) { - Optional opt = findEnumTypedef(name); + Optional opt = findEnumTypedef(name, false); // Find in this group if (opt.isPresent()) { return opt.get(); } else { @@ -1141,10 +1198,6 @@ public EnumTypedef findOrAddEnumTypedef(String name, Map map) { } } - public Optional findEnumTypedef(String name) { - return this.enumTypedefs.stream().filter(e -> e.shortName.equals(name)).findFirst(); - } - /** Add a Variable, throw error if one of the same name if it exists. */ public Builder addVariable(Variable.Builder variable) { Preconditions.checkNotNull(variable); diff --git a/cdm/core/src/main/java/ucar/nc2/NetcdfFile.java b/cdm/core/src/main/java/ucar/nc2/NetcdfFile.java index 9c7f7e3dfb..645328cff4 100644 --- a/cdm/core/src/main/java/ucar/nc2/NetcdfFile.java +++ b/cdm/core/src/main/java/ucar/nc2/NetcdfFile.java @@ -41,12 +41,12 @@ import ucar.ma2.InvalidRangeException; import ucar.ma2.Section; import ucar.ma2.StructureDataIterator; +import ucar.nc2.internal.iosp.hdf5.H5iospNew; import ucar.nc2.internal.iosp.netcdf3.N3headerNew; import ucar.nc2.iosp.AbstractIOServiceProvider; import ucar.nc2.iosp.IOServiceProvider; import ucar.nc2.iosp.IospHelper; import ucar.nc2.iosp.hdf5.H5header; -import ucar.nc2.iosp.hdf5.H5iosp; import ucar.nc2.iosp.netcdf3.N3header; import ucar.nc2.iosp.netcdf3.N3iosp; import ucar.nc2.iosp.netcdf3.SPFactory; @@ -830,7 +830,7 @@ private static IOServiceProvider getIosp(RandomAccessFile raf) throws IOExceptio return SPFactory.getServiceProvider(); } else if (H5header.isValidFile(raf)) { - return new H5iosp(); + return new H5iospNew(); } else { diff --git a/cdm/core/src/main/java/ucar/nc2/Variable.java b/cdm/core/src/main/java/ucar/nc2/Variable.java index 19d6b98060..a94219af21 100644 --- a/cdm/core/src/main/java/ucar/nc2/Variable.java +++ b/cdm/core/src/main/java/ucar/nc2/Variable.java @@ -1830,7 +1830,7 @@ protected Variable(Builder builder, Group parentGroup) { this.cache = builder.cache; if (this.dataType.isEnum()) { - this.enumTypedef = this.group.findEnumeration(builder.enumTypeName); + this.enumTypedef = this.group.findEnumeration(builder.enumTypeName, true); if (this.enumTypedef == null) { throw new IllegalStateException( String.format("EnumTypedef '%s' does not exist in a parent Group", builder.enumTypeName)); diff --git a/cdm/core/src/main/java/ucar/nc2/internal/iosp/hdf5/H5headerNew.java b/cdm/core/src/main/java/ucar/nc2/internal/iosp/hdf5/H5headerNew.java index 765721f8f1..faa7fb8fa6 100644 --- a/cdm/core/src/main/java/ucar/nc2/internal/iosp/hdf5/H5headerNew.java +++ b/cdm/core/src/main/java/ucar/nc2/internal/iosp/hdf5/H5headerNew.java @@ -17,13 +17,8 @@ import java.nio.ShortBuffer; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Formatter; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.TimeZone; +import java.util.*; + import ucar.ma2.Array; import ucar.ma2.ArrayChar; import ucar.ma2.ArrayObject; @@ -44,7 +39,6 @@ import ucar.nc2.Structure; import ucar.nc2.Variable; import ucar.nc2.constants.CDM; -import ucar.nc2.filter.Filter; import ucar.nc2.internal.iosp.hdf4.HdfEos; import ucar.nc2.internal.iosp.hdf4.HdfHeaderIF; import ucar.nc2.internal.iosp.hdf5.H5objects.DataObject; @@ -498,7 +492,7 @@ private boolean makeNetcdfGroup(Group.Builder parentGroup, H5Group h5group) thro } if (facadeNested.dobj.mdt.map != null) { - EnumTypedef enumTypedef = parentGroup.findEnumTypedef(facadeNested.name).orElse(null); + EnumTypedef enumTypedef = parentGroup.findEnumTypedef(facadeNested.name, true).orElse(null); if (enumTypedef == null) { DataType basetype; switch (facadeNested.dobj.mdt.byteSize) { @@ -554,7 +548,7 @@ private boolean makeNetcdfGroup(Group.Builder parentGroup, H5Group h5group) thro } // This code apparently addresses the possibility of an anonymous enum LOOK ?? if (enumTypeName.isEmpty()) { - EnumTypedef enumTypedef = parentGroup.findEnumTypedef(facadeNested.name).orElse(null); + EnumTypedef enumTypedef = parentGroup.findEnumTypedef(facadeNested.name, true).get(); if (enumTypedef == null) { enumTypedef = new EnumTypedef(facadeNested.name, facadeNested.dobj.mdt.map); parentGroup.addEnumTypedef(enumTypedef); @@ -1553,14 +1547,51 @@ private boolean makeVariableShapeAndType(Group.Builder parent, Variable.Builder // set the enumTypedef if (dt.isEnum()) { - // TODO Not sure why, but there may be both a user type and a "local" mdt enum. May need to do a value match? - EnumTypedef enumTypedef = parent.findEnumTypedef(mdt.enumTypeName).orElse(null); - if (enumTypedef == null) { // if shared object, wont have a name, shared version gets added later - EnumTypedef local = new EnumTypedef(mdt.enumTypeName, mdt.map); - enumTypedef = parent.enumTypedefs.stream().filter((e) -> e.equalsMapOnly(local)).findFirst().orElse(local); - parent.addEnumTypedef(enumTypedef); - } - v.setEnumTypeName(enumTypedef.getShortName()); + // dmh: HDF5, at least as used by netcdf-4, defines an enumeration type multiple times. + // One is when the enum type is defined, and then for every variable or field typed by that + // enum type, another enum type is created but with the name of the variable/field instead of + // the name of the actual type. This appears to be because H5header(New) does not pass + // down enough information for the HDF5->CDM translator to recognize the second case. + // The solution provided is to see if the following conditions hold when an enum typed + // variable is encountered: + // 1. The enum name is the same as the variable name. + // 2. There is no enum of that name in the current group. + // 3. There is another enum type in some containing group + // that is structurally identical to the EnumTypedef -- but with a + // different name -- associated with the variable. This is in contrast + // to testing for name equality. + // + // If all three conditions are true, then use the enum found + // in condition 3 as the enum type for the variable. + // Note that provision is made only for a shortname rather than a + // fully qualified name, which is incorrect, but too hard to change. + // + // If condition 1 if false, then it is ok to create a new EnumTypedef. + // Else if condition 2 is false then it is an error because the existence + // of such an enum is illegal netcdf-4 because duplicate name. + // Else if condition 3 is false, then it is an error because the + // variable's enum type is not defined. + + EnumTypedef actualEnumTypedef = null; // The final chosen EnumTypedef + // Create the variables EnumTypedef on speculation + EnumTypedef template = new EnumTypedef(mdt.enumTypeName, mdt.map); + if (template.getShortName().equals(v.shortName)) { // Condition 1 + Optional candidate = parent.findEnumTypedef(mdt.enumTypeName, false); + if (!candidate.isPresent()) { // Condition 2 + candidate = parent.findSimilarEnumTypedef(template, true, false); + if (candidate.isPresent()) // Condition 3; use correct EnumTypedef + actualEnumTypedef = candidate.get(); + else { // !Condition 3 + log.warn("EnumTypedef is missing for variable: {}", v.shortName); + throw new IllegalStateException("EnumTypedef is missing for variable: " + v.shortName); + } + } else { // !Condition 2 + log.warn("Duplicate name: EnumTypedef and Variable: {}", v.shortName); + throw new IllegalStateException("Duplicate name: EnumTypedef and Variable: " + v.shortName); + } + } else // ! Condition 1; use template + actualEnumTypedef = template; + v.setEnumTypeName(actualEnumTypedef.getShortName()); } return true; @@ -1610,6 +1641,10 @@ public class Vinfo { boolean useFillValue; byte[] fillValue; + public DataBTree getBtree() { + return btree; + } + public String getCompression() { if (mfp == null) return null; diff --git a/cdm/core/src/main/java/ucar/nc2/internal/iosp/hdf5/H5iospNew.java b/cdm/core/src/main/java/ucar/nc2/internal/iosp/hdf5/H5iospNew.java index e881ee9103..771737de0e 100644 --- a/cdm/core/src/main/java/ucar/nc2/internal/iosp/hdf5/H5iospNew.java +++ b/cdm/core/src/main/java/ucar/nc2/internal/iosp/hdf5/H5iospNew.java @@ -97,7 +97,7 @@ public String getFileTypeDescription() { return "Hierarchical Data Format, version 5"; } - RandomAccessFile getRandomAccessFile() { + public RandomAccessFile getRandomAccessFile() { return raf; } diff --git a/cdm/core/src/main/java/ucar/nc2/internal/iosp/hdf5/H5objects.java b/cdm/core/src/main/java/ucar/nc2/internal/iosp/hdf5/H5objects.java index 110885a280..23794555d0 100644 --- a/cdm/core/src/main/java/ucar/nc2/internal/iosp/hdf5/H5objects.java +++ b/cdm/core/src/main/java/ucar/nc2/internal/iosp/hdf5/H5objects.java @@ -1774,7 +1774,7 @@ String getName() { } int getId() { - return (int) this.properties.get(Filters.Keys.ID); + return ((Short) this.properties.get(Filters.Keys.ID)).intValue(); } Map getProperties() { diff --git a/cdm/core/src/main/java/ucar/nc2/iosp/hdf5/H5header.java b/cdm/core/src/main/java/ucar/nc2/iosp/hdf5/H5header.java index 3db0bd88c1..429b9d1b41 100644 --- a/cdm/core/src/main/java/ucar/nc2/iosp/hdf5/H5header.java +++ b/cdm/core/src/main/java/ucar/nc2/iosp/hdf5/H5header.java @@ -489,7 +489,7 @@ private boolean makeNetcdfGroup(ucar.nc2.Group ncGroup, H5Group h5group) throws } if (facadeNested.dobj.mdt.map != null) { - EnumTypedef enumTypedef = ncGroup.findEnumeration(facadeNested.name); + EnumTypedef enumTypedef = ncGroup.findEnumeration(facadeNested.name, false); if (enumTypedef == null) { DataType basetype; switch (facadeNested.dobj.mdt.byteSize) { @@ -547,7 +547,7 @@ private boolean makeNetcdfGroup(ucar.nc2.Group ncGroup, H5Group h5group) throws // This code apparently addresses the possibility of an anonymous enum LOOK ?? String ename = enumTypedef.getShortName(); if (ename == null || ename.isEmpty()) { - enumTypedef = ncGroup.findEnumeration(facadeNested.name); + enumTypedef = ncGroup.findEnumeration(facadeNested.name, false); if (enumTypedef == null) { enumTypedef = new EnumTypedef(facadeNested.name, facadeNested.dobj.mdt.map); ncGroup.addEnumeration(enumTypedef); diff --git a/cdm/core/src/main/java/ucar/nc2/ncml/NcMLReader.java b/cdm/core/src/main/java/ucar/nc2/ncml/NcMLReader.java index 189a8a2abd..c757a94a1f 100644 --- a/cdm/core/src/main/java/ucar/nc2/ncml/NcMLReader.java +++ b/cdm/core/src/main/java/ucar/nc2/ncml/NcMLReader.java @@ -996,7 +996,7 @@ private void readVariable(NetcdfDataset ds, Group g, Group refg, Element varElem if (dtype.isEnum()) { String typedefS = varElem.getAttributeValue("typedef"); if (typedefS != null) - typedef = g.findEnumeration(typedefS); + typedef = g.findEnumeration(typedefS, true); } String shape = varElem.getAttributeValue("shape"); @@ -1207,7 +1207,7 @@ private Variable readVariableNew(NetcdfDataset ds, Group g, Structure parentS, E if (dtype.isEnum()) { String typedefS = varElem.getAttributeValue("typedef"); if (typedefS != null) - typedef = g.findEnumeration(typedefS); + typedef = g.findEnumeration(typedefS, true); } String shape = varElem.getAttributeValue("shape"); diff --git a/cdm/core/src/main/java/ucar/nc2/util/CompareNetcdf2.java b/cdm/core/src/main/java/ucar/nc2/util/CompareNetcdf2.java index f71c84a0bc..5de0fa63f4 100644 --- a/cdm/core/src/main/java/ucar/nc2/util/CompareNetcdf2.java +++ b/cdm/core/src/main/java/ucar/nc2/util/CompareNetcdf2.java @@ -165,6 +165,7 @@ public static boolean checkContains(String what, List container, List SERVERS; + + static { + SERVERS = new ArrayList<>(); + SERVERS.add(new Server("149.165.169.123", "8080")); + SERVERS.add(new Server("remotetest.unidata.ucar.edu", null)); + } + + ////////////////////////////////////////////////// + // Instance variables + + // Test cases + + List alltestcases = new ArrayList(); + List chosentests = new ArrayList(); + + String datasetpath = null; + + Server server = null; + + ////////////////////////////////////////////////// + + @Before + public void setup() throws Exception { + // Find the server to use + this.server = null; + for (Server svc : SERVERS) { + String url = svc.getTestURL(); + try (HTTPMethod method = HTTPFactory.Get(url)) { + try { + int code = method.execute(); + if (code == 200) { + this.server = svc; + System.out.println("Using server url " + url); + break; + } + } catch (HTTPException e) { + this.server = null; + } + } + } + if (this.server == null) + throw new Exception("Cannot locate server"); + defineAllTestcases(this.getResourceDir(), SERVLETPATH, this.server.getURL()); + chooseTestcases(); + if (BUILDBASELINE) + prop_baseline = true; + } + + ////////////////////////////////////////////////// + // Define test cases + + void chooseTestcases() { + if (false) { + chosentests = locate("test_atomic_types.nc"); + prop_baseline = true; + } else { + for (ClientTest tc : alltestcases) { + chosentests.add(tc); + } + } + } + + boolean defineAllTestcases(String root, String servlet, String server) { + boolean what = HEADERONLY; + ClientTest.root = root; + ClientTest.server = server; + ClientTest.servlet = servlet; + alltestcases.add(new ClientTest("test_atomic_array.nc")); + alltestcases.add(new ClientTest("test_atomic_types.nc")); + alltestcases.add(new ClientTest("test_enum.nc")); + alltestcases.add(new ClientTest("test_enum_2.nc")); + alltestcases.add(new ClientTest("test_enum_array.nc")); + alltestcases.add(new ClientTest("test_enum1.nc")); + alltestcases.add(new ClientTest("test_fill.nc")); + alltestcases.add(new ClientTest("test_groups1.nc")); + if (BROKEN) + alltestcases.add(new ClientTest("test_misc1.nc")); // 0 size unlimited + if (BROKEN) + alltestcases.add(new ClientTest("test_one_var.nc")); // 0 size unlimited + alltestcases.add(new ClientTest("test_one_vararray.nc")); + alltestcases.add(new ClientTest("test_opaque.nc")); + alltestcases.add(new ClientTest("test_opaque_array.nc")); + alltestcases.add(new ClientTest("test_struct_array.nc")); + alltestcases.add(new ClientTest("test_struct_nested.nc")); + alltestcases.add(new ClientTest("test_struct_nested3.nc")); + alltestcases.add(new ClientTest("test_struct_type.nc")); + alltestcases.add(new ClientTest("test_struct1.nc")); + alltestcases.add(new ClientTest("test_test.nc")); + if (BROKEN) + alltestcases.add(new ClientTest("test_unlim.nc")); // ? + if (BROKEN) + alltestcases.add(new ClientTest("test_unlim1.nc")); // ? + if (BROKEN) + alltestcases.add(new ClientTest("test_utf8.nc")); // ? + alltestcases.add(new ClientTest("test_vlen1.nc")); + if (BROKEN) + alltestcases.add(new ClientTest("test_vlen2.nc")); // non scalar vlen + if (BROKEN) + alltestcases.add(new ClientTest("test_vlen3.nc")); // non scalar vlen + if (BROKEN) + alltestcases.add(new ClientTest("test_vlen4.nc")); // non scalar vlen + alltestcases.add(new ClientTest("test_vlen5.nc")); + if (BROKEN) + alltestcases.add(new ClientTest("test_vlen6.nc")); // non-scalar vlen + if (BROKEN) + alltestcases.add(new ClientTest("test_vlen7.nc")); // non-scalar vlen + if (BROKEN) + alltestcases.add(new ClientTest("test_vlen8.nc")); // non-scalar vlen + if (BROKEN) + alltestcases.add(new ClientTest("test_vlen9.nc")); // non-scalar + if (BROKEN) + alltestcases.add(new ClientTest("test_vlen10.nc")); // non-scalar + if (BROKEN) + alltestcases.add(new ClientTest("test_vlen11.nc")); // unknown failure + if (BROKEN) + alltestcases.add(new ClientTest("test_zerodim.nc")); // non-scalar seq + alltestcases.add(new ClientTest("tst_fills.nc")); + for (ClientTest test : alltestcases) { + if (what == HEADERONLY) + test.headeronly(); + } + return true; + } + + ////////////////////////////////////////////////// + // Junit test method + + @Test + public void testDAP4Client() throws Exception { + boolean pass = true; + for (ClientTest testcase : chosentests) { + if (!doOneTest(testcase)) + pass = false; + } + Assert.assertTrue("*** Fail: TestDAP4Client", pass); + } + + ////////////////////////////////////////////////// + // Primary test method + + boolean doOneTest(ClientTest testcase) throws Exception { + boolean pass = true; + System.out.println("Testcase: " + testcase.dataset); + String url = testcase.makeurl(); + NetcdfDataset ncfile = null; + try { + ncfile = openDataset(url); + } catch (Exception e) { + System.err.println(testcase.xfail ? "XFail" : "Fail"); + e.printStackTrace(); + return testcase.xfail; + } + String usethisname = UnitTestCommon.extractDatasetname(url, null); + String metadata = (NCDUMP ? ncdumpmetadata(ncfile, usethisname) : null); + if (prop_visual) { + visual(testcase.title + ".dmr", metadata); + } + + String data = null; + if (!testcase.headeronly) { + data = (NCDUMP ? ncdumpdata(ncfile, usethisname) : null); + if (prop_visual) { + visual(testcase.title + ".dap", data); + } + } + + String testoutput = (testcase.headeronly ? metadata : (NCDUMP ? data : metadata + data)); + + String baselinefile = testcase.baselinepath + "." + EXTENSION; + + if (prop_baseline) + writefile(baselinefile, testoutput); + + if (prop_diff) { // compare with baseline + // Read the baseline file(s) + String baselinecontent = readfile(baselinefile); + System.out.println("Comparison: vs " + baselinefile); + pass = pass && same(getTitle(), baselinecontent, testoutput); + System.out.println(pass ? "Pass" : "Fail"); + } + return pass; + } + + + String ncdumpmetadata(NetcdfDataset ncfile, String datasetname) throws Exception { + StringWriter sw = new StringWriter(); + + StringBuilder args = new StringBuilder("-strict"); + if (datasetname != null) { + args.append(" -datasetname "); + args.append(datasetname); + } + // Print the meta-databuffer using these args to NcdumpW + try { + if (!ucar.nc2.NCdumpW.print(ncfile, args.toString(), sw, null)) + throw new Exception("NcdumpW failed"); + } catch (IOException ioe) { + throw new Exception("NcdumpW failed", ioe); + } + sw.close(); + return sw.toString(); + } + + String ncdumpdata(NetcdfDataset ncfile, String datasetname) throws Exception { + StringWriter sw = new StringWriter(); + + StringBuilder args = new StringBuilder("-strict -vall"); + if (datasetname != null) { + args.append(" -datasetname "); + args.append(datasetname); + } + + // Dump the databuffer + sw = new StringWriter(); + try { + if (!ucar.nc2.NCdumpW.print(ncfile, args.toString(), sw, null)) + throw new Exception("NCdumpW failed"); + } catch (IOException ioe) { + ioe.printStackTrace(); + throw new Exception("NCdumpW failed", ioe); + } + sw.close(); + return sw.toString(); + } + + ////////////////////////////////////////////////// + // Utility methods + + + // Locate the test cases with given prefix + List locate(String prefix) { + List results = new ArrayList(); + for (ClientTest ct : this.alltestcases) { + if (!ct.dataset.startsWith(prefix)) + continue; + results.add(ct); + } + return results; + } + + static boolean report(String msg) { + System.err.println(msg); + return false; + } + +} // class TestDAP4Client + diff --git a/dap4/d4tests/src/test/java/dap4/test/TestHyrax.java b/dap4/d4tests/src/test/java/dap4/test/TestHyrax.java index c4b678aa8f..3dfa0006ce 100644 --- a/dap4/d4tests/src/test/java/dap4/test/TestHyrax.java +++ b/dap4/d4tests/src/test/java/dap4/test/TestHyrax.java @@ -21,7 +21,6 @@ /** * Test OpenDap Server at the NetcdfDataset level */ - @Ignore public class TestHyrax extends DapTestCommon { private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); diff --git a/netcdf4/src/main/java/ucar/nc2/jni/netcdf/Nc4Iosp.java b/netcdf4/src/main/java/ucar/nc2/jni/netcdf/Nc4Iosp.java index af411373e0..2aa52af3b0 100755 --- a/netcdf4/src/main/java/ucar/nc2/jni/netcdf/Nc4Iosp.java +++ b/netcdf4/src/main/java/ucar/nc2/jni/netcdf/Nc4Iosp.java @@ -1072,7 +1072,7 @@ private Variable makeVariable(Group g, Structure parent, String vname, int typei } if (dtype.isEnum()) { - EnumTypedef enumTypedef = g.findEnumeration(utype.name); + EnumTypedef enumTypedef = g.findEnumeration(utype.name, true); v.setEnumTypedef(enumTypedef); } else if (dtype == DataType.OPAQUE) { // TODO whats the problem with knowing the size?? Needed to read properly??