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 http://hdfgroup.org/products/hdf-java/doc/Copyright.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 * <p> 036 * @version 1.1 9/4/2007 037 * @author Peter X. Cao 038 */ 039public class H4Group extends Group 040{ 041 /** 042 * 043 */ 044 private static final long serialVersionUID = 3785240955078867900L; 045 046 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(H4Group.class); 047 048 /** 049 * The list of attributes of this data object. Members of the list are 050 * instance of Attribute. 051 */ 052 private List attributeList; 053 054 private int nAttributes = -1; 055 056 /** The default object ID for HDF4 objects */ 057 private final static long[] DEFAULT_OID = {0, 0}; 058 059 public H4Group(FileFormat theFile, String name, String path, Group parent) 060 { 061 this(theFile, name, path, parent, null); 062 } 063 064 /** 065 * Creates a group object with specific name, path, and parent. 066 * <p> 067 * @param theFile the HDF file. 068 * @param name the name of this group. 069 * @param path the full path of this group. 070 * @param parent the parent of this group. 071 * @param oid the unique identifier of this data object. 072 */ 073 public H4Group( 074 FileFormat theFile, 075 String name, 076 String path, 077 Group parent, 078 long[] oid) 079 { 080 super (theFile, name, path, parent, ((oid == null) ? DEFAULT_OID : oid)); 081 } 082 083 /* 084 * (non-Javadoc) 085 * @see hdf.object.DataFormat#hasAttribute() 086 */ 087 public boolean hasAttribute () 088 { 089 if (nAttributes < 0) { 090 int vgid = open(); 091 try { 092 nAttributes =HDFLibrary.Vnattrs(vgid); 093 nMembersInFile = HDFLibrary.Vntagrefs(vgid); 094 } 095 catch (Exception ex) { 096 nAttributes = 0; 097 } 098 close(vgid); 099 } 100 101 return (nAttributes > 0); 102 } 103 104 // Implementing DataFormat 105 public List getMetadata() throws HDFException 106 { 107 if (attributeList != null) { 108 return attributeList; 109 } 110 else { 111 attributeList = new Vector(); 112 } 113 114 int vgid = open(); 115 if (vgid <= 0) { 116 return attributeList; 117 } 118 119 int n = -1; 120 121 try { 122 n = HDFLibrary.Vnattrs(vgid); 123 124 boolean b = false; 125 String[] attrName = new String[1]; 126 int[] attrInfo = new int[5]; 127 for (int i=0; i<n; i++) { 128 attrName[0] = ""; 129 try { 130 b = HDFLibrary.Vattrinfo(vgid, i, attrName, attrInfo); 131 // mask off the litend bit 132 attrInfo[0] = attrInfo[0] & (~HDFConstants.DFNT_LITEND); 133 } 134 catch (HDFException ex) { 135 b = false; 136 } 137 138 if (!b) { 139 continue; 140 } 141 142 long[] attrDims = {attrInfo[1]}; 143 Attribute attr = new Attribute(attrName[0], new H4Datatype(attrInfo[0]), attrDims);; 144 attributeList.add(attr); 145 146 Object buf = H4Datatype.allocateArray(attrInfo[0], attrInfo[1]); 147 148 try { 149 HDFLibrary.Vgetattr(vgid, i, buf); 150 } 151 catch (HDFException ex) { 152 ex.printStackTrace(); 153 buf = null; 154 } 155 156 if (buf != null) { 157 if ((attrInfo[0] == HDFConstants.DFNT_CHAR) || 158 (attrInfo[0] == HDFConstants.DFNT_UCHAR8)) { 159 buf = Dataset.byteToString((byte[])buf, attrInfo[1]); 160 } 161 162 attr.setValue(buf); 163 } 164 } 165 } 166 finally { 167 close(vgid); 168 } 169 170 return attributeList; 171 } 172 173 // To do: implementing DataFormat 174 public void writeMetadata(Object info) throws Exception 175 { 176 // only attribute metadata is supported. 177 if (!(info instanceof Attribute)) { 178 return; 179 } 180 181 getFileFormat().writeAttribute(this, (Attribute)info, true); 182 183 if (attributeList == null) { 184 attributeList = new Vector(); 185 } 186 187 attributeList.add(info); 188 nAttributes = attributeList.size(); 189 } 190 191 192 // To do: implementing DataFormat 193 public void removeMetadata(Object info) throws HDFException {;} 194 195 // implementing DataFormat 196 public void updateMetadata(Object info) throws Exception { 197 log.trace("updateMetadata(): disabled"); 198 } 199 200 // Implementing HObject 201 @Override 202 public int open() 203 { 204 int vgid = -1; 205 206 // try to open with write permission 207 try { 208 vgid = HDFLibrary.Vattach(getFID(), (int)oid[1], "w"); 209 } 210 catch (HDFException ex) { 211 vgid = -1; 212 } 213 214 // try to open with read-only permission 215 if (vgid < 0) { 216 try { 217 vgid = HDFLibrary.Vattach(getFID(), (int)oid[1], "r"); 218 } 219 catch (HDFException ex) { 220 vgid = -1; 221 } 222 } 223 224 return vgid; 225 } 226 227 /** close group access. */ 228 @Override 229 public void close(int vgid) 230 { 231 try { 232 HDFLibrary.Vdetach(vgid); 233 } 234 catch (Exception ex) { 235 log.debug("close.Vdetach:", ex); 236 } 237 } 238 239 /** 240 * Creates a new group. 241 * @param name the name of the group to create. 242 * @param pgroup the parent group of the new group. 243 * @return the new group if successful. Otherwise returns null. 244 */ 245 public static H4Group create(String name, Group pgroup) 246 throws Exception 247 { 248 H4Group group = null; 249 if ((pgroup == null) || 250 (name == null)) { 251 return null; 252 } 253 254 H4File file = (H4File)pgroup.getFileFormat(); 255 256 if (file == null) { 257 return null; 258 } 259 260 String path = HObject.separator; 261 if (!pgroup.isRoot()) { 262 path = pgroup.getPath()+pgroup.getName()+HObject.separator; 263 } 264 int fileid = file.open(); 265 if (fileid < 0) { 266 return null; 267 } 268 269 int gid = HDFLibrary.Vattach(fileid, -1, "w"); 270 if (gid < 0) { 271 return null; 272 } 273 274 HDFLibrary.Vsetname(gid, name); 275 int ref = HDFLibrary.VQueryref(gid); 276 int tag = HDFLibrary.VQuerytag(gid); 277 278 if (!pgroup.isRoot()) { 279 // add the dataset to the parent group 280 int pid = pgroup.open(); 281 if (pid < 0) { 282 throw (new HDFException("Unable to open the parent group.")); 283 } 284 285 HDFLibrary.Vinsert(pid, gid); 286 287 pgroup.close(pid); 288 } 289 290 try { 291 HDFLibrary.Vdetach(gid); 292 } 293 catch (Exception ex) { 294 log.debug("create.Vdetach:", ex); 295 } 296 297 long[] oid = {tag, ref}; 298 group = new H4Group(file, name, path, pgroup, oid); 299 300 if (group != null) { 301 pgroup.addToMemberList(group); 302 } 303 304 return group; 305 } 306 307 //Implementing DataFormat 308 public List getMetadata(int... attrPropList) throws Exception { 309 throw new UnsupportedOperationException("getMetadata(int... attrPropList) is not supported"); 310 } 311 312}