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