    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    private static final long serialVersionUID = -1261533010442193447L;
    038
    039    private static final org.slf4j.Logger   log = org.slf4j.LoggerFactory.getLogger(NC2Group.class);
    040
    041    /**
    042     * The corresponding netcdf Group for this group.
    043     */
    044    protected ucar.nc2.Group netCDFGroup;
    045
    046    public ucar.nc2.Group getNetCDFGroup() {
    047        return netCDFGroup;
    048    }
    049
    050    public void setNetCDFGroup(ucar.nc2.Group netCDFGroup) {
    051        this.netCDFGroup = netCDFGroup;
    052    }
    053
    054    /**
    055     * The list of attributes of this data object. Members of the list are
    056     * instance of Attribute.
    057     */
    058    private List attributeList;
    059
    060    /**
    061     * The list of netcdf typedefs, dimensions and attributes of this data object. Members of the list are
    062     * instance of ucar.nc2.*.
    063     */
    064    private List netcdfTypedefList;
    065    private List netcdfDimensionList;
    066    private List netcdfAttributeList;
    067
    068    /** The default object ID for NC2 objects */
    069    private static final long[] DEFAULT_OID = { 0 };
    070
    071    /**
    072     * Constructs an NC2 group with specific name, path, and parent.
    073     *
    074     * @param fileFormat
    075     *            the file which containing the group.
    076     * @param name
    077     *            the name of this group.
    078     * @param path
    079     *            the full path of this group.
    080     * @param parent
    081     *            the parent of this group.
    082     * @param theID
    083     *            the unique identifier of this data object.
    084     */
    085    public NC2Group(FileFormat fileFormat, String name, String path, Group parent, long[] theID) {
    086        super(fileFormat, name, path, parent, ((theID == null) ? DEFAULT_OID : theID));
    087        ucar.nc2.Group parentGroup = null;
    088        if (parent != null)
    089            parentGroup = ((NC2Group)parent).getNetCDFGroup();
    090        netCDFGroup = new ucar.nc2.Group(((NC2File)fileFormat).getNetcdfFile(), parentGroup, name);
    091        log.trace("NC2Group:{}", name);
    092    }
    093
    094    /*
    095     * (non-Javadoc)
    096     *
    097     * @see hdf.object.DataFormat#hasAttribute()
    098     */
    099    public boolean hasAttribute() {
    100        return false;
    101    }
    102
    103    public boolean hasDimension() {
    104        return false;
    105    }
    106
    107    // Implementing DataFormat
    108    @SuppressWarnings("rawtypes")
    109    public List getMetadata() throws Exception {
    110        if (attributeList != null) {
    111            return attributeList;
    112        }
    113
    114        NC2File theFile = (NC2File)getFileFormat();
    115        NetcdfFile ncFile = theFile.getNetcdfFile();
    116        if (!isRoot() && (netCDFGroup !=null)) {
    117            netcdfDimensionList = netCDFGroup.getDimensions();
    118
    119            netcdfTypedefList = netCDFGroup.getEnumTypedefs();
    120
    121            netcdfAttributeList = netCDFGroup.getAttributes();
    122        }
    123        else {
    124            netcdfDimensionList = ncFile.getDimensions();
    125
    126            netcdfAttributeList = ncFile.getGlobalAttributes();
    127        }
    128        if (netcdfAttributeList == null) {
    129            attributeList = null;
    130        }
    131        else {
    132            int n = netcdfAttributeList.size();
    133            log.trace("Attribute size:{}", n);
    134            attributeList = new Vector(n);
    135
    136            ucar.nc2.Attribute netcdfAttr = null;
    137            for (int i = 0; i < n; i++) {
    138                netcdfAttr = (ucar.nc2.Attribute) netcdfAttributeList.get(i);
    139                log.trace("getMetadata(): Attribute[{}]:{}", i, netcdfAttr.toString());
    140                attributeList.add(NC2File.convertAttribute(this, netcdfAttr));
    141            }
    142        }
    143        return attributeList;
    144    }
    145
    146    /**
    147     * Creates a new attribute and attached to this dataset if attribute does
    148     * not exist. Otherwise, just update the value of the attribute.
    149     *
    150     * @param info
    151     *            the atribute to attach
    152     *
    153     * @throws Exception
    154     *            if there is an error
    155     */
    156    public void writeMetadata(Object info) throws Exception {
    157        // not supported
    158        throw new UnsupportedOperationException("Unsupported operation for NetCDF.");
    159    }
    160
    161    /**
    162     * Deletes an attribute from this dataset.
    163     *
    164     * @param info
    165     *            the attribute to delete.
    166     *
    167     * @throws Exception
    168     *            if there is an error
    169     */
    170    public void removeMetadata(Object info) throws Exception {
    171        // not supported
    172        throw new UnsupportedOperationException("Unsupported operation for NetCDF.");
    173    }
    174
    175    // implementing DataFormat
    176    public void updateMetadata(Object info) throws Exception {
    177        // not supported
    178        throw new UnsupportedOperationException("Unsupported operation for NetCDF.");
    179    }
    180
    181    // Implementing DataFormat
    182    @Override
    183    public long open() {
    184        // not supported
    185        throw new UnsupportedOperationException("Unsupported operation for NetCDF.");
    186    }
    187
    188    /* close group access */
    189    @Override
    190    public void close(long gid) {
    191        // not supported
    192        throw new UnsupportedOperationException("Unsupported operation for NetCDF.");
    193    }
    194
    195    /**
    196     * Creates a new group.
    197     *
    198     * @param name
    199     *            the name of the group to create.
    200     * @param pgroup
    201     *            the parent group of the new group.
    202     *
    203     * @return the new group if successful. Otherwise returns null.
    204     *
    205     * @throws Exception
    206     *            if there is an error
    207     */
    208    public static NC2Group create(String name, Group pgroup) throws Exception {
    209        // not supported
    210        throw new UnsupportedOperationException("Unsupported operation for NetCDF.");
    211    }
    212
    213    // overload to get different lists
    214    @SuppressWarnings("rawtypes")
    215    public List getMetadata(int... attrPropList) throws Exception {
    216        int hdfType = 0;
    217        int attrType = 0;
    218        int dimType = 0;
    219        int enumType = 0;
    220        List returnList = null;
    221
    222        // use 0 to skip or 1 select in attrPropList to get the list
    223        // hdf attributes first netcdf attributes second, dimensions third, enumTypes fourth
    224        log.trace("getMetadata(...): attrPropList={}", attrPropList.length);
    225        if (attrPropList.length > 0) {
    226            hdfType = attrPropList[0];
    227        }
    228        if (attrPropList.length > 1) {
    229            attrType = attrPropList[1];
    230        }
    231        if (attrPropList.length > 2) {
    232            dimType = attrPropList[2];
    233        }
    234        if (attrPropList.length > 3) {
    235            enumType = attrPropList[3];
    236        }
    237        if ((hdfType != 0) && (attributeList != null)) {
    238            returnList = attributeList;
    239        }
    240        else if ((attrType != 0) && (netcdfAttributeList != null)) {
    241            returnList = netcdfAttributeList;
    242        }
    243        else if ((dimType != 0) && (netcdfDimensionList != null)) {
    244            returnList = netcdfDimensionList;
    245        }
    246        else if ((enumType != 0) && (netcdfTypedefList != null)) {
    247            returnList = netcdfTypedefList;
    248        }
    249
    250        return returnList;
    251    }
    252
    253    public String netcdfAttributeString(int index) {
    254        ucar.nc2.Attribute netcdfAttr = (ucar.nc2.Attribute) netcdfAttributeList.get(index);
    255        log.trace("netcdfAttributeString(): netcdfAttribute[{}]:{}", index, netcdfAttr.toString());
    256        String returnStr = netcdfAttr.toString();
    257        return returnStr;
    258    }
    259
    260    public String netcdfDimensionString(int index) {
    261        ucar.nc2.Dimension netcdfDim = (ucar.nc2.Dimension) netcdfDimensionList.get(index);
    262        log.trace("netcdfDimensionString(): netcdfDimension[{}]:{}", index, netcdfDim.toString());
    263        StringBuilder objDimensionStr = new StringBuilder(netcdfDim.getShortName());
    264        if (netcdfDim.isShared())
    265            objDimensionStr.append("[SHARED]");
    266        if (netcdfDim.isUnlimited())
    267            objDimensionStr.append(" = UNLIMITED");
    268          else if (netcdfDim.isVariableLength())
    269              objDimensionStr.append(" = UNKNOWN");
    270          else
    271              objDimensionStr.append(" = " + netcdfDim.getLength());
    272        return objDimensionStr.toString();
    273    }
    274
    275    public String netcdfTypedefString(int index) {
    276        ucar.nc2.EnumTypedef netcdfType = (ucar.nc2.EnumTypedef) netcdfTypedefList.get(index);
    277        log.trace("netcdfEnumTypedefString(): netcdfTypedef[{}]:{}", index, netcdfType.toString());
    278        StringBuilder objEnumTypedefStr = new StringBuilder(netcdfType.getShortName() + " {");
    279        int count = 0;
    280        List<Object> keyset = Arrays.asList(netcdfType.getMap().keySet().toArray());
    281        for (Object key : keyset) {
    282          String s = netcdfType.getMap().get(key);
    283          if (0 < count++)
    284              objEnumTypedefStr.append(", ");
    285          objEnumTypedefStr.append("'" + s + "' = " + key);
    286        }
    287        objEnumTypedefStr.append(" }");
    288        return objEnumTypedefStr.toString();
    289    }
    290
    291}