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