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 * 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 * 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 * 242 * @param name the name of the group to create. 243 * @param pgroup the parent group of the new group. 244 * 245 * @return the new group if successful. Otherwise returns null. 246 * 247 * @throws Exception if the group can not be created 248 */ 249 public static H4Group create(String name, Group pgroup) 250 throws Exception 251 { 252 H4Group group = null; 253 if ((pgroup == null) || 254 (name == null)) { 255 return null; 256 } 257 258 H4File file = (H4File)pgroup.getFileFormat(); 259 260 if (file == null) { 261 return null; 262 } 263 264 String path = HObject.separator; 265 if (!pgroup.isRoot()) { 266 path = pgroup.getPath()+pgroup.getName()+HObject.separator; 267 } 268 int fileid = file.open(); 269 if (fileid < 0) { 270 return null; 271 } 272 273 int gid = HDFLibrary.Vattach(fileid, -1, "w"); 274 if (gid < 0) { 275 return null; 276 } 277 278 HDFLibrary.Vsetname(gid, name); 279 int ref = HDFLibrary.VQueryref(gid); 280 int tag = HDFLibrary.VQuerytag(gid); 281 282 if (!pgroup.isRoot()) { 283 // add the dataset to the parent group 284 int pid = pgroup.open(); 285 if (pid < 0) { 286 throw (new HDFException("Unable to open the parent group.")); 287 } 288 289 HDFLibrary.Vinsert(pid, gid); 290 291 pgroup.close(pid); 292 } 293 294 try { 295 HDFLibrary.Vdetach(gid); 296 } 297 catch (Exception ex) { 298 log.debug("create.Vdetach:", ex); 299 } 300 301 long[] oid = {tag, ref}; 302 group = new H4Group(file, name, path, pgroup, oid); 303 304 if (group != null) { 305 pgroup.addToMemberList(group); 306 } 307 308 return group; 309 } 310 311 //Implementing DataFormat 312 public List getMetadata(int... attrPropList) throws Exception { 313 throw new UnsupportedOperationException("getMetadata(int... attrPropList) is not supported"); 314 } 315 316}