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