    001/*****************************************************************************
    002 * Copyright by The HDF Group.                                               *
    003 * Copyright by the Board of Trustees of the University of Illinois.         *
    004 * All rights reserved.                                                      *
    005 *                                                                           *
    006 * This file is part of the HDF Java Products distribution.                  *
    007 * The full copyright notice, including terms governing use, modification,   *
    008 * and redistribution, is contained in the files COPYING and Copyright.html. *
    009 * COPYING can be found at the root of the source code distribution tree.    *
    010 * Or, see https://support.hdfgroup.org/products/licenses.html               *
    011 * If you do not have access to either file, you may request a copy from     *
    012 * help@hdfgroup.org.                                                        *
    013 ****************************************************************************/
    014
    015package hdf.object.h4;
    016
    017import hdf.object.Attribute;
    018import hdf.object.Datatype;
    019import hdf.object.FileFormat;
    020import hdf.object.HObject;
    021
    022/**
    023 * An attribute is a (name, value) pair of metadata attached to a primary data object such as a
    024 * dataset, group or named datatype.
    025 * <p>
    026 * Like a dataset, an attribute has a name, datatype and dataspace.
    027 *
    028 * <p>
    029 * For more details on attributes, <a href=
    030 * "https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/index.html">HDF5
    031 * User's Guide</a>
    032 * <p>
    033 *
    034 * The following code is an example of an attribute with 1D integer array of two elements.
    035 *
    036 * <pre>
    037 * // Example of creating a new attribute
    038 * // The name of the new attribute
    039 * String name = "Data range";
    040 * // Creating an unsigned 1-byte integer datatype
    041 * Datatype type = new Datatype(Datatype.CLASS_INTEGER, // class
    042 *                              1,                      // size in bytes
    043 *                              Datatype.ORDER_LE,      // byte order
    044 *                              Datatype.SIGN_NONE);    // unsigned
    045 * // 1-D array of size two
    046 * long[] dims = {2};
    047 * // The value of the attribute
    048 * int[] value = {0, 255};
    049 * // Create a new attribute
    050 * Attribute dataRange = new Attribute(name, type, dims);
    051 * // Set the attribute value
    052 * dataRange.setValue(value);
    053 * // See FileFormat.writeAttribute() for how to attach an attribute to an object,
    054 * &#64;see hdf.object.FileFormat#writeAttribute(HObject, Attribute, boolean)
    055 * </pre>
    056 *
    057 *
    058 * For an atomic datatype, the value of an Attribute will be a 1D array of integers, floats and
    059 * strings. For a compound datatype, it will be a 1D array of strings with field members separated
    060 * by a comma. For example, "{0, 10.5}, {255, 20.0}, {512, 30.0}" is a compound attribute of {int,
    061 * float} of three data points.
    062 *
    063 * @see hdf.object.Datatype
    064 *
    065 * @version 2.0 4/2/2018
    066 * @author Peter X. Cao, Jordan T. Henderson
    067 */
    068public class H4Attribute extends Attribute {
    069
    070    private static final long serialVersionUID = 2072473407027648309L;
    071
    072    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(H4Attribute.class);
    073
    074    /**
    075     * Create an attribute with specified name, data type and dimension sizes.
    076     *
    077     * For scalar attribute, the dimension size can be either an array of size one
    078     * or null, and the rank can be either 1 or zero. Attribute is a general class
    079     * and is independent of file format, e.g., the implementation of attribute
    080     * applies to both HDF4 and HDF5.
    081     * <p>
    082     * The following example creates a string attribute with the name "CLASS" and
    083     * value "IMAGE".
    084     *
    085     * <pre>
    086     * long[] attrDims = { 1 };
    087     * String attrName = &quot;CLASS&quot;;
    088     * String[] classValue = { &quot;IMAGE&quot; };
    089     * Datatype attrType = null;
    090     * try {
    091     *     attrType = new H5Datatype(Datatype.CLASS_STRING, classValue[0].length() + 1, Datatype.NATIVE, Datatype.NATIVE);
    092     * }
    093     * catch (Exception ex) {}
    094     * Attribute attr = new Attribute(attrName, attrType, attrDims);
    095     * attr.setValue(classValue);
    096     * </pre>
    097     *
    098     * @param parentObj
    099     *            the HObject to which this Attribute is attached.
    100     * @param attrName
    101     *            the name of the attribute.
    102     * @param attrType
    103     *            the datatype of the attribute.
    104     * @param attrDims
    105     *            the dimension sizes of the attribute, null for scalar attribute
    106     *
    107     * @see hdf.object.Datatype
    108     */
    109    public H4Attribute(HObject parentObj, String attrName, Datatype attrType, long[] attrDims) {
    110        this(parentObj, attrName, attrType, attrDims, null);
    111    }
    112
    113    /**
    114     * Create an attribute with specific name and value.
    115     *
    116     * For scalar attribute, the dimension size can be either an array of size one
    117     * or null, and the rank can be either 1 or zero. Attribute is a general class
    118     * and is independent of file format, e.g., the implementation of attribute
    119     * applies to both HDF4 and HDF5.
    120     * <p>
    121     * The following example creates a string attribute with the name "CLASS" and
    122     * value "IMAGE".
    123     *
    124     * <pre>
    125     * long[] attrDims = { 1 };
    126     * String attrName = &quot;CLASS&quot;;
    127     * String[] classValue = { &quot;IMAGE&quot; };
    128     * Datatype attrType = null;
    129     * try {
    130     *     attrType = new H5Datatype(Datatype.CLASS_STRING, classValue[0].length() + 1, Datatype.NATIVE, Datatype.NATIVE);
    131     * }
    132     * catch (Exception ex) {}
    133     * Attribute attr = new Attribute(attrName, attrType, attrDims, classValue);
    134     * </pre>
    135     *
    136     * @param parentObj
    137     *            the HObject to which this Attribute is attached.
    138     * @param attrName
    139     *            the name of the attribute.
    140     * @param attrType
    141     *            the datatype of the attribute.
    142     * @param attrDims
    143     *            the dimension sizes of the attribute, null for scalar attribute
    144     * @param attrValue
    145     *            the value of the attribute, null if no value
    146     *
    147     * @see hdf.object.Datatype
    148     */
    149    @SuppressWarnings({ "rawtypes", "unchecked", "deprecation" })
    150    public H4Attribute(HObject parentObj, String attrName, Datatype attrType, long[] attrDims, Object attrValue) {
    151        super(parentObj, attrName, attrType, null);
    152    }
    153
    154    /*
    155     * (non-Javadoc)
    156     *
    157     * @see hdf.object.HObject#open()
    158     */
    159    @Override
    160    public long open() {
    161        long aid = super.open();
    162        long pObjID = -1;
    163
    164        try {
    165            pObjID = parentObject.open();
    166            if (pObjID >= 0) {
    167                if (this.getFileFormat().isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF4))) {
    168                    log.trace("open(): FILE_TYPE_HDF4");
    169                    /*
    170                     * TODO: Get type of HDF4 object this is attached to and retrieve attribute info.
    171                     */
    172                }
    173            }
    174
    175            log.trace("open(): aid={}", aid);
    176        }
    177        catch (Exception ex) {
    178            log.debug("open(): Failed to open attribute {}: ", getName(), ex);
    179            aid = -1;
    180        }
    181        finally {
    182            parentObject.close(pObjID);
    183        }
    184
    185        return aid;
    186    }
    187
    188    /*
    189     * (non-Javadoc)
    190     *
    191     * @see hdf.object.HObject#close(int)
    192     */
    193    @Override
    194    public void close(long aid) {
    195        if (aid >= 0) {
    196            if (this.getFileFormat().isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF4))) {
    197                log.trace("close(): FILE_TYPE_HDF4");
    198                /*
    199                 * TODO: Get type of HDF4 object this is attached to and close attribute.
    200                 */
    201            }
    202        }
    203    }
    204
    205    @Override
    206    public void init() {
    207        super.init();
    208        if (inited) {
    209            return;
    210        }
    211
    212        if (this.getFileFormat().isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF4))) {
    213            log.trace("init(): FILE_TYPE_HDF4");
    214            /*
    215             * TODO: If HDF4 attribute object needs to init dependent objects.
    216             */
    217            inited = true;
    218        }
    219
    220        resetSelection();
    221    }
    222}