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}