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 java.util.List; 018import java.util.Vector; 019 020import hdf.hdflib.HDFConstants; 021import hdf.hdflib.HDFException; 022import hdf.hdflib.HDFLibrary; 023import hdf.object.Attribute; 024import hdf.object.Dataset; 025import hdf.object.FileFormat; 026import hdf.object.Group; 027import hdf.object.HObject; 028 029/** 030 * An H4Group is a vgroup in HDF4, inheriting from Group. 031 * A vgroup is a structure designed to associate related data objects. The 032 * general structure of a vgroup is similar to that of the UNIX file system in 033 * that the vgroup may contain references to other vgroups or HDF data objects 034 * just as the UNIX directory may contain subdirectories or files. 035 * 036 * @version 1.1 9/4/2007 037 * @author Peter X. Cao 038 */ 039public class H4Group extends Group 040{ 041 private static final long serialVersionUID = 3785240955078867900L; 042 043 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(H4Group.class); 044 045 /** 046 * The list of attributes of this data object. Members of the list are 047 * instance of Attribute. 048 */ 049 @SuppressWarnings("rawtypes") 050 private List attributeList; 051 052 private int nAttributes = -1; 053 054 /** The default object ID for HDF4 objects */ 055 private static final long[] DEFAULT_OID = {0, 0}; 056 057 public H4Group(FileFormat theFile, String name, String path, Group parent) 058 { 059 this(theFile, name, path, parent, null); 060 } 061 062 /** 063 * Creates a group object with specific name, path, and parent. 064 * 065 * @param theFile the HDF file. 066 * @param name the name of this group. 067 * @param path the full path of this group. 068 * @param parent the parent of this group. 069 * @param oid the unique identifier of this data object. 070 */ 071 @SuppressWarnings("deprecation") 072 public H4Group( 073 FileFormat theFile, 074 String name, 075 String path, 076 Group parent, 077 long[] oid) 078 { 079 super (theFile, name, path, parent, ((oid == null) ? DEFAULT_OID : oid)); 080 } 081 082 /* 083 * (non-Javadoc) 084 * @see hdf.object.DataFormat#hasAttribute() 085 */ 086 @Override 087 public boolean hasAttribute () 088 { 089 if (nAttributes < 0) { 090 long vgid = open(); 091 092 if (vgid > 0) { 093 try { 094 nAttributes = HDFLibrary.Vnattrs(vgid); 095 nMembersInFile = HDFLibrary.Vntagrefs(vgid); 096 } 097 catch (Exception ex) { 098 log.debug("hasAttribute(): failure: ", ex); 099 nAttributes = 0; 100 } 101 102 log.trace("hasAttribute(): nAttributes={}", nAttributes); 103 104 close(vgid); 105 } 106 } 107 108 return (nAttributes > 0); 109 } 110 111 // Implementing DataFormat 112 @Override 113 @SuppressWarnings({"rawtypes", "unchecked"}) 114 public List getMetadata() throws HDFException 115 { 116 if (attributeList != null) { 117 log.trace("getMetadata(): attributeList != null"); 118 return attributeList; 119 } 120 else { 121 attributeList = new Vector(); 122 } 123 124 // Library methods cannot be called on HDF4 dummy root group since it has a ref of 0 125 if (oid[1] > 0) { 126 long vgid = open(); 127 log.trace("getMetadata(): open: id={}", vgid); 128 if (vgid < 0) { 129 log.debug("getMetadata(): Invalid VG ID"); 130 return attributeList; 131 } 132 133 int n = -1; 134 135 try { 136 n = HDFLibrary.Vnattrs(vgid); 137 log.trace("getMetadata(): Vnattrs: n={}", n); 138 139 boolean b = false; 140 String[] attrName = new String[1]; 141 int[] attrInfo = new int[5]; 142 for (int i=0; i<n; i++) { 143 attrName[0] = ""; 144 try { 145 b = HDFLibrary.Vattrinfo(vgid, i, attrName, attrInfo); 146 // mask off the litend bit 147 attrInfo[0] = attrInfo[0] & (~HDFConstants.DFNT_LITEND); 148 } 149 catch (HDFException ex) { 150 log.trace("getMetadata(): attribute[{}] Vattrinfo failure: ", i, ex); 151 b = false; 152 } 153 154 if (!b) { 155 continue; 156 } 157 158 long[] attrDims = {attrInfo[1]}; 159 Attribute attr = new Attribute(this, attrName[0], new H4Datatype(attrInfo[0]), attrDims); 160 attributeList.add(attr); 161 162 Object buf = null; 163 try { 164 buf = H4Datatype.allocateArray(attrInfo[0], attrInfo[1]); 165 } 166 catch (OutOfMemoryError e) { 167 log.debug("getMetadata(): out of memory: ", e); 168 } 169 170 try { 171 HDFLibrary.Vgetattr(vgid, i, buf); 172 } 173 catch (HDFException ex) { 174 log.trace("getMetadata(): attribute[{}] Vgetattr failure: ", i, ex); 175 buf = null; 176 } 177 178 if (buf != null) { 179 if ((attrInfo[0] == HDFConstants.DFNT_CHAR) || 180 (attrInfo[0] == HDFConstants.DFNT_UCHAR8)) { 181 buf = Dataset.byteToString((byte[])buf, attrInfo[1]); 182 } 183 184 attr.setData(buf); 185 } 186 } 187 } 188 catch (Exception ex) { 189 log.trace("getMetadata(): failure: ", ex); 190 } 191 finally { 192 close(vgid); 193 } 194 } 195 196 return attributeList; 197 } 198 199 // To do: implementing DataFormat 200 @Override 201 @SuppressWarnings({"rawtypes", "unchecked"}) 202 public void writeMetadata(Object info) throws Exception 203 { 204 // only attribute metadata is supported. 205 if (!(info instanceof Attribute)) { 206 log.debug("writeMetadata(): Object not an Attribute"); 207 return; 208 } 209 210 try { 211 getFileFormat().writeAttribute(this, (Attribute)info, true); 212 213 if (attributeList == null) { 214 attributeList = new Vector(); 215 } 216 217 attributeList.add(info); 218 nAttributes = attributeList.size(); 219 } 220 catch (Exception ex) { 221 log.debug("writeMetadata(): failure: ", ex); 222 } 223 } 224 225 226 // To do: implementing DataFormat 227 @Override 228 public void removeMetadata(Object info) throws HDFException { 229 log.trace("removeMetadata(): disabled"); 230 } 231 232 // implementing DataFormat 233 @Override 234 public void updateMetadata(Object info) throws Exception { 235 log.trace("updateMetadata(): disabled"); 236 } 237 238 // Implementing HObject 239 @Override 240 public long open() 241 { 242 log.trace("open(): start: for file={} with ref={}", getFID(), oid[1]); 243 244 if (oid[1] <= 0) { 245 log.debug("open(): oid[1] <= 0"); 246 return -1; // Library methods cannot be called on HDF4 dummy group with ref 0 247 } 248 249 long vgid = -1; 250 251 if (!getFileFormat().isReadOnly()) { 252 // try to open with write permission 253 try { 254 vgid = HDFLibrary.Vattach(getFID(), (int)oid[1], "w"); 255 log.trace("open(): Vattach write id={}", vgid); 256 } 257 catch (HDFException ex) { 258 log.debug("open(): Vattach failure: ", ex); 259 vgid = -1; 260 } 261 } 262 263 // try to open with read-only permission 264 if (getFileFormat().isReadOnly() || vgid < 0) { 265 try { 266 vgid = HDFLibrary.Vattach(getFID(), (int)oid[1], "r"); 267 log.trace("open(): Vattach readonly id={}", vgid); 268 } 269 catch (HDFException ex) { 270 log.debug("open(): Vattach failure: ", ex); 271 vgid = -1; 272 } 273 } 274 275 return vgid; 276 } 277 278 /** close group access. */ 279 @Override 280 public void close(long vgid) 281 { 282 log.trace("close(): id={}", vgid); 283 284 if (vgid >= 0) { 285 try { 286 HDFLibrary.Vdetach(vgid); 287 } 288 catch (Exception ex) { 289 log.debug("close(): Vdetach failure: ", ex); 290 } 291 } 292 } 293 294 /** 295 * Creates a new group. 296 * 297 * @param name the name of the group to create. 298 * @param pgroup the parent group of the new group. 299 * 300 * @return the new group if successful. Otherwise returns null. 301 * 302 * @throws Exception if the group can not be created 303 */ 304 public static H4Group create(String name, Group pgroup) 305 throws Exception 306 { 307 log.trace("create(): start: name={} parentGroup={}", name, pgroup); 308 309 H4Group group = null; 310 if ((pgroup == null) || 311 (name == null)) { 312 log.debug("create(): one or more parameters are null"); 313 return null; 314 } 315 316 H4File file = (H4File)pgroup.getFileFormat(); 317 318 if (file == null) { 319 log.debug("create(): Parent group FileFormat is null"); 320 return null; 321 } 322 323 String path = HObject.SEPARATOR; 324 if (!pgroup.isRoot()) { 325 path = pgroup.getPath()+pgroup.getName()+HObject.SEPARATOR; 326 } 327 long fileid = file.open(); 328 if (fileid < 0) { 329 log.debug("create(): Invalid File ID"); 330 return null; 331 } 332 333 long gid = HDFLibrary.Vattach(fileid, -1, "w"); 334 if (gid < 0) { 335 log.debug("create(): Invalid Group ID"); 336 return null; 337 } 338 339 HDFLibrary.Vsetname(gid, name); 340 int ref = HDFLibrary.VQueryref(gid); 341 int tag = HDFLibrary.VQuerytag(gid); 342 343 if (!pgroup.isRoot()) { 344 // add the dataset to the parent group 345 long pid = pgroup.open(); 346 if (pid < 0) { 347 log.debug("create(): Invalid Parent Group ID"); 348 throw (new HDFException("Unable to open the parent group.")); 349 } 350 351 HDFLibrary.Vinsert(pid, gid); 352 353 pgroup.close(pid); 354 } 355 356 try { 357 HDFLibrary.Vdetach(gid); 358 } 359 catch (Exception ex) { 360 log.debug("create(): Vdetach failure: ", ex); 361 } 362 363 long[] oid = {tag, ref}; 364 group = new H4Group(file, name, path, pgroup, oid); 365 366 if (group != null) { 367 pgroup.addToMemberList(group); 368 } 369 370 return group; 371 } 372 373 //Implementing DataFormat 374 @SuppressWarnings("rawtypes") 375 public List getMetadata(int... attrPropList) throws Exception { 376 throw new UnsupportedOperationException("getMetadata(int... attrPropList) is not supported"); 377 } 378}