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