All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ucar.nc2.iosp.hdf4.ODLparser Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 1998-2018 John Caron and University Corporation for Atmospheric Research/Unidata
 * See LICENSE for license information.
 */
package ucar.nc2.iosp.hdf4;

import java.nio.charset.StandardCharsets;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.output.XMLOutputter;
import org.jdom2.output.Format;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import ucar.nc2.util.IO;

/**
 * Turn ODL into XML
 * 
 * @author caron
 * @since Aug 7, 2007
 */

/*
 * http://newsroom.gsfc.nasa.gov/sdptoolkit/hdfeosfaq.html
 * 
 * 3.2 What types of metadata are embedded in an HDF-EOS file and what are the added storage requirements?
 * An HDF-EOS file must contain ECS "core" metadata which is essential for ECS search services. Core metadata are
 * populated
 * using the SDP Toolkit, rather than through HDF-EOS calls. "Archive" metadata (supplementary information included by
 * the
 * data provider) may also be present. If grid, point, or swath data types have been used, there also will be structural
 * metadata describing how these data types have been translated into standard HDF data types. Metadata resides in
 * human-readable form in the Object Descriptor Language (ODL). Structural metadata uses 32K of storage, regardless of
 * the amount actually required. The sizes of the core and archive metadata vary depending on what has been entered by
 * the user.
 * 
 * 3.3 What are the options for adding ECS metadata to standard HDF files?
 * For data products that will be accessed by ECS but which remain in native HDF, there is a choice of
 * 1) adding no ECS metadata in the HDF file,
 * 2) inserting ECS metadata into the HDF file, or
 * 3) "appending" ECS metadata to the HDF file. "Append" means updating the HDF location table so that the appended
 * metadata
 * becomes known to the HDF libraries/tools.
 * 
 * 3.4 Some DAACs currently provide descriptor files that give background information about the data. Will this
 * information be included in an HDF-EOS file?
 * Yes. The descriptor file will be retained. It can be viewed by EOSView if it stored either as a global attribute or a
 * file annotation.
 * 
 */
public class ODLparser {
  private static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ODLparser.class);
  private static boolean debug, showRaw, show;

  private Document doc;

  public void showDoc(PrintWriter out) {
    XMLOutputter fmt = new XMLOutputter(Format.getPrettyFormat());
    try {
      fmt.output(doc, out);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  public void parseFile(String filename) throws IOException {
    String text = new String(IO.readFileToByteArray(filename), StandardCharsets.UTF_8);
    parseFromString(text);
  }

  public Element parseFromString(String text) {
    if (showRaw)
      System.out.println("Raw ODL=\n" + text);

    Element rootElem = new Element("odl");
    doc = new Document(rootElem);

    Element current = rootElem;
    StringTokenizer lineFinder = new StringTokenizer(text, "\t\n\r\f");
    while (lineFinder.hasMoreTokens()) {
      String line = lineFinder.nextToken();
      if (line == null)
        continue;

      if (line.startsWith("GROUP")) {
        current = startGroup(current, line);

      } else if (line.startsWith("OBJECT")) {
        current = startObject(current, line);

      } else if (line.startsWith("END_OBJECT")) {
        endObject(current, line);
        current = current.getParentElement();
        if (current == null)
          throw new IllegalStateException();

      } else if (line.startsWith("END_GROUP")) {
        endGroup(current, line);
        current = current.getParentElement();
        if (current == null)
          throw new IllegalStateException();

      } else {
        addField(current, line);
      }
    }

    if (show)
      showDoc(new PrintWriter(new OutputStreamWriter(System.out, StandardCharsets.UTF_8)));
    return rootElem;
  }

  Element startGroup(Element parent, String line) {
    StringTokenizer stoke = new StringTokenizer(line, "=");
    String toke = stoke.nextToken();
    assert toke.equals("GROUP");
    String name = stoke.nextToken();
    Element group = new Element(name);
    parent.addContent(group);
    return group;
  }

  void endGroup(Element current, String line) {
    StringTokenizer stoke = new StringTokenizer(line, "=");
    String toke = stoke.nextToken();
    assert toke.equals("END_GROUP");
    String name = stoke.nextToken();
    if (debug)
      System.out.println(line + " -> " + current);
    assert name.equals(current.getName());
  }

  Element startObject(Element parent, String line) {
    StringTokenizer stoke = new StringTokenizer(line, "=");
    String toke = stoke.nextToken();
    assert toke.equals("OBJECT");
    String name = stoke.nextToken();
    Element obj = new Element(name);
    parent.addContent(obj);
    return obj;
  }

  void endObject(Element current, String line) {
    StringTokenizer stoke = new StringTokenizer(line, "=");
    String toke = stoke.nextToken();
    assert toke.equals("END_OBJECT");
    String name = stoke.nextToken();
    if (debug)
      System.out.println(line + " -> " + current);
    assert name.equals(current.getName()) : name + " !+ " + current.getName();
  }

  void addField(Element parent, String line) {
    StringTokenizer stoke = new StringTokenizer(line, "=");
    String name = stoke.nextToken();
    if (stoke.hasMoreTokens()) {
      Element field = new Element(name);
      parent.addContent(field);
      String value = stoke.nextToken();

      if (value.startsWith("(")) {
        parseValueCollection(field, value);
        return;
      }

      value = stripQuotes(value);
      field.addContent(value);
    }
  }

  void parseValueCollection(Element field, String value) {
    if (value.startsWith("("))
      value = value.substring(1);
    if (value.endsWith(")"))
      value = value.substring(0, value.length() - 1);
    StringTokenizer stoke = new StringTokenizer(value, "\",");
    while (stoke.hasMoreTokens()) {
      field.addContent(new Element("value").addContent(stripQuotes(stoke.nextToken())));
    }
  }

  String stripQuotes(String name) {
    if (name.startsWith("\""))
      name = name.substring(1);
    if (name.endsWith("\""))
      name = name.substring(0, name.length() - 1);
    return name;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy