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 java.util.Arrays; 018import java.util.List; 019import java.util.Vector; 020 021import hdf.object.FileFormat; 022import hdf.object.Group; 023import ucar.nc2.NetcdfFile; 024 025/** 026 * An NC2Group represents NetCDF3 group, inheriting from Group. Every NetCDF3 object 027 * has at least one name. An NetCDF3 group is used to store a set of the names 028 * together in one place, i.e. a group. The general structure of a group is 029 * similar to that of the UNIX file system in that the group may contain 030 * references to other groups or data objects just as the UNIX directory may 031 * contain subdirectories or files. 032 * 033 * @version 1.1 9/4/2007 034 * @author Peter X. Cao 035 */ 036public class NC2Group extends Group 037{ 038 private static final long serialVersionUID = -1261533010442193447L; 039 040 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(NC2Group.class); 041 042 /** 043 * The corresponding netcdf Group for this group. 044 */ 045 protected ucar.nc2.Group netCDFGroup; 046 047 /** 048 * @return the corresponding netcdf Group for this group. 049 */ 050 public ucar.nc2.Group getNetCDFGroup() { 051 return netCDFGroup; 052 } 053 054 /** 055 * Set the corresponding netcdf Group for this group. 056 * 057 * @param netCDFGroup 058 * the ucar.nc2.Group to associate to this group 059 */ 060 public void setNetCDFGroup(ucar.nc2.Group netCDFGroup) { 061 this.netCDFGroup = netCDFGroup; 062 } 063 064 /** 065 * The list of attributes of this data object. Members of the list are 066 * instance of NC2Attribute. 067 */ 068 private List attributeList; 069 070 /** The list of netcdf typedefs of this data object. Members of the list are instance of ucar.nc2.*. */ 071 private List netcdfTypedefList; 072 /** The list of netcdf dimensions of this data object. Members of the list are instance of ucar.nc2.*. */ 073 private List netcdfDimensionList; 074 /** The list of netcdf attributes of this data object. Members of the list are * instance of ucar.nc2.*. */ 075 private List netcdfAttributeList; 076 077 /** The default object ID for NC2 objects */ 078 private static final long[] DEFAULT_OID = { 0 }; 079 080 /** 081 * Constructs an NC2 group with specific name, path, and parent. 082 * 083 * @param fileFormat 084 * the file which containing the group. 085 * @param name 086 * the name of this group. 087 * @param path 088 * the full path of this group. 089 * @param parent 090 * the parent of this group. 091 * @param theID 092 * the unique identifier of this data object. 093 */ 094 public NC2Group(FileFormat fileFormat, String name, String path, Group parent, long[] theID) { 095 super(fileFormat, name, path, parent, ((theID == null) ? DEFAULT_OID : theID)); 096 ucar.nc2.Group parentGroup = null; 097 if (parent != null) 098 parentGroup = ((NC2Group)parent).getNetCDFGroup(); 099 netCDFGroup = new ucar.nc2.Group(((NC2File)fileFormat).getNetcdfFile(), parentGroup, name); 100 log.trace("NC2Group:{}", name); 101 } 102 103 /** 104 * Check if the object has any attributes attached. 105 * 106 * @return true if it has any attributes, false otherwise. 107 */ 108 public boolean hasAttribute() { 109 return false; 110 } 111 112 /** 113 * @return true if this group has an attached dimension. 114 */ 115 public boolean hasDimension() { 116 return false; 117 } 118 119 // Implementing DataFormat 120 /** 121 * Retrieves the object's metadata, such as attributes, from the file. 122 * 123 * Metadata, such as attributes, is stored in a List. 124 * 125 * @return the list of metadata objects. 126 * 127 * @throws Exception 128 * if the metadata can not be retrieved 129 */ 130 @SuppressWarnings("rawtypes") 131 public List getMetadata() throws Exception { 132 if (attributeList != null) 133 return attributeList; 134 135 NC2File theFile = (NC2File)getFileFormat(); 136 NetcdfFile ncFile = theFile.getNetcdfFile(); 137 if (!isRoot() && (netCDFGroup !=null)) { 138 netcdfDimensionList = netCDFGroup.getDimensions(); 139 140 netcdfTypedefList = netCDFGroup.getEnumTypedefs(); 141 142 netcdfAttributeList = netCDFGroup.getAttributes(); 143 } 144 else { 145 netcdfDimensionList = ncFile.getDimensions(); 146 147 netcdfAttributeList = ncFile.getGlobalAttributes(); 148 } 149 if (netcdfAttributeList == null) { 150 attributeList = null; 151 } 152 else { 153 int n = netcdfAttributeList.size(); 154 log.trace("Attribute size:{}", n); 155 attributeList = new Vector(n); 156 157 ucar.nc2.Attribute netcdfAttr = null; 158 for (int i = 0; i < n; i++) { 159 netcdfAttr = (ucar.nc2.Attribute) netcdfAttributeList.get(i); 160 log.trace("getMetadata(): Attribute[{}]:{}", i, netcdfAttr.toString()); 161 attributeList.add(NC2File.convertAttribute(this, netcdfAttr)); 162 } 163 } 164 return attributeList; 165 } 166 167 /** 168 * Creates a new attribute and attached to this dataset if attribute does 169 * not exist. Otherwise, just update the value of the attribute. 170 * 171 * @param info 172 * the attribute to attach 173 * 174 * @throws Exception 175 * if there is an error 176 */ 177 public void writeMetadata(Object info) throws Exception { 178 // not supported 179 throw new UnsupportedOperationException("Unsupported operation for NetCDF."); 180 } 181 182 /** 183 * Deletes an attribute from this dataset. 184 * 185 * @param info 186 * the attribute to delete. 187 * 188 * @throws Exception 189 * if there is an error 190 */ 191 public void removeMetadata(Object info) throws Exception { 192 // not supported 193 throw new UnsupportedOperationException("Unsupported operation for NetCDF."); 194 } 195 196 // implementing DataFormat 197 /** 198 * Updates an attribute from this dataset. 199 * 200 * @param info 201 * the attribute to update. 202 * 203 * @throws Exception 204 * if there is an error 205 */ 206 public void updateMetadata(Object info) throws Exception { 207 // not supported 208 throw new UnsupportedOperationException("Unsupported operation for NetCDF."); 209 } 210 211 // Implementing DataFormat 212 /** 213 * open a group. 214 * 215 * @return the group identifier if successful. 216 */ 217 @Override 218 public long open() { 219 // not supported 220 throw new UnsupportedOperationException("Unsupported operation for NetCDF."); 221 } 222 223 /** 224 * Close a group. 225 * 226 * @param gid 227 * the identifier of the group to close. 228 */ 229 @Override 230 public void close(long gid) { 231 // not supported 232 throw new UnsupportedOperationException("Unsupported operation for NetCDF."); 233 } 234 235 /** 236 * Creates a new group. 237 * 238 * @param name 239 * the name of the group to create. 240 * @param pgroup 241 * the parent group of the new group. 242 * 243 * @return the new group if successful. Otherwise returns null. 244 * 245 * @throws Exception 246 * if there is an error 247 */ 248 public static NC2Group create(String name, Group pgroup) throws Exception { 249 // not supported 250 throw new UnsupportedOperationException("Unsupported operation for NetCDF."); 251 } 252 253 /** 254 * Retrieves the object's metadata, such as attributes, from the file. 255 * 256 * Metadata, such as attributes, is stored in a List. 257 * 258 * @param attrPropList 259 * the list of properties to get 260 * 261 * @return the list of metadata objects. 262 * 263 * @throws Exception 264 * if the metadata can not be retrieved 265 */ 266 @SuppressWarnings("rawtypes") 267 public List getMetadata(int... attrPropList) throws Exception { 268 int hdfType = 0; 269 int attrType = 0; 270 int dimType = 0; 271 int enumType = 0; 272 List returnList = null; 273 274 // use 0 to skip or 1 select in attrPropList to get the list 275 // hdf attributes first netcdf attributes second, dimensions third, enumTypes fourth 276 log.trace("getMetadata(...): attrPropList={}", attrPropList.length); 277 if (attrPropList.length > 0) 278 hdfType = attrPropList[0]; 279 if (attrPropList.length > 1) 280 attrType = attrPropList[1]; 281 if (attrPropList.length > 2) 282 dimType = attrPropList[2]; 283 if (attrPropList.length > 3) 284 enumType = attrPropList[3]; 285 if ((hdfType != 0) && (attributeList != null)) 286 returnList = attributeList; 287 else if ((attrType != 0) && (netcdfAttributeList != null)) 288 returnList = netcdfAttributeList; 289 else if ((dimType != 0) && (netcdfDimensionList != null)) 290 returnList = netcdfDimensionList; 291 else if ((enumType != 0) && (netcdfTypedefList != null)) 292 returnList = netcdfTypedefList; 293 294 return returnList; 295 } 296 297 /** 298 * Retrieves the attribute name. 299 * 300 * @param index 301 * the index of the attribute to get 302 * 303 * @return the attribute string. 304 */ 305 public String netcdfAttributeString(int index) { 306 ucar.nc2.Attribute netcdfAttr = (ucar.nc2.Attribute) netcdfAttributeList.get(index); 307 log.trace("netcdfAttributeString(): netcdfAttribute[{}]:{}", index, netcdfAttr.toString()); 308 String returnStr = netcdfAttr.toString(); 309 return returnStr; 310 } 311 312 /** 313 * Retrieves the Dimension name. 314 * 315 * @param index 316 * the index of the Dimension to get 317 * 318 * @return the Dimension string. 319 */ 320 public String netcdfDimensionString(int index) { 321 ucar.nc2.Dimension netcdfDim = (ucar.nc2.Dimension) netcdfDimensionList.get(index); 322 log.trace("netcdfDimensionString(): netcdfDimension[{}]:{}", index, netcdfDim.toString()); 323 StringBuilder objDimensionStr = new StringBuilder(netcdfDim.getShortName()); 324 if (netcdfDim.isShared()) 325 objDimensionStr.append("[SHARED]"); 326 if (netcdfDim.isUnlimited()) 327 objDimensionStr.append(" = UNLIMITED"); 328 else if (netcdfDim.isVariableLength()) 329 objDimensionStr.append(" = UNKNOWN"); 330 else 331 objDimensionStr.append(" = " + netcdfDim.getLength()); 332 return objDimensionStr.toString(); 333 } 334 335 /** 336 * Retrieves the EnumTypedef name. 337 * 338 * @param index 339 * the index of the EnumTypedef to get 340 * 341 * @return the EnumTypedef string. 342 */ 343 public String netcdfTypedefString(int index) { 344 ucar.nc2.EnumTypedef netcdfType = (ucar.nc2.EnumTypedef) netcdfTypedefList.get(index); 345 log.trace("netcdfEnumTypedefString(): netcdfTypedef[{}]:{}", index, netcdfType.toString()); 346 StringBuilder objEnumTypedefStr = new StringBuilder(netcdfType.getShortName() + " {"); 347 int count = 0; 348 List<Object> keyset = Arrays.asList(netcdfType.getMap().keySet().toArray()); 349 for (Object key : keyset) { 350 String s = netcdfType.getMap().get(key); 351 if (0 < count++) 352 objEnumTypedefStr.append(", "); 353 objEnumTypedefStr.append("'" + s + "' = " + key); 354 } 355 objEnumTypedefStr.append(" }"); 356 return objEnumTypedefStr.toString(); 357 } 358 359}