cdm/src/main/java/ucar/nc2/dataset/CoordSysBuilder.java
static public @Nonnull
  CoordSysBuilderIF factory(NetcdfDataset ds, CancelTask cancelTask) throws IOException {

    // look for the Conventions attribute
    String convName = ds.findAttValueIgnoreCase(null, CDM.CONVENTIONS, null);
    if (convName == null)
      convName = ds.findAttValueIgnoreCase(null, "Convention", null); // common mistake Convention instead of Conventions
    if (convName != null)
      convName = convName.trim();

    // look for ncml first
    if (convName != null) {
      String convNcML = ncmlHash.get(convName);
      if (convNcML != null) {
        CoordSysBuilder csb = new CoordSysBuilder();
        NcMLReader.wrapNcML(ds, convNcML, cancelTask);
        return csb;
      }
    }

    // look for registered conventions using convention name
    Class convClass = null;
    if (convName != null) {
      convClass = matchConvention(convName);

      // now look for comma or semicolon or / delimited list
      if (convClass == null) {
        List<String> names = breakupConventionNames(convName);
        if (names.size() > 0) {
          // search the registered conventions, in order
          for (Convention conv : conventionList) {
            for (String name : names) {
              if (name.equalsIgnoreCase(conv.convName)) {
                convClass = conv.convClass;
                convName = name;
              }
            }
            if (convClass != null) break;
          }
        }
      }
    }

    // look for ones that dont use Convention attribute, in order added.
    // call static isMine() using reflection.
    if (convClass == null) {
      for (Convention conv : conventionList) {
        Class c = conv.convClass;
        Method m;

        try {
          m = c.getMethod("isMine", NetcdfFile.class);   // LOOK cant we test if method exists ?
        } catch (NoSuchMethodException ex) {
          continue;
        }

        try {
          Boolean result = (Boolean) m.invoke(null, ds);
          if (result) {
            convClass = c;
            break;
          }
        } catch (Exception ex) {
          log.error("ERROR: Class " + c.getName() + " Exception invoking isMine method\n" + ex);
        }
      }
    }

    // use service loader mechanism
    // call static isMine() using reflection.
    CoordSysBuilderIF builder = null;
    if (convClass == null) {
      for (CoordSysBuilderIF csb : ServiceLoader.load(CoordSysBuilderIF.class)) {

        Class c = csb.getClass();
        Method m;
        try {
          m = c.getMethod("isMine", NetcdfFile.class);
        } catch (NoSuchMethodException ex) {
          continue;
        }

        try {
          Boolean result = (Boolean) m.invoke(null, ds);
          if (result) {
            builder = csb;
            convClass = c;
            break;
          }
        } catch (Exception ex) {
          log.error("ERROR: Class " + c.getName() + " Exception invoking isMine method%n" + ex);
        }
      }

    }

    // if no convention class found, use the default
    if (convClass == null)
      convClass = DefaultConvention.class;

    if (builder == null) {
      // get an instance of the class
      try {
        builder = (CoordSysBuilderIF) convClass.newInstance();
      } catch (Exception e) {
        log.error("failed on CoordSysBuilderIF for " + convClass.getName(), e);
        throw new RuntimeException(e);
      }
    }

    if (convName == null)
      builder.addUserAdvice("No 'Conventions' global attribute.");
    else if (convClass == DefaultConvention.class)
      builder.addUserAdvice("No CoordSysBuilder is defined for Conventions= '" + convName + "'\n");
    else
      builder.setConventionUsed(convClass.getName());

    ds.addAttribute(null, new Attribute(_Coordinate._CoordSysBuilder, convClass.getName()));
    return builder;
  }
static public @Nonnull
  CoordSysBuilderIF factory(NetcdfDataset ds, CancelTask cancelTask) throws IOException {

    // look for the Conventions attribute
    String convName = ds.findAttValueIgnoreCase(null, CDM.CONVENTIONS, null);
    if (convName == null)
      convName = ds.findAttValueIgnoreCase(null, "Convention", null); // common mistake Convention instead of Conventions
    if (convName != null)
      convName = convName.trim();

    // look for ncml first
    if (convName != null) {
      String convNcML = ncmlHash.get(convName);
      if (convNcML != null) {
        CoordSysBuilder csb = new CoordSysBuilder();
        NcMLReader.wrapNcML(ds, convNcML, cancelTask);
        return csb;
      }
    }

    // look for registered conventions using convention name
    Class convClass = null;
    if (convName != null) {
      convClass = matchConvention(convName);

      // now look for comma or semicolon or / delimited list
      if (convClass == null) {
        List<String> names = breakupConventionNames(convName);
        if (names.size() > 0) {
          // search the registered conventions, in order
          for (Convention conv : conventionList) {
            for (String name : names) {
              if (name.equalsIgnoreCase(conv.convName)) {
                convClass = conv.convClass;
                convName = name;
              }
            }
            if (convClass != null) break;
          }
        }
      }
    }

    // look for ones that dont use Convention attribute, in order added.
    // call static isMine() using reflection.
    if (convClass == null) {
      for (Convention conv : conventionList) {
        Class c = conv.convClass;
        Method m;

        try {
          m = c.getMethod("isMine", NetcdfFile.class);   // LOOK cant we test if method exists ?
        } catch (NoSuchMethodException ex) {
          continue;
        }

        try {
          Boolean result = (Boolean) m.invoke(null, ds);
          if (result) {
            convClass = c;
            break;
          }
        } catch (Exception ex) {
          log.error("ERROR: Class " + c.getName() + " Exception invoking isMine method\n" + ex);
        }
      }
    }

    // use service loader mechanism
    // call static isMine() using reflection.
    CoordSysBuilderIF builder = null;
    if (convClass == null) {
      for (CoordSysBuilderIF csb : ServiceLoader.load(CoordSysBuilderIF.class)) {

        Class c = csb.getClass();
        Method m;
        try {
          m = c.getMethod("isMine", NetcdfFile.class);
        } catch (NoSuchMethodException ex) {
          continue;
        }

        try {
          Boolean result = (Boolean) m.invoke(null, ds);
          if (result) {
            builder = csb;
            convClass = c;
            break;
          }
        } catch (Exception ex) {
          log.error("ERROR: Class " + c.getName() + " Exception invoking isMine method%n" + ex);
        }
      }

    }

    // if no convention class found, use the default
    if (convClass == null)
      convClass = DefaultConvention.class;

    if (builder == null) {
      // get an instance of the class
      try {
        builder = (CoordSysBuilderIF) convClass.newInstance();
      } catch (Exception e) {
        log.error("failed on CoordSysBuilderIF for " + convClass.getName(), e);
        throw new RuntimeException(e);
      }
    }

    if (convName == null)
      builder.addUserAdvice("No 'Conventions' global attribute.");
    else if (convClass == DefaultConvention.class)
      builder.addUserAdvice("No CoordSysBuilder is defined for Conventions= '" + convName + "'\n");
    else
      builder.setConventionUsed(convClass.getName());

    ds.addAttribute(null, new Attribute(_Coordinate._CoordSysBuilder, convClass.getName()));
    return builder;
  }
Get a CoordSysBuilder whose job it is to add Coordinate information to a NetcdfDataset.

@param ds         the NetcdfDataset to modify
@param cancelTask allow user to bail out.
@return the builder used
@throws java.io.IOException on io error
@see ucar.nc2.dataset.NetcdfDataset#enhance