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.h5;
016
017import java.util.List;
018
019import hdf.hdf5lib.H5;
020import hdf.hdf5lib.HDF5Constants;
021import hdf.hdf5lib.HDFArray;
022import hdf.hdf5lib.HDFNativeData;
023import hdf.hdf5lib.exceptions.HDF5Exception;
024import hdf.hdf5lib.structs.H5O_info_t;
025import hdf.hdf5lib.structs.H5O_token_t;
026
027import hdf.object.Attribute;
028import hdf.object.FileFormat;
029import hdf.object.HObject;
030import hdf.object.MetaDataContainer;
031
032/**
033 * An H5Link object represents an existing HDF5 object in file.
034 *
035 * H5Link object is an HDF5 object that is either a soft or an external link to
036 * an object in a file that does not exist. The type of the object is unknown.
037 * Once the object being linked to is created, and the type is known, then
038 * H5link object will change its type.
039 *
040 * @version 2.7.2 7/6/2010
041 * @author Nidhi Gupta
042 */
043
044public class H5Link extends HObject implements MetaDataContainer
045{
046    private static final long serialVersionUID = -8137277460521594367L;
047
048    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(H5Link.class);
049
050    /** the object properties */
051    private H5O_info_t objInfo;
052
053    /**
054     * Constructs an HDF5 link with specific name, path, and parent.
055     *
056     * @param theFile
057     *            the file which containing the link.
058     * @param theName
059     *            the name of this link, e.g. "link1".
060     * @param thePath
061     *            the full path of this link, e.g. "/groups/".
062     */
063    public H5Link(FileFormat theFile, String theName, String thePath) {
064        this(theFile, theName, thePath, null);
065    }
066
067    /**
068     * Constructs an HDF5 link with specific name, path, parent and oid.
069     *
070     * @param theFile
071     *            the file which containing the link.
072     * @param theName
073     *            the name of this link, e.g. "link1".
074     * @param thePath
075     *            the full path of this link, e.g. "/groups/".
076     * @param oid
077     *            the oid of this link, e.g. "/groups/".
078     */
079    @SuppressWarnings("deprecation")
080    public H5Link(FileFormat theFile, String theName, String thePath, long[] oid) {
081        super(theFile, theName, thePath, oid);
082
083        if (theFile != null) {
084            if (oid == null) {
085                // retrieve the object ID
086                byte[] refBuf = null;
087                try {
088                    refBuf = H5.H5Rcreate_object(theFile.getFID(), this.getFullName(), HDF5Constants.H5P_DEFAULT);
089                    this.oid = HDFNativeData.byteToLong(refBuf);
090                    log.trace("constructor REF {} to OID {}", refBuf, this.oid);
091                }
092                catch (Exception ex) {
093                    log.debug("constructor ID {} for {} failed H5Rcreate_object", theFile.getFID(), this.getFullName());
094                }
095                finally {
096                    if (refBuf != null)
097                        H5.H5Rdestroy(refBuf);
098                }
099            }
100            log.trace("constructor OID {}", this.oid);
101            try {
102                objInfo = H5.H5Oget_info_by_name(theFile.getFID(), this.getFullName(), HDF5Constants.H5O_INFO_BASIC, HDF5Constants.H5P_DEFAULT);
103            }
104            catch (Exception ex) {
105                objInfo = new H5O_info_t(-1L, null, 0, 0, 0L, 0L, 0L, 0L, 0L);
106            }
107        }
108        else {
109            this.oid = null;
110            objInfo = new H5O_info_t(-1L, null, 0, 0, 0L, 0L, 0L, 0L, 0L);
111        }
112    }
113
114    /*
115     * (non-Javadoc)
116     *
117     * @see hdf.object.HObject#open()
118     */
119    @Override
120    public long open() {
121        return 0;
122    }
123
124    /*
125     * (non-Javadoc)
126     *
127     * @see hdf.object.HObject#close(int)
128     */
129    @Override
130    public void close(long id) {
131    }
132
133    /**
134     * Get the token for this object.
135     *
136     * @return true if it has any attributes, false otherwise.
137     */
138    public long[] getToken() {
139        H5O_token_t token = objInfo.token;
140        return HDFNativeData.byteToLong(token.data);
141    }
142
143    /**
144     * Check if the object has any attributes attached.
145     *
146     * @return true if it has any attributes, false otherwise.
147     */
148    @Override
149    public boolean hasAttribute() {
150        return false;
151    }
152
153    /**
154     * Removes all of the elements from metadata list.
155     * The list should be empty after this call returns.
156     */
157    @Override
158    public void clear() {
159    }
160
161    /**
162     * Retrieves the object's metadata, such as attributes, from the file.
163     *
164     * Metadata, such as attributes, is stored in a List.
165     *
166     * @return the list of metadata objects.
167     *
168     * @throws HDF5Exception
169     *             if the metadata can not be retrieved
170     */
171    @Override
172    public List<Attribute> getMetadata() throws HDF5Exception {
173        try {
174            this.linkTargetObjName = H5File.getLinkTargetName(this);
175        }
176        catch (Exception ex) {
177            log.debug("getMetadata(): getLinkTargetName failed: ", ex);
178        }
179
180        return null;
181    }
182
183    /**
184     * Retrieves the object's metadata, such as attributes, from the file.
185     *
186     * Metadata, such as attributes, is stored in a List.
187     *
188     * @param attrPropList
189     *             the list of properties to get
190     *
191     * @return the list of metadata objects.
192     *
193     * @throws HDF5Exception
194     *             if the metadata can not be retrieved
195     */
196    public List<Attribute> getMetadata(int... attrPropList) throws HDF5Exception {
197        try {
198            this.linkTargetObjName = H5File.getLinkTargetName(this);
199        }
200        catch (Exception ex) {
201            log.debug("getMetadata(): getLinkTargetName failed: ", ex);
202        }
203
204        return null;
205    }
206
207    /**
208     * Writes a specific piece of metadata (such as an attribute) into the file.
209     *
210     * If an HDF(4&amp;5) attribute exists in the file, this method updates its
211     * value. If the attribute does not exist in the file, it creates the
212     * attribute in the file and attaches it to the object. It will fail to
213     * write a new attribute to the object where an attribute with the same name
214     * already exists. To update the value of an existing attribute in the file,
215     * one needs to get the instance of the attribute by getMetadata(), change
216     * its values, then use writeMetadata() to write the value.
217     *
218     * @param info
219     *            the metadata to write.
220     *
221     * @throws Exception
222     *             if the metadata can not be written
223     */
224    @Override
225    public void writeMetadata(Object info) throws Exception {
226    }
227
228    /**
229     * Deletes an existing piece of metadata from this object.
230     *
231     * @param info
232     *            the metadata to delete.
233     *
234     * @throws HDF5Exception
235     *             if the metadata can not be removed
236     */
237    @Override
238    public void removeMetadata(Object info) throws HDF5Exception {
239    }
240
241    /**
242     * Updates an existing piece of metadata attached to this object.
243     *
244     * @param info
245     *            the metadata to update.
246     *
247     * @throws HDF5Exception
248     *             if the metadata can not be updated
249     */
250    @Override
251    public void updateMetadata(Object info) throws HDF5Exception {
252    }
253
254    /*
255     * (non-Javadoc)
256     *
257     * @see hdf.object.HObject#setName(java.lang.String)
258     */
259    @Override
260    public void setName(String newName) throws Exception {
261        if (newName == null)
262            throw new IllegalArgumentException("The new name is NULL");
263
264        H5File.renameObject(this, newName);
265        super.setName(newName);
266    }
267}