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.nc2; 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 * @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 NC2Attribute extends Attribute { 069 070 private static final long serialVersionUID = 2072473407027648309L; 071 072 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(NC2Attribute.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 = "CLASS"; 088 * String[] classValue = { "IMAGE" }; 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 NC2Attribute(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 = "CLASS"; 127 * String[] classValue = { "IMAGE" }; 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 NC2Attribute(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_NC3))) { 168 log.trace("open(): FILE_TYPE_NC3"); 169 /* 170 * TODO: Get type of netcdf3 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_NC3))) { 197 log.trace("close(): FILE_TYPE_NC3"); 198 /* 199 * TODO: Get type of netcdf3 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_NC3))) { 213 log.trace("init(): FILE_TYPE_NC3"); 214 /* 215 * TODO: If netcdf3 attribute object needs to init dependent objects. 216 */ 217 inited = true; 218 } 219 220 resetSelection(); 221 } 222}