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.view.MetaDataView;
016
017import hdf.object.FileFormat;
018import hdf.object.Group;
019import hdf.object.HObject;
020import hdf.object.h5.H5Link;
021import hdf.view.DataView.DataViewManager;
022import hdf.view.Tools;
023
024import org.eclipse.swt.SWT;
025import org.eclipse.swt.events.TraverseEvent;
026import org.eclipse.swt.events.TraverseListener;
027import org.eclipse.swt.layout.GridData;
028import org.eclipse.swt.layout.GridLayout;
029import org.eclipse.swt.widgets.Composite;
030import org.eclipse.swt.widgets.Display;
031import org.eclipse.swt.widgets.Event;
032import org.eclipse.swt.widgets.Label;
033import org.eclipse.swt.widgets.Listener;
034import org.eclipse.swt.widgets.Text;
035
036/**
037 *
038 * The metadata view interface for displaying link metadata information
039 */
040public class DefaultLinkMetaDataView extends DefaultBaseMetaDataView implements MetaDataView {
041
042    private static final org.slf4j.Logger log =
043        org.slf4j.LoggerFactory.getLogger(DefaultLinkMetaDataView.class);
044
045    /**
046     *The metadata view interface for displaying link metadata information
047     *
048     * @param parentComposite
049     *        the parent visual object
050     * @param viewer
051     *        the viewer to use
052     * @param theObj
053     *        the object to display the metadata info
054     */
055    public DefaultLinkMetaDataView(Composite parentComposite, DataViewManager viewer, HObject theObj)
056    {
057        super(parentComposite, viewer, theObj);
058    }
059
060    @Override
061    protected void addObjectSpecificContent()
062    {
063        /* For HDF5 links, add a box to allow changing of the link target */
064        if (dataObject.getLinkTargetObjName() != null) {
065            org.eclipse.swt.widgets.Group linkTargetGroup =
066                new org.eclipse.swt.widgets.Group(generalObjectInfoPane, SWT.NONE);
067            linkTargetGroup.setFont(curFont);
068            linkTargetGroup.setText("Link Target Info");
069            linkTargetGroup.setLayout(new GridLayout(2, false));
070
071            /*
072             * If this object is purely a link, meaning a soft/external/other link that does
073             * not point to an existing object, allow the Link Target Info Group to take up
074             * all the available vertical space in the MetaDataView.
075             *
076             * Otherwise, if this link points to an existing object, it will not be an
077             * instanceof H5Link. Rather, it will be an instanceof Dataset, instanceof
078             * Group, etc. and will contain the information necessary to determine that the
079             * object is really a link.
080             *
081             * In this case, we don't allow the Link Target Info Group to take up all the
082             * available vertical space, in order to allow other object Metadata information
083             * to be comfortable displayed in the MetaDataView.
084             */
085            if (dataObject instanceof H5Link)
086                linkTargetGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
087            else
088                linkTargetGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
089
090            Label label = new Label(linkTargetGroup, SWT.LEFT);
091            label.setFont(curFont);
092            label.setText("Link To Target: ");
093
094            final Text linkTarget = new Text(linkTargetGroup, SWT.SINGLE | SWT.BORDER | SWT.H_SCROLL);
095            linkTarget.setFont(curFont);
096            linkTarget.setText(dataObject.getLinkTargetObjName());
097            linkTarget.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
098            linkTarget.addTraverseListener(new TraverseListener() {
099                @Override
100                public void keyTraversed(TraverseEvent e)
101                {
102                    if (e.detail == SWT.TRAVERSE_RETURN) {
103                        changeLinkTarget(linkTarget.getText());
104                    }
105                }
106            });
107            linkTarget.addListener(SWT.FocusOut, new Listener() {
108                @Override
109                public void handleEvent(Event arg0)
110                {
111                    changeLinkTarget(linkTarget.getText());
112                }
113            });
114        }
115    }
116
117    private void changeLinkTarget(String linkTargetName)
118    {
119        Group pgroup = null;
120        try {
121            pgroup = (Group)dataObject.getFileFormat().get(dataObject.getPath());
122        }
123        catch (Exception ex) {
124            log.debug("addObjectSpecificContent(): parent group get failure:", ex);
125        }
126
127        if (pgroup == null) {
128            log.debug("addObjectSpecificContent(): parent group is null");
129            display.beep();
130            Tools.showError(display.getShells()[0], "Select",
131                            "Parent group is null.\nLink target change failed.");
132            return;
133        }
134
135        if (linkTargetName != null)
136            linkTargetName = linkTargetName.trim();
137
138        int linkType = Group.LINK_TYPE_SOFT;
139        if (dataObject.getLinkTargetObjName().contains(FileFormat.FILE_OBJ_SEP))
140            linkType = Group.LINK_TYPE_EXTERNAL;
141        else if ((linkTargetName != null) &&
142                 (linkTargetName.equals("/"))) { // do not allow to link to the root
143            display.beep();
144            Tools.showError(display.getShells()[0], "Select",
145                            "Link to root not allowed.\nLink target change failed.");
146            return;
147        }
148
149        // no change
150        if ((linkTargetName != null) && (linkTargetName.equals(dataObject.getLinkTargetObjName())))
151            return;
152
153        // invalid name
154        if (linkTargetName == null || linkTargetName.length() < 1)
155            return;
156
157        try {
158            dataObject.getFileFormat().createLink(pgroup, dataObject.getName(), linkTargetName, linkType);
159            dataObject.setLinkTargetObjName(linkTargetName);
160        }
161        catch (Exception ex) {
162            log.debug("addObjectSpecificContent(): createLink() failure:", ex);
163            display.beep();
164            Tools.showError(display.getShells()[0], "Select", "Link target change failed." + ex.getMessage());
165            return;
166        }
167
168        Tools.showInformation(display.getShells()[0], "Link target changed.",
169                              "Reload file to display changes.");
170    }
171}