    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.dialog;
    016
    017import java.io.File;
    018import java.util.ArrayList;
    019import java.util.Iterator;
    020import java.util.LinkedList;
    021import java.util.List;
    022import java.util.Queue;
    023import java.util.Vector;
    024
    025import org.slf4j.Logger;
    026import org.slf4j.LoggerFactory;
    027
    028import org.eclipse.swt.SWT;
    029import org.eclipse.swt.custom.CCombo;
    030import org.eclipse.swt.events.DisposeEvent;
    031import org.eclipse.swt.events.DisposeListener;
    032import org.eclipse.swt.events.SelectionAdapter;
    033import org.eclipse.swt.events.SelectionEvent;
    034import org.eclipse.swt.events.TraverseEvent;
    035import org.eclipse.swt.events.TraverseListener;
    036import org.eclipse.swt.graphics.Font;
    037import org.eclipse.swt.graphics.Point;
    038import org.eclipse.swt.graphics.Rectangle;
    039import org.eclipse.swt.layout.GridData;
    040import org.eclipse.swt.layout.GridLayout;
    041import org.eclipse.swt.widgets.Button;
    042import org.eclipse.swt.widgets.Combo;
    043import org.eclipse.swt.widgets.Composite;
    044import org.eclipse.swt.widgets.Dialog;
    045import org.eclipse.swt.widgets.Display;
    046import org.eclipse.swt.widgets.FileDialog;
    047import org.eclipse.swt.widgets.Label;
    048import org.eclipse.swt.widgets.Shell;
    049import org.eclipse.swt.widgets.Text;
    050
    051import hdf.hdf5lib.H5;
    052import hdf.object.FileFormat;
    053import hdf.object.Group;
    054import hdf.object.HObject;
    055import hdf.view.DefaultFileFilter;
    056import hdf.view.Tools;
    057import hdf.view.ViewProperties;
    058
    059/**
    060 * NewLinkDialog shows a message dialog requesting user input for creating
    061 * new links.
    062 *
    063 * @author Jordan T. Henderson
    064 * @version 2.4 1/1/2016
    065 */
    066public class NewLinkDialog extends Dialog {
    067
    068    private static final Logger log = LoggerFactory.getLogger(NewLinkDialog.class);
    069
    070    private Shell         shell;
    071
    072    private Font          curFont;
    073
    074    private Text          nameField;
    075
    076    private Combo         parentChoice;
    077
    078    private CCombo        targetObject;
    079
    080    private String        currentDir;
    081
    082    private Text          targetFile;
    083
    084    private Button        targetFileButton;
    085
    086    private Button        hardLink, softLink, externalLink;
    087
    088    /** a list of current groups */
    089    private List<Group>   groupList;
    090
    091    /** a list of current objects */
    092    private List<?>       objList;
    093
    094    private HObject       newObject;
    095    private Group         parentGroup;
    096
    097    private FileFormat    fileFormat;
    098
    099    private final List<?> fileList;
    100
    101    /**
    102     * Constructs a NewLinkDialog with specified list of possible parent groups.
    103     *
    104     * @param parent
    105     *            the parent shell of the dialog
    106     * @param pGroup
    107     *            the parent group which the new group is added to.
    108     * @param objs
    109     *            the list of all objects.
    110     * @param files
    111     *            the list of all files open in the TreeView
    112     */
    113    public NewLinkDialog(Shell parent, Group pGroup, List<?> objs, List<FileFormat> files) {
    114        super(parent, SWT.APPLICATION_MODAL);
    115
    116        try {
    117            curFont = new Font(
    118                    Display.getCurrent(),
    119                    ViewProperties.getFontType(),
    120                    ViewProperties.getFontSize(),
    121                    SWT.NORMAL);
    122        }
    123        catch (Exception ex) {
    124            curFont = null;
    125        }
    126
    127        newObject = null;
    128        parentGroup = pGroup;
    129        objList = objs;
    130
    131        fileFormat = pGroup.getFileFormat();
    132        currentDir = ViewProperties.getWorkDir();
    133        fileList = files;
    134    }
    135
    136    /**
    137     * Open the NewLinkDialog for adding a new link.
    138     */
    139    public void open() {
    140        Shell parent = getParent();
    141        shell = new Shell(parent, SWT.SHELL_TRIM | SWT.APPLICATION_MODAL);
    142        shell.setFont(curFont);
    143        shell.setText("New Link...");
    144        shell.setImages(ViewProperties.getHdfIcons());
    145        shell.setLayout(new GridLayout(1, true));
    146
    147        // Create the main content region
    148        Composite content = new Composite(shell, SWT.NONE);
    149        content.setLayout(new GridLayout(2, false));
    150        content.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
    151
    152        Label label = new Label(content, SWT.LEFT);
    153        label.setFont(curFont);
    154        label.setText("Link name: ");
    155
    156        nameField = new Text(content, SWT.SINGLE | SWT.BORDER);
    157        nameField.setFont(curFont);
    158        GridData fieldData = new GridData(SWT.FILL, SWT.FILL, true, false);
    159        fieldData.minimumWidth = 300;
    160        nameField.setLayoutData(fieldData);
    161
    162        label = new Label(content, SWT.LEFT);
    163        label.setFont(curFont);
    164        label.setText("Parent group: ");
    165
    166        parentChoice = new Combo(content, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY);
    167        parentChoice.setFont(curFont);
    168        parentChoice.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    169        parentChoice.addSelectionListener(new SelectionAdapter() {
    170            @Override
    171            public void widgetSelected(SelectionEvent e) {
    172                parentGroup = groupList.get(parentChoice.getSelectionIndex());
    173            }
    174        });
    175
    176        Composite helpComposite = new Composite(content, SWT.NONE);
    177        helpComposite.setLayout(new GridLayout(1, true));
    178        helpComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    179
    180        label = new Label(helpComposite, SWT.LEFT);
    181        label.setFont(curFont);
    182        label.setText("Type of Link: ");
    183
    184        Button helpButton = new Button(helpComposite, SWT.PUSH);
    185        helpButton.setImage(ViewProperties.getHelpIcon());
    186        helpButton.setToolTipText("Help on Links");
    187        helpButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    188        helpButton.addSelectionListener(new SelectionAdapter() {
    189            @Override
    190            public void widgetSelected(SelectionEvent e) {
    191                final String msg = "The Type of Link specifies which type of link the user wants to create. \n"
    192                        + "It could be hard, soft or external links. \n\n"
    193                        + "Hard Link: \n"
    194                        + "Hard Link creates a hard link to a pre-existing object in an HDF5 file. \n"
    195                        + "The target object must already exist in the file.\n"
    196                        + "The HDF5 library keeps a count of all hard links pointing to an object. \n\n"
    197                        + "Soft Link: \n"
    198                        + "Soft Link creates a new soft link to an object in an HDF5 file. \n"
    199                        + "Soft links are only for use only if the target object is in the current file. \n"
    200                        + "Unlike hard links, a soft link in an HDF5 file is allowed to dangle, \n"
    201                        + "meaning that the target object need not exist at the time that the link is created.\n"
    202                        + "The HDF5 library does not keep a count of soft links.  \n\n"
    203                        + "External Link: \n"
    204                        + "External Link creates a new soft link to an external object, which is an \n"
    205                        + "object in a different HDF5 file from the location of the link. \n"
    206                        + "External links are allowed to dangle like soft links. \n\n"
    207                        + "Soft links and external links are also known as symbolic links as they use "
    208                        + "a name to point to an object; hard links employ an object's address in the file.  \n\n\n";
    209
    210                Tools.showInformation(shell, "Help", msg);
    211            }
    212        });
    213
    214        Composite typeComposite = new Composite(content, SWT.BORDER);
    215        typeComposite.setLayout(new GridLayout(3, true));
    216        typeComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    217
    218        hardLink = new Button(typeComposite, SWT.RADIO);
    219        hardLink.setFont(curFont);
    220        hardLink.setText("Hard Link");
    221        hardLink.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, true, false));
    222        hardLink.addSelectionListener(new SelectionAdapter() {
    223            @Override
    224            public void widgetSelected(SelectionEvent e) {
    225                targetFile.setEnabled(false);
    226                targetFileButton.setEnabled(false);
    227                targetObject.setEnabled(true);
    228                targetObject.setEditable(false);
    229                targetObject.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW));
    230
    231                targetObject.removeAll();
    232                retrieveObjects(fileFormat);
    233
    234                targetObject.select(0);
    235            }
    236        });
    237
    238        softLink = new Button(typeComposite, SWT.RADIO);
    239        softLink.setFont(curFont);
    240        softLink.setText("Soft Link");
    241        softLink.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, true, false));
    242        softLink.addSelectionListener(new SelectionAdapter() {
    243            @Override
    244            public void widgetSelected(SelectionEvent e) {
    245                targetFile.setEnabled(false);
    246                targetFileButton.setEnabled(false);
    247                targetObject.setEnabled(true);
    248                targetObject.setEditable(true);
    249                targetObject.setBackground(null);
    250
    251                targetObject.removeAll();
    252                retrieveObjects(fileFormat);
    253
    254                targetObject.select(0);
    255            }
    256        });
    257
    258        externalLink = new Button(typeComposite, SWT.RADIO);
    259        externalLink.setFont(curFont);
    260        externalLink.setText("External Link");
    261        externalLink.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, true, false));
    262        externalLink.addSelectionListener(new SelectionAdapter() {
    263            @Override
    264            public void widgetSelected(SelectionEvent e) {
    265                targetFile.setEnabled(true);
    266                targetFileButton.setEnabled(true);
    267                targetObject.setEnabled(true);
    268                targetObject.setEditable(true);
    269                targetObject.setBackground(null);
    270                targetObject.removeAll();
    271            }
    272        });
    273
    274        label = new Label(content, SWT.LEFT);
    275        label.setFont(curFont);
    276        label.setText("Target File: ");
    277
    278        Composite fileComposite = new Composite(content, SWT.NONE);
    279        GridLayout layout = new GridLayout(2, false);
    280        layout.horizontalSpacing = 0;
    281        layout.marginHeight = 0;
    282        layout.marginWidth = 0;
    283        fileComposite.setLayout(layout);
    284        fileComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    285
    286        targetFile = new Text(fileComposite, SWT.SINGLE | SWT.BORDER);
    287        targetFile.setFont(curFont);
    288        targetFile.setEnabled(false);
    289        targetFile.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
    290        targetFile.addTraverseListener(new TraverseListener() {
    291            @Override
    292            public void keyTraversed(TraverseEvent e) {
    293                if (e.detail == SWT.TRAVERSE_RETURN) {
    294                    String filename = targetFile.getText();
    295
    296                    if (filename == null || filename.length() <= 0) return;
    297
    298                    File chosenFile = new File(filename);
    299
    300                    if (!chosenFile.exists()) {
    301                        return;
    302                    }
    303
    304                    if (chosenFile.isDirectory()) {
    305                        currentDir = chosenFile.getPath();
    306                    }
    307                    else {
    308                        currentDir = chosenFile.getParent();
    309                    }
    310
    311                    //Check if the target File is not the current file.
    312                    String currentFileName = fileFormat.getAbsolutePath();
    313                    if(currentFileName.equals(chosenFile.getAbsolutePath())) {
    314                        Tools.showError(shell, "Traverse",
    315                                "Please select a file other than the current file for external links.");
    316                        targetFile.setText("");
    317                        return;
    318                    }
    319
    320                    getTargetFileObjs();
    321
    322                    if(targetObject.getItemCount() > 0) targetObject.select(0);
    323                }
    324            }
    325        });
    326
    327        targetFileButton = new Button(fileComposite, SWT.PUSH);
    328        targetFileButton.setFont(curFont);
    329        targetFileButton.setText("Browse...");
    330        targetFileButton.setEnabled(false);
    331        targetFileButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
    332        targetFileButton.addSelectionListener(new SelectionAdapter() {
    333            @Override
    334            public void widgetSelected(SelectionEvent e) {
    335                String filename = null;
    336                filename = openTargetFile();
    337
    338                if (filename == null) {
    339                    return;
    340                }
    341
    342                targetFile.setText(filename);
    343                getTargetFileObjs();
    344
    345                if(targetObject.getItemCount() > 0) targetObject.select(0);
    346            }
    347        });
    348
    349        label = new Label(content, SWT.LEFT);
    350        label.setFont(curFont);
    351        label.setText("Target Object: ");
    352
    353        targetObject = new CCombo(content, SWT.DROP_DOWN | SWT.BORDER);
    354        targetObject.setFont(curFont);
    355        targetObject.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    356        targetObject.setEditable(false);
    357        targetObject.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW));
    358
    359        groupList = new ArrayList<>(objList.size());
    360        Object obj = null;
    361        Iterator<?> iterator = objList.iterator();
    362        String fullName = null;
    363        int idx_root = -1, idx = -1;
    364        while (iterator.hasNext()) {
    365            obj = iterator.next();
    366            idx++;
    367
    368            if (obj instanceof Group) {
    369                Group g = (Group) obj;
    370                groupList.add(g);
    371                if (g.isRoot()) {
    372                    fullName = HObject.SEPARATOR;
    373                    idx_root = idx;
    374                }
    375                else {
    376                    fullName = g.getPath() + g.getName() + HObject.SEPARATOR;
    377                }
    378                parentChoice.add(fullName);
    379            }
    380            else {
    381                fullName = ((HObject) obj).getPath() + ((HObject) obj).getName();
    382            }
    383
    384            targetObject.add(fullName);
    385        }
    386
    387        targetObject.remove(idx_root);
    388        objList.remove(idx_root);
    389
    390        if (parentGroup.isRoot()) {
    391            parentChoice.select(parentChoice.indexOf(HObject.SEPARATOR));
    392        }
    393        else {
    394            parentChoice.select(parentChoice.indexOf(parentGroup.getPath() + parentGroup.getName()
    395                    + HObject.SEPARATOR));
    396        }
    397
    398        // Dummy label to take up space as dialog is resized
    399        label = new Label(content, SWT.LEFT);
    400        label.setFont(curFont);
    401        label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
    402
    403
    404        // Create the Ok/Cancel button region
    405        Composite buttonComposite = new Composite(shell, SWT.NONE);
    406        buttonComposite.setLayout(new GridLayout(2, true));
    407        buttonComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    408
    409        Button okButton = new Button(buttonComposite, SWT.PUSH);
    410        okButton.setFont(curFont);
    411        okButton.setText("   &OK   ");
    412        okButton.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false));
    413        okButton.addSelectionListener(new SelectionAdapter() {
    414            @Override
    415            public void widgetSelected(SelectionEvent e) {
    416                newObject = createLink();
    417
    418                if (newObject != null) {
    419                    shell.dispose();
    420                }
    421            }
    422        });
    423
    424        Button cancelButton = new Button(buttonComposite, SWT.PUSH);
    425        cancelButton.setFont(curFont);
    426        cancelButton.setText(" &Cancel ");
    427        cancelButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.FILL, true, false));
    428        cancelButton.addSelectionListener(new SelectionAdapter() {
    429            @Override
    430            public void widgetSelected(SelectionEvent e) {
    431                newObject = null;
    432                shell.dispose();
    433                ((Vector<Group>) groupList).setSize(0);
    434            }
    435        });
    436
    437        hardLink.setSelection(true);
    438        targetObject.select(0);
    439
    440        shell.pack();
    441
    442        shell.addDisposeListener(new DisposeListener() {
    443            @Override
    444            public void widgetDisposed(DisposeEvent e) {
    445                if (curFont != null) curFont.dispose();
    446            }
    447        });
    448
    449        shell.setMinimumSize(shell.computeSize(SWT.DEFAULT, SWT.DEFAULT));
    450
    451        Rectangle parentBounds = parent.getBounds();
    452        Point shellSize = shell.getSize();
    453        shell.setLocation((parentBounds.x + (parentBounds.width / 2)) - (shellSize.x / 2),
    454                          (parentBounds.y + (parentBounds.height / 2)) - (shellSize.y / 2));
    455
    456        shell.open();
    457
    458        Display display = shell.getDisplay();
    459        while (!shell.isDisposed())
    460            if (!display.readAndDispatch())
    461                display.sleep();
    462    }
    463
    464    private HObject createLink() {
    465        String name = null;
    466        Group pgroup = null;
    467        HObject obj = null;
    468
    469        name = nameField.getText().trim();
    470        if ((name == null) || (name.length() < 1)) {
    471            shell.getDisplay().beep();
    472            Tools.showError(shell, "Create", "Link name is not specified.");
    473            return null;
    474        }
    475
    476        if (name.indexOf(HObject.SEPARATOR) >= 0) {
    477            shell.getDisplay().beep();
    478            Tools.showError(shell, "Create", "Link name cannot contain path.");
    479            return null;
    480        }
    481
    482        pgroup = groupList.get(parentChoice.getSelectionIndex());
    483
    484        if (pgroup == null) {
    485            shell.getDisplay().beep();
    486            Tools.showError(shell, "Create", "Parent group is null.");
    487            return null;
    488        }
    489
    490        if (hardLink.getSelection()) {
    491            HObject targetObj = (HObject) objList.get(targetObject
    492                    .getSelectionIndex());
    493
    494            if (targetObj == null) {
    495                shell.getDisplay().beep();
    496                Tools.showError(shell, "Create", "Target object is null.");
    497                return null;
    498            }
    499
    500            if ((targetObj instanceof Group) && ((Group) targetObj).isRoot()) {
    501                shell.getDisplay().beep();
    502                Tools.showError(shell, "Create", "Cannot make a link to the root group.");
    503                return null;
    504            }
    505
    506            try {
    507                obj = fileFormat.createLink(pgroup, name, targetObj);
    508            }
    509            catch (Exception ex) {
    510                shell.getDisplay().beep();
    511                Tools.showError(shell, "Create", ex.getMessage());
    512                return null;
    513            }
    514        }
    515        else if (softLink.getSelection()){
    516            String target_name = targetObject.getText();
    517            if (target_name.length() < 1)  {
    518                shell.getDisplay().beep();
    519                Tools.showError(shell, "Create", "Target object name is not specified.");
    520                return null;
    521            }
    522
    523            /*
    524             * While checking for the existence of the object that the soft link points to,
    525             * the following function currently just calls H5Oopen, which will fail and
    526             * throw an HDF5 error stack for dangling soft links. Due to this, we
    527             * temporarily suppress the HDF5 error stack.
    528             */
    529            HObject targetObj = null;
    530            try {
    531                H5.H5error_off();
    532                targetObj = fileFormat.get(target_name);
    533            }
    534            catch (Exception ex) {
    535                /* It is possible that this is a soft link to a non-existent
    536                 * object, in which case this exception would be normal.
    537                 * For this reason, no logging is done here even though there
    538                 * is the possibility of a real HDF5 exception being thrown
    539                 * if something went terribly wrong.
    540                 */
    541            }
    542            finally {
    543                H5.H5error_on();
    544            }
    545
    546            String tObj = null;
    547            if (targetObj == null) {
    548                tObj = target_name;
    549
    550                if (!tObj.startsWith(HObject.SEPARATOR)) {
    551                    tObj = HObject.SEPARATOR + tObj;
    552                }
    553            }
    554
    555            if ((targetObj instanceof Group) && ((Group) targetObj).isRoot()) {
    556                shell.getDisplay().beep();
    557                Tools.showError(shell, "Create", "Cannot make a link to the root group.");
    558                return null;
    559            }
    560
    561            try {
    562                if (targetObj != null)
    563                    obj = fileFormat.createLink(pgroup, name, targetObj, Group.LINK_TYPE_SOFT);
    564                else if (tObj != null)
    565                    obj = fileFormat.createLink(pgroup, name, tObj, Group.LINK_TYPE_SOFT);
    566            }
    567            catch (Exception ex) {
    568                ex.printStackTrace();
    569                shell.getDisplay().beep();
    570                Tools.showError(shell, "Create", ex.getMessage());
    571                return null;
    572            }
    573        }
    574        else if (externalLink.getSelection()){
    575            String TargetFileName = targetFile.getText();
    576            FileFormat TargetFileFormat = null;
    577            int fileAccessID = FileFormat.FILE_CREATE_OPEN;
    578
    579            File TargetFile = new File(TargetFileName);
    580
    581            if (!TargetFile.exists()) {
    582                return null;
    583            }
    584            FileFormat h5format = FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5);
    585            try {
    586                TargetFileFormat = h5format.createInstance(TargetFileName, fileAccessID);
    587                TargetFileFormat.open(); //open the file
    588            }
    589            catch (Exception ex) {
    590                log.debug("external link:", ex);
    591                return null;
    592            }
    593
    594            HObject targetObj = null;
    595            try{
    596                targetObj = TargetFileFormat.get(targetObject.getText());
    597            }
    598            catch (Exception ex) {
    599                ex.printStackTrace();
    600            }
    601
    602            try {
    603                TargetFileFormat.close();
    604            }
    605            catch (Exception ex) {
    606                log.debug("external link:", ex);
    607            }
    608
    609            String tFileObj = null;
    610            if(targetObj==null){
    611                String tObj = null;
    612                tObj = targetObject.getText();
    613                if (tObj.length() < 1)  {
    614                    shell.getDisplay().beep();
    615                    Tools.showError(shell, "Create", "Target object name not specified.");
    616                    return null;
    617                }
    618                tFileObj = TargetFileName + FileFormat.FILE_OBJ_SEP + tObj;
    619            }
    620
    621            try {
    622                if(targetObj !=null)
    623                    obj = fileFormat.createLink(pgroup, name, targetObj, Group.LINK_TYPE_EXTERNAL);
    624                else if(tFileObj!=null)
    625                    obj = fileFormat.createLink(pgroup, name, tFileObj, Group.LINK_TYPE_EXTERNAL);
    626            }
    627            catch (Exception ex) {
    628                ex.printStackTrace();
    629                shell.getDisplay().beep();
    630                Tools.showError(shell, "Create", ex.getMessage());
    631                return null;
    632            }
    633        }
    634
    635        return obj;
    636    }
    637
    638    private String openTargetFile() {
    639        FileDialog fchooser = new FileDialog(shell, SWT.OPEN);
    640        fchooser.setFilterPath(currentDir);
    641
    642        DefaultFileFilter filter = DefaultFileFilter.getFileFilter();
    643        fchooser.setFilterExtensions(new String[] {"*", filter.getExtensions()});
    644        fchooser.setFilterNames(new String[] {"All Files", filter.getDescription()});
    645        fchooser.setFilterIndex(1);
    646
    647        if(fchooser.open() == null) return null;
    648
    649        File chosenFile = new File(fchooser.getFilterPath() + File.separator + fchooser.getFileName());
    650
    651        if (!chosenFile.exists()) {
    652            return null;
    653        }
    654
    655        if (chosenFile.isDirectory()) {
    656            currentDir = chosenFile.getPath();
    657        }
    658        else {
    659            currentDir = chosenFile.getParent();
    660        }
    661
    662        //Check if the target File is not the current file.
    663        String currentFileName = fileFormat.getAbsolutePath();
    664        if(currentFileName.equals(chosenFile.getAbsolutePath())) {
    665            Tools.showError(shell, "Open", "Please select a file other than the current file for external links.");
    666            targetFile.setText("");
    667            return null;
    668        }
    669
    670        return chosenFile.getAbsolutePath();
    671    }
    672
    673    //Function to check if the target File is open in TreeView
    674    private boolean isFileOpen(String filename)
    675    {
    676        boolean isOpen = false;
    677        FileFormat theFile = null;
    678
    679        Iterator<?> iterator = fileList.iterator();
    680        while(iterator.hasNext()) {
    681            theFile = (FileFormat)iterator.next();
    682            if (theFile.getFilePath().equals(filename)) {
    683                isOpen = true;
    684                if(!theFile.isThisType(FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5))){
    685                    targetObject.setEnabled(false);
    686                }
    687                retrieveObjects(theFile);
    688                break;
    689            }
    690        }
    691
    692        return isOpen;
    693    }
    694
    695    private List<HObject> getAllUserObjectsBreadthFirst(FileFormat file) {
    696        if (file == null) return null;
    697
    698        ArrayList<HObject> breadthFirstObjects = new ArrayList<>();
    699        Queue<HObject> currentChildren = new LinkedList<>();
    700        HObject currentObject = file.getRootObject();
    701
    702        if (currentObject == null) {
    703            log.debug("getAllUserObjectsBreadthFirst(): file root object is null");
    704            return null;
    705        }
    706
    707        breadthFirstObjects.add(file.getRootObject()); // Add the root object to the list first
    708
    709        // Add all root object children to a Queue
    710        currentChildren.addAll(((Group) currentObject).getMemberList());
    711
    712        while(!currentChildren.isEmpty()) {
    713            currentObject = currentChildren.remove();
    714            breadthFirstObjects.add(currentObject);
    715
    716            if(currentObject instanceof Group) {
    717                if(((Group) currentObject).getNumberOfMembersInFile() <= 0) continue;
    718
    719                currentChildren.addAll(((Group) currentObject).getMemberList());
    720            }
    721        }
    722
    723        return breadthFirstObjects;
    724    }
    725
    726    // Retrieves the list of objects from the file
    727    private void retrieveObjects(FileFormat file) {
    728        HObject obj = null;
    729        List<HObject> userObjectList = getAllUserObjectsBreadthFirst(file);
    730        Iterator<HObject> iterator;
    731        String fullName = null;
    732
    733        if (userObjectList == null) {
    734            log.debug("retrieveObjects(): user object list is null");
    735            return;
    736        }
    737
    738        iterator = userObjectList.iterator();
    739        while (iterator.hasNext()) {
    740            obj = iterator.next();
    741
    742            if (obj instanceof Group) {
    743                Group g = (Group) obj;
    744                if (g.isRoot()) {
    745                    fullName = HObject.SEPARATOR;
    746                }
    747                else {
    748                    fullName = g.getPath() + g.getName() + HObject.SEPARATOR;
    749                }
    750            }
    751            else {
    752                fullName = obj.getPath() + obj.getName();
    753            }
    754
    755            targetObject.add(fullName);
    756        }
    757
    758        // Remove the root group "/" from the target objects
    759        targetObject.remove(0);
    760    }
    761
    762    // Retrieves objects from Target File.
    763    private void getTargetFileObjs(){
    764        FileFormat fileFormatC = null;
    765        int fileAccessID = FileFormat.FILE_CREATE_OPEN;
    766        String filename = null;
    767        filename = targetFile.getText();
    768
    769        if (filename == null || filename.length()<1) {
    770            return;
    771        }
    772
    773        // Check if the target File is open in treeView
    774        if (isFileOpen(filename)) {
    775            return;
    776        }
    777
    778        File chosenFile = new File(filename);
    779
    780        if (!chosenFile.exists()) {
    781            targetObject.setEnabled(false);
    782            return;
    783        }
    784
    785        FileFormat h5format = FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5);
    786        try {
    787            fileFormatC = h5format.createInstance(filename, fileAccessID);
    788            fileFormatC.open(); //open the file
    789        }
    790        catch (Exception ex) {
    791            shell.getDisplay().beep();
    792            Tools.showError(shell, "Target", "Invalid File Format");
    793            targetFile.setText("");
    794            return;
    795        }
    796
    797        // get the list of objects from the file
    798        retrieveObjects(fileFormatC);
    799
    800        try {
    801            fileFormatC.close();
    802        }
    803        catch (Exception ex) {
    804            log.debug("FileFormat close:", ex);
    805        }
    806    }
    807
    808    /** @return the new dataset created. */
    809    public HObject getObject() {
    810        return newObject;
    811    }
    812
    813    /** @return the parent group of the new dataset. */
    814    public Group getParentGroup() {
    815        return parentGroup;
    816    }
    817}