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