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