156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson/*
256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Copyright (C) 2010 Google Inc.
356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson *
456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Licensed under the Apache License, Version 2.0 (the "License");
556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * you may not use this file except in compliance with the License.
656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * You may obtain a copy of the License at
756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson *
856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * http://www.apache.org/licenses/LICENSE-2.0
956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson *
1056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Unless required by applicable law or agreed to in writing, software
1156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * distributed under the License is distributed on an "AS IS" BASIS,
1256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * See the License for the specific language governing permissions and
1456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * limitations under the License.
1556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */
1656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
1756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonpackage org.clearsilver.jni;
1856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
1956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonimport org.clearsilver.CSFileLoader;
2056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonimport org.clearsilver.HDF;
2156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
2256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonimport java.io.IOException;
2356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonimport java.util.Calendar;
2456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonimport java.util.Date;
2556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonimport java.util.TimeZone;
2656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
2756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson/**
2856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * This class is a wrapper around the HDF C API.  Many features of the C API
2956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * are not yet exposed through this wrapper.
3056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */
3156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonpublic class JniHdf implements HDF {
3256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
3356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  long hdfptr;  // stores the C HDF* pointer
3456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  JniHdf root; // If this is a child HDF node, points at the root node of
3556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson               // the tree.  For root nodes this is null.  A child node needs
3656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson               // to hold a reference on the root to prevent the root from
3756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson               // being GC-ed.
3856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
3956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  static {
4056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    JNI.loadLibrary();
4156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
4256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
4356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  static JniHdf cast(HDF hdf) {
4456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if (!(hdf instanceof JniHdf)) {
4556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      throw new IllegalArgumentException("HDF object not of type JniHdf.  "
4656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson          + "Make sure you use the same ClearsilverFactory to construct all "
4756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson          + "related HDF and CS objects.");
4856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
4956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    return (JniHdf)hdf;
5056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
5156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
5256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  /**
5356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   * Default public constructor.
5456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   */
5556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  public JniHdf() {
5656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    hdfptr = _init();
5756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    root = null;
5856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
5956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
6056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  protected JniHdf(long hdfptr, JniHdf parent) {
6156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    this.hdfptr = hdfptr;
6256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    this.root = (parent.root != null) ? parent.root : parent;
6356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
6456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
6556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  /** Constructs an HDF child node.  Used by other methods in this class when
6656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   * a child node needs to be constructed.
6756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   */
6856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  protected JniHdf newHdf(long hdfptr, HDF parent) {
6956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    return new JniHdf(hdfptr, cast(parent));
7056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
7156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
7256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  /** Clean up allocated memory if neccesary. close() allows application
7356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   *  to force clean up.
7456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   */
7556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  public void close() {
7656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    // Only root nodes have ownership of the C HDF pointer, so only a root
7756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    // node needs to dealloc hdfptr.dir
7856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if (root == null) {
7956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      if (hdfptr != 0) {
8056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson        _dealloc(hdfptr);
8156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson        hdfptr = 0;
8256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      }
8356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
8456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
8556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
8656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  /** Call close() just in case when deallocating Java object.
8756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   */
8856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  protected void finalize() throws Throwable {
8956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    close();
9056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    super.finalize();
9156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
9256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
9356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  /** Loads the contents of the specified HDF file from disk into the current
9456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   *  HDF object.  The loaded contents are merged with the existing contents.
9556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   *  @param filename the name of file to read in and parse.
9656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   *  @throws java.io.FileNotFoundException if the specified file does not
9756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   *  exist.
9856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   *  @throws IOException other problems reading the file.
9956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   */
10056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  public boolean readFile(String filename) throws IOException {
10156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if (hdfptr == 0) {
10256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      throw new NullPointerException("HDF is closed.");
10356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
10456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    return _readFile(hdfptr, filename, fileLoader != null);
10556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
10656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
10756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  protected String fileLoad(String filename) throws IOException {
10856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if (hdfptr == 0) {
10956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      throw new NullPointerException("HDF is closed.");
11056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
11156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    CSFileLoader aFileLoader = fileLoader;
11256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if (aFileLoader == null) {
11356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      throw new NullPointerException("No fileLoader specified.");
11456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    } else {
11556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      String result = aFileLoader.load(this, filename);
11656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      if (result == null) {
11756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson        throw new NullPointerException("CSFileLoader.load() returned null");
11856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      }
11956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      return result;
12056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
12156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
12256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
12356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  // The optional CS file loader to use to read in files
12456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  private CSFileLoader fileLoader = null;
12556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
12656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  /**
12756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   * Get the file loader in use, if any.
12856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   * @return the file loader in use.
12956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   */
13056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  public CSFileLoader getFileLoader() {
13156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    return fileLoader;
13256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
13356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
13456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  /**
13556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   * Set the CS file loader to use
13656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   * @param fileLoader the file loader that should be used.
13756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   */
13856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  public void setFileLoader(CSFileLoader fileLoader) {
13956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    this.fileLoader = fileLoader;
14056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
14156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
14256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  /** Serializes HDF contents to a file (readable by readFile)
14356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   */
14456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  public boolean writeFile(String filename) throws IOException {
14556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if (hdfptr == 0) {
14656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      throw new NullPointerException("HDF is closed.");
14756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
14856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    return _writeFile(hdfptr, filename);
14956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
15056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
15156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  /** Parses/loads the contents of the given string as HDF into the current
15256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   *  HDF object.  The loaded contents are merged with the existing contents.
15356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   */
15456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  public boolean readString(String data) {
15556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if (hdfptr == 0) {
15656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      throw new NullPointerException("HDF is closed.");
15756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
15856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    return _readString(hdfptr, data);
15956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
16056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
16156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  /** Serializes HDF contents to a string (readable by readString)
16256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   */
16356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  public String writeString() {
16456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if (hdfptr == 0) {
16556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      throw new NullPointerException("HDF is closed.");
16656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
16756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    return _writeString(hdfptr);
16856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
16956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
17056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  /** Retrieves the integer value at the specified path in this HDF node's
17156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   *  subtree.  If the value does not exist, or cannot be converted to an
17256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   *  integer, default_value will be returned. */
17356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  public int getIntValue(String hdfname, int default_value) {
17456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if (hdfptr == 0) {
17556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      throw new NullPointerException("HDF is closed.");
17656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
17756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    return _getIntValue(hdfptr,hdfname,default_value);
17856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
17956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
18056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  /** Retrieves the value at the specified path in this HDF node's subtree.
18156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   */
18256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  public String getValue(String hdfname, String default_value) {
18356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if (hdfptr == 0) {
18456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      throw new NullPointerException("HDF is closed.");
18556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
18656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    return _getValue(hdfptr,hdfname,default_value);
18756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
18856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
18956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  /** Sets the value at the specified path in this HDF node's subtree. */
19056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  public void setValue(String hdfname, String value) {
19156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if (hdfptr == 0) {
19256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      throw new NullPointerException("HDF is closed.");
19356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
19456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    _setValue(hdfptr,hdfname,value);
19556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
19656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
19756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  /** Remove the specified subtree. */
19856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  public void removeTree(String hdfname) {
19956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if (hdfptr == 0) {
20056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      throw new NullPointerException("HDF is closed.");
20156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
20256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    _removeTree(hdfptr,hdfname);
20356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
20456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
20556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  /** Links the src hdf name to the dest. */
20656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  public void setSymLink(String hdf_name_src, String hdf_name_dest) {
20756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if (hdfptr == 0) {
20856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      throw new NullPointerException("HDF is closed.");
20956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
21056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    _setSymLink(hdfptr,hdf_name_src,hdf_name_dest);
21156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
21256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
21356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  /** Export a date to a clearsilver tree using a specified timezone */
21456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  public void exportDate(String hdfname, TimeZone timeZone, Date date) {
21556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if (hdfptr == 0) {
21656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      throw new NullPointerException("HDF is closed.");
21756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
21856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
21956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    Calendar cal = Calendar.getInstance(timeZone);
22056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    cal.setTime(date);
22156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
22256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    String sec = Integer.toString(cal.get(Calendar.SECOND));
22356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    setValue(hdfname + ".sec", sec.length() == 1 ? "0" + sec : sec);
22456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
22556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    String min = Integer.toString(cal.get(Calendar.MINUTE));
22656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    setValue(hdfname + ".min", min.length() == 1 ? "0" + min : min);
22756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
22856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    setValue(hdfname + ".24hour",
22956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson        Integer.toString(cal.get(Calendar.HOUR_OF_DAY)));
23056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    // java.util.Calendar uses represents 12 o'clock as 0
23156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    setValue(hdfname + ".hour",
23256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson        Integer.toString(
23356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson            cal.get(Calendar.HOUR) == 0 ? 12 : cal.get(Calendar.HOUR)));
23456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    setValue(hdfname + ".am",
23556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson        cal.get(Calendar.AM_PM) == Calendar.AM ? "1" : "0");
23656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    setValue(hdfname + ".mday",
23756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson        Integer.toString(cal.get(Calendar.DAY_OF_MONTH)));
23856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    setValue(hdfname + ".mon",
23956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson        Integer.toString(cal.get(Calendar.MONTH)+1));
24056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    setValue(hdfname + ".year",
24156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson        Integer.toString(cal.get(Calendar.YEAR)));
24256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    setValue(hdfname + ".2yr",
24356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson        Integer.toString(cal.get(Calendar.YEAR)).substring(2));
24456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
24556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    // Java DAY_OF_WEEK puts Sunday .. Saturday as 1 .. 7 respectively
24656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    // See http://java.sun.com/j2se/1.5.0/docs/api/java/util/Calendar.html#DAY_OF_WEEK
24756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    // However, C and Python export Sun .. Sat as 0 .. 6, because
24856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    // POSIX localtime_r produces wday 0 .. 6.  So, adjust.
24956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    setValue(hdfname + ".wday",
25056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson        Integer.toString(cal.get(Calendar.DAY_OF_WEEK) - 1));
25156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
25256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    boolean tzNegative = timeZone.getRawOffset() < 0;
25356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    int tzAbsolute = java.lang.Math.abs(timeZone.getRawOffset()/1000);
25456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    String tzHour = Integer.toString(tzAbsolute/3600);
25556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    String tzMin = Integer.toString(tzAbsolute/60 - (tzAbsolute/3600)*60);
25656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    String tzString = (tzNegative ? "-" : "+")
25756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson        + (tzHour.length() == 1 ? "0" + tzHour : tzHour)
25856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson        + (tzMin.length() == 1 ? "0" + tzMin : tzMin);
25956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    setValue(hdfname + ".tzoffset", tzString);
26056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
26156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
26256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  /** Export a date to a clearsilver tree using a specified timezone */
26356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  public void exportDate(String hdfname, String tz, int tt) {
26456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if (hdfptr == 0) {
26556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      throw new NullPointerException("HDF is closed.");
26656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
26756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
26856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    TimeZone timeZone = TimeZone.getTimeZone(tz);
26956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
27056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if (timeZone == null) {
27156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      throw new RuntimeException("Unknown timezone: " + tz);
27256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
27356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
27456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    Date date = new Date((long)tt * 1000);
27556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
27656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    exportDate(hdfname, timeZone, date);
27756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
27856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
27956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  /** Retrieves the HDF object that is the root of the subtree at hdfpath, or
28056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   *  null if no object exists at that path. */
28156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  public JniHdf getObj(String hdfpath) {
28256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if (hdfptr == 0) {
28356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      throw new NullPointerException("HDF is closed.");
28456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
28556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    long obj_ptr = _getObj(hdfptr, hdfpath);
28656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if ( obj_ptr == 0 ) {
28756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      return null;
28856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
28956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    return newHdf(obj_ptr, this);
29056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
29156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
29256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  /** Retrieves the HDF for the first child of the root of the subtree
29356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   *  at hdfpath, or null if no child exists of that path or if the
29456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   *  path doesn't exist. */
29556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  public JniHdf getChild(String hdfpath) {
29656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if (hdfptr == 0) {
29756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      throw new NullPointerException("HDF is closed.");
29856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
29956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    long obj_ptr = _getChild(hdfptr, hdfpath);
30056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if ( obj_ptr == 0 ) {
30156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      return null;
30256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
30356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    return newHdf(obj_ptr, this);
30456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
30556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
30656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  /** Return the root of the tree where the current node lies.  If the
30756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   *  current node is the root, return this. */
30856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  public JniHdf getRootObj() {
30956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    return root != null ? root : this;
31056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
31156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
31256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  public boolean belongsToSameRoot(HDF hdf) {
31356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    JniHdf jniHdf = cast(hdf);
31456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    return this.getRootObj() == jniHdf.getRootObj();
31556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
31656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
31756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  /** Retrieves the HDF object that is the root of the subtree at
31856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   *  hdfpath, create the subtree if it doesn't exist */
31956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  public JniHdf getOrCreateObj(String hdfpath) {
32056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if (hdfptr == 0) {
32156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      throw new NullPointerException("HDF is closed.");
32256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
32356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    long obj_ptr = _getObj(hdfptr, hdfpath);
32456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if ( obj_ptr == 0 ) {
32556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      // Create a node
32656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      _setValue(hdfptr, hdfpath, "");
32756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      obj_ptr = _getObj( hdfptr, hdfpath );
32856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      if ( obj_ptr == 0 ) {
32956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson        return null;
33056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      }
33156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
33256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    return newHdf(obj_ptr, this);
33356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
33456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
33556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  /** Returns the name of this HDF node.   The root node has no name, so
33656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   *  calling this on the root node will return null. */
33756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  public String objName() {
33856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if (hdfptr == 0) {
33956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      throw new NullPointerException("HDF is closed.");
34056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
34156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    return _objName(hdfptr);
34256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
34356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
34456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  /** Returns the value of this HDF node, or null if this node has no value.
34556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   *  Every node in the tree can have a value, a child, and a next peer. */
34656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  public String objValue() {
34756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if (hdfptr == 0) {
34856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      throw new NullPointerException("HDF is closed.");
34956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
35056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    return _objValue(hdfptr);
35156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
35256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
35356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  /** Returns the child of this HDF node, or null if there is no child.
35456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   *  Use this in conjunction with objNext to walk the HDF tree.  Every node
35556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   *  in the tree can have a value, a child, and a next peer.
35656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   */
35756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  public JniHdf objChild() {
35856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if (hdfptr == 0) {
35956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      throw new NullPointerException("HDF is closed.");
36056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
36156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    long child_ptr = _objChild(hdfptr);
36256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if ( child_ptr == 0 ) {
36356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      return null;
36456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
36556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    return newHdf(child_ptr, this);
36656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
36756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
36856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  /** Returns the next sibling of this HDF node, or null if there is no next
36956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   *  sibling.  Use this in conjunction with objChild to walk the HDF tree.
37056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   *  Every node in the tree can have a value, a child, and a next peer.
37156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   */
37256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  public JniHdf objNext() {
37356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if (hdfptr == 0) {
37456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      throw new NullPointerException("HDF is closed.");
37556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
37656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    long next_ptr = _objNext(hdfptr);
37756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if ( next_ptr == 0 ) {
37856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      return null;
37956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
38056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    return newHdf(next_ptr, this);
38156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
38256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
38356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  public void copy(String hdfpath, HDF src) {
38456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    JniHdf source = cast(src);
38556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if (hdfptr == 0 || source.hdfptr == 0) {
38656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      throw new NullPointerException("HDF is closed.");
38756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
38856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    _copy(hdfptr, hdfpath, source.hdfptr);
38956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
39056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
39156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  /**
39256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   * Generates a string representing the content of the HDF tree rooted at
39356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   * this node.
39456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson   */
39556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  public String dump() {
39656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    if (hdfptr == 0) {
39756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      throw new NullPointerException("HDF is closed.");
39856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    }
39956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson    return _dump(hdfptr);
40056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  }
40156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
40256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  private static native long _init();
40356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  private static native void _dealloc(long ptr);
40456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  private native boolean _readFile(long ptr, String filename, boolean use_cb)
40556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      throws IOException;
40656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  private static native boolean _writeFile(long ptr, String filename);
40756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  private static native boolean _readString(long ptr, String data);
40856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  private static native String _writeString(long ptr);
40956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  private static native int _getIntValue(long ptr, String hdfname,
41056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      int default_value);
41156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  private static native String _getValue(long ptr, String hdfname,
41256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      String default_value);
41356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  private static native void _setValue(long ptr, String hdfname,
41456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      String hdf_value);
41556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  private static native void _removeTree(long ptr, String hdfname);
41656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  private static native void _setSymLink(long ptr, String hdf_name_src,
41756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson      String hdf_name_dest);
41856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  private static native long _getObj(long ptr, String hdfpath);
41956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  private static native long _getChild(long ptr, String hdfpath);
42056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  private static native long _objChild(long ptr);
42156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  private static native long _objNext(long ptr);
42256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  private static native String _objName(long ptr);
42356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  private static native String _objValue(long ptr);
42456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  private static native void _copy(long destptr, String hdfpath, long srcptr);
42556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
42656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson  private static native String _dump(long ptr);
42756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson}
428