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