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