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