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