View Javadoc

1   /*
2    * $Id: LibraryDescriptor.java,v 1.17 2005/06/01 17:47:49 aperezlo Exp $
3    *
4    * Copyright (c) 1999-2004, BBN Technologies, LLC.
5    * All rights reserved.
6    * http://www.daml.org/legal/opensource/bbn_license.html
7    */
8    
9   package com.bbn.swede.core.libraries;
10  
11  import java.io.File;
12  import java.lang.reflect.InvocationTargetException;
13  import java.net.MalformedURLException;
14  import java.net.URL;
15  import java.util.ArrayList;
16  import java.util.Iterator;
17  import java.util.List;
18  import java.util.Properties;
19  
20  import org.eclipse.core.resources.IFile;
21  import org.eclipse.core.resources.IResource;
22  import org.eclipse.core.resources.ResourcesPlugin;
23  import org.eclipse.core.runtime.CoreException;
24  import org.eclipse.core.runtime.IPath;
25  import org.eclipse.core.runtime.IProgressMonitor;
26  import org.eclipse.core.runtime.IStatus;
27  import org.eclipse.core.runtime.MultiStatus;
28  import org.eclipse.core.runtime.Status;
29  import org.eclipse.core.runtime.SubProgressMonitor;
30  import org.eclipse.jface.operation.IRunnableWithProgress;
31  import org.eclipse.ui.actions.WorkspaceModifyDelegatingOperation;
32  
33  import com.bbn.swede.core.OWLCore;
34  import com.bbn.swede.core.dom.IOWLAbstractSyntaxTree;
35  
36  /***
37   * The main interface for client code to manipulate libraries.  This class 
38   * serves in some capacity as a wrapper around the underlying library, and an 
39   * abstraction from it.
40   * 
41   * LibraryDescriptors are intended to be created only by a call to
42   * {@link com.bbn.swede.core.libraries.Library#createDescriptor()}. 
43   * 
44   * @author aperezlo
45   */
46  public class LibraryDescriptor implements ILibraryDescriptor
47  {
48     private Library _library;
49     private List _entries;
50     private LibraryConfiguration _configuration;
51  
52     private LibraryChangeSupport _libraryChangeSupport;
53     
54     /***
55      * File extension for serialized OWL abstract syntax trees.
56      */
57     static final String OAST_EXTENSION = ".oast";
58     /***
59      * File extension for library metadata file.
60      */
61     static final String METADATA_EXTENSION = ".metadata";
62     /***
63      * File extension for entry metadata file.
64      */
65     static final String FILE_EXTENSION = ".entry";
66     
67     /***
68      * Path for library entries.
69      */
70     static final String FILE_PATH = "entry";
71     /***
72      * Path for library metadata.
73      */
74     static final String METADATA_PATH = "metadata";
75     /***
76      * Path for serialized OWL abstract syntax trees.
77      */
78     static final String OAST_PATH = "oast";
79     
80     private boolean _isAvailable = true;
81     
82     /*
83      * @see com.bbn.swede.core.libraries.ILibraryDescriptor#isAvailable()
84      */
85     public boolean isAvailable()
86     {
87        return _isAvailable;
88     }
89     
90     private synchronized void setAvailable(boolean newValue)
91     {
92        _isAvailable = newValue;
93        notifyAll();
94     }
95     
96     /***
97      * Create a new LibraryDescriptor.
98      * 
99      * @param library the library for which this object is a descriptor
100     */
101    LibraryDescriptor(Library library)
102    {
103       _libraryChangeSupport = new LibraryChangeSupport();
104       setLibrary(library);
105    }
106    
107    /*
108     * 
109     * 
110     * @see com.bbn.swede.core.libraries.ILibraryDescriptor#export(org.eclipse.core.runtime.IPath,
111     *      com.bbn.swede.core.libraries.ILibraryEntryDescriptor,
112     *      org.eclipse.core.runtime.IProgressMonitor)
113     */
114    public synchronized IStatus export(IPath exportPath, ILibraryEntryDescriptor iled,
115       IProgressMonitor monitor)
116    {
117       MultiStatus toReturn = new MultiStatus(OWLCore.getID(), IStatus.OK, "Library Export Succeeded.", null);
118       WorkspaceModifyDelegatingOperation wmdo = null;
119 
120       ExportOperation thisOperation = new ExportOperation(exportPath, iled);
121       monitor.beginTask("Exporting...", 100);
122       wmdo = new WorkspaceModifyDelegatingOperation(thisOperation);
123       try
124       {
125          wmdo.run(new SubProgressMonitor(monitor, 100));
126       }
127       catch (InvocationTargetException e)
128       {
129          toReturn.add(new Status(IStatus.ERROR, OWLCore.getID(), IStatus.OK, "Invocation Target Exception", e));
130       }
131       catch (InterruptedException e)
132       {
133          toReturn.add(new Status(IStatus.ERROR, OWLCore.getID(), IStatus.OK, "Interrupted Exception", e));
134       }
135       finally
136       {
137          toReturn.add(thisOperation.getStatus());
138          monitor.done();
139       }
140       return toReturn;
141    }
142 
143    /*
144     * @see com.bbn.swede.core.libraries.ILibraryDescriptor#addLibraryChangeListener(
145     *    com.bbn.swede.core.libraries.ILibraryChangeListener)
146     */
147    public void addLibraryChangeListener(ILibraryChangeListener lcl)
148    {
149       _libraryChangeSupport.addLibraryChangeListener(lcl);
150    }
151    
152    /*
153     * @see com.bbn.swede.core.libraries.ILibraryDescriptor#removeLibraryChangeListener(
154     *    com.bbn.swede.core.libraries.ILibraryChangeListener)
155     */
156    public void removeLibraryChangeListener(ILibraryChangeListener lcl)
157    {
158       _libraryChangeSupport.removeLibraryChangeListener(lcl);
159    }
160    
161    private synchronized void init()
162    {
163       _entries = new ArrayList();
164       _configuration = new LibraryConfiguration();
165       _entries.addAll(_library.getEntries());
166       _configuration.setProperties(_library.getProperties());
167    }
168    
169    /*
170     * @see com.bbn.swede.core.libraries.ILibraryDescriptor#getConfiguration()
171     */
172    public synchronized IConfiguration getConfiguration()
173    {
174       return _configuration;
175    }
176    
177    /*
178     * @see com.bbn.swede.core.libraries.ILibraryDescriptor#delete()
179     */
180    public synchronized void delete()
181    {
182       _libraryChangeSupport.fireLibraryChange(new LibraryChangeEvent(this, LibraryChangeEvent.DELETED));
183    }
184    
185    
186    /***
187     * This method is unsynchronized, whereas getConfiguration() is.  This method will 
188     * return the name of the library, even if it is being refreshed. 
189     * Returns the name of this library.  This call is exactly equivalent to 
190     * the following snippet:
191     * 
192     * <pre>
193     * _configuration.getName();
194     * </pre>
195     * 
196     * @return the name of this library
197     */
198    public String getName()
199    {
200       String toReturn = "";
201       synchronized (_configuration)
202       {
203          toReturn = _configuration.getName(); 
204       }
205       
206       return toReturn;
207    }
208    
209    /*
210     * @see com.bbn.swede.core.libraries.ILibraryDescriptor#writeLibrary(java.lang.String)
211     */
212    public synchronized void writeLibrary(String path)
213    {
214       setAvailable(false);
215       _library.setProperties(_configuration.getProperties());
216       _library.writeLibrary(path + (path.endsWith(File.separator) ? "" : File.separator));
217       setAvailable(true);
218    }
219    
220    /*
221     * @see com.bbn.swede.core.libraries.ILibraryDescriptor#writeLibrary()
222     */
223    public synchronized void writeLibrary()
224    {
225       writeLibrary(Libraries.getLibraryLocationPath());
226    }
227    
228 
229    /*** 
230     * This method returns true if any of the entries in the library are 
231     * marked as being updateable, and false otherwise.
232     * 
233     * 
234     * @return true if this library is updatable, false otherwise
235     */
236    private boolean isRefreshRequired()
237    {
238       List entries = _library.getEntries();
239       Iterator i = entries.iterator();
240       LibraryEntryDescriptor led = null;
241       LibraryEntryConfiguration lec = null;
242       boolean refreshRequired = false;
243       while(i.hasNext())
244       {
245          led = (LibraryEntryDescriptor) i.next();
246          lec = (LibraryEntryConfiguration) led.getConfiguration();
247          if(Boolean.TRUE.toString().equals(lec.getUpdateSchedule()))
248          {
249             refreshRequired = true;
250             break;
251          }
252       }
253       
254       return refreshRequired;
255    }
256    
257    
258    /***
259     * This implementation of the interface encapsulates refresh operations 
260     * in terms of a LibraryEdit object, and calls {@link #edit(LibraryEdit, IProgressMonitor)}.
261     * <br /><br />
262     * This operation supports cancelation.
263     * 
264     * @see com.bbn.swede.core.libraries.ILibraryDescriptor#refresh(org.eclipse.core.runtime.IProgressMonitor)
265     */
266    public synchronized IStatus refresh(IProgressMonitor progress)
267    {
268       setAvailable(false);
269       MultiStatus toReturn = new MultiStatus(OWLCore.getID(), IStatus.OK, "Refresh succeeded...", null);
270       LibraryStructuralCompositeEdit lsce = null;
271       LibraryStructuralEdit lse = null;
272       LibraryEntryDescriptor led = null;
273       LibraryEntryConfiguration lec = null;
274       
275       Iterator i = null;
276       if(isRefreshRequired())
277       {
278          lsce = new LibraryStructuralCompositeEdit(this, new File(Libraries.getLibraryEditPath(getName())));
279          i = _entries.iterator();
280          while(i.hasNext())
281          {
282             led = (LibraryEntryDescriptor) i.next();
283             lec = (LibraryEntryConfiguration) led.getConfiguration();
284             if(Boolean.TRUE.toString().equals(lec.getUpdateSchedule()))
285             {
286                try
287                {
288                   lsce.addEdit(new LibraryStructuralEdit(new URL(lec.getURL()), lec.getName(), LibraryEdit.REFRESH));
289                }
290                catch (MalformedURLException e)
291                {
292                   toReturn.add(new Status(IStatus.ERROR, OWLCore.getID(), IStatus.OK, "Malformed update URL", e));
293                }
294             }
295          }
296          LibraryEdit edit = new LibraryEdit(this);
297          edit.add(lsce);
298          toReturn.add(edit(edit, progress));
299       }
300       if(progress.isCanceled())
301       {
302          toReturn.add(Status.CANCEL_STATUS);
303       }
304       else
305       {
306          _libraryChangeSupport.fireLibraryChange(new LibraryChangeEvent(this,
307             LibraryChangeEvent.REFRESHED & LibraryChangeEvent.CHANGED));         
308       }
309       setAvailable(true);
310       return toReturn;
311    }
312 
313 
314    /*** 
315     * Performs an edit operation, encapsulated in the LibraryEdit 
316     * object upon this library and its descriptor.
317     * <br /> <br />
318     * Here is what actually happens - first, the library becomes unavailable for 
319     * further operations, as ascertainable by a call to {@link #isAvailable()}.  
320     * Next, the files of this descriptor's library are unzipped into a location 
321     * determined by a call to {@link Libraries#getLibraryEditPath(String)}.  
322     * Then edits are performed, first additions and deletions, then configurations.
323     * Finally the library is rebuilt from that directory, and if there were no errors,
324     * it is used as a replacement for the original library.  
325     * <br /> <br />
326     * This operation supports cancelation.
327     * 
328     * @see com.bbn.swede.core.libraries.ILibraryDescriptor#edit(
329     *         com.bbn.swede.core.libraries.LibraryEdit, org.eclipse.core.runtime.IProgressMonitor)
330     */
331    public synchronized IStatus edit(LibraryEdit edit, IProgressMonitor progress)
332    {
333       // steps for refresh - first determine if anything needs to be 
334       // refreshed
335       // if not, end, you're done
336       // otherwise 
337       // make a new refresh-temp directory (ie /.swlib/.tmp/.<library-name>-refresh/)
338       // unzip everything into that directory
339       // download all of the stuff that requires refreshing
340       // reconstitute the .zip file as an .swlib
341       // delete the original, copy the updated one, set the references in 
342       // the 'Descriptor, and fire events as needed.
343       setAvailable(false);
344 
345       MultiStatus toReturn = new MultiStatus(OWLCore.getID(), IStatus.OK, "Edit succeeded...", null);
346       File oldLibraryLocation = new File(Libraries.getLibraryLocationPath() + _library.getFilename());
347       File tempEditDirectory = new File(Libraries.getLibraryEditPath(getName()));
348       File newLibraryLocation = new File(tempEditDirectory, _library.getFilename());
349       
350       progress.beginTask("Editing Library '" + getName() + "'...", _entries.size() * 10);
351       try
352       {
353          if(tempEditDirectory.mkdirs())
354          {
355             _library.unzipAll(tempEditDirectory);
356          }
357          progress.worked(1 * _entries.size());
358          LibraryEntryDescriptor led = null;
359          LibraryEntryConfiguration lec = null;
360          URL downloadURL = null;
361          Iterator i = _library.getEntries().iterator();
362          int numEntries = _library.getEntries().size();
363          
364          toReturn.add(edit.perform(new SubProgressMonitor(progress, 6 * _entries.size())));
365          // rebuild the library based on all the files in the edit directory...
366          if(toReturn.getSeverity() == IStatus.OK)
367          {
368             toReturn.add(_library.rebuild(tempEditDirectory, new SubProgressMonitor(progress, 1 * _entries.size())));
369             _entries.clear();
370             _entries.addAll(_library.getEntries());
371             toReturn.add(edit.configure(new SubProgressMonitor(progress, 2 * _entries.size())));
372             writeLibrary(tempEditDirectory.toString());
373             _library.close();
374             if(toReturn.getSeverity() == IStatus.OK)
375             {
376                oldLibraryLocation.delete();
377                newLibraryLocation.renameTo(oldLibraryLocation);
378                _library = new Library(oldLibraryLocation, this);
379                init();
380             }
381          }
382       }
383       catch(Exception ie)
384       {
385          toReturn.add(new Status(IStatus.WARNING, OWLCore.getID(), IStatus.OK, "Unknown Exception encountered", ie));
386       }
387       finally
388       {
389          if(!progress.isCanceled())
390          {
391             _libraryChangeSupport.fireLibraryChange(new LibraryChangeEvent(this, LibraryChangeEvent.CHANGED));
392          }
393          else
394          {
395             toReturn.add(Status.CANCEL_STATUS);
396          }
397          tempEditDirectory.deleteOnExit();
398          recursiveFileDelete(tempEditDirectory);
399          progress.done();
400       }
401       setAvailable(true);
402       return toReturn;
403    }   
404    /*
405     * @see com.bbn.swede.core.libraries.ILibraryDescriptor#setLibrary(com.bbn.swede.core.libraries.Library)
406     */
407    public synchronized void setLibrary(Library l)
408    {
409       setAvailable(false);
410       boolean alreadyFired = false;
411       close();
412 //      if(l == null)
413 //      {
414 //         System.out.println("LibraryDescriptor.setLibrary: Someone tried to give me a NULL Library!");
415 //      }
416       
417       if(_library != null)
418       {
419          if(!_library.getFilename().equals(l.getFilename()))
420          {
421             _libraryChangeSupport.fireLibraryChange(new LibraryChangeEvent(this, LibraryChangeEvent.RENAMED));
422             alreadyFired = true;
423          }
424       }
425       //TODO: do something?
426 //      if(!alreadyFired)
427 //      {
428 //
429 //      }
430       _library = l;
431       init();
432       setAvailable(true);
433    }
434    
435    /*
436     * @see com.bbn.swede.core.libraries.ILibraryDescriptor#close()
437     */
438    public boolean close()
439    {
440       boolean toReturn = true;
441       ILibraryEntryDescriptor iled = null;
442       Iterator i = null;
443       if(_entries != null)
444       {
445          i = _entries.iterator();
446          while(i.hasNext())
447          {
448             iled = (ILibraryEntryDescriptor) i.next();
449             toReturn = toReturn && iled.close();
450          }
451          
452          toReturn = toReturn && _library.close();
453          
454          if(toReturn)
455          {
456             _libraryChangeSupport.fireLibraryChange(new LibraryChangeEvent(this, LibraryChangeEvent.CLOSED));
457          }
458       }
459       return toReturn;
460    }
461    
462    /***
463     * Retrieves a configuration validator for this library's properties.
464     * @return an instance of  <code>IConfigurationValidator</code>
465     *         capable of validating the properties of this library
466     */
467    public IConfigurationValidator getPropertiesValidator()
468    {
469       IConfigurationValidator toReturn = null;
470       synchronized (_configuration)
471       {
472          toReturn = _configuration.getPropertiesValidator();
473       }
474       return toReturn;
475    }
476    
477    /*
478     * @see com.bbn.swede.core.libraries.ILibraryDescriptor#createEntry(
479     *    java.io.File, java.util.Properties, com.bbn.swede.core.dom.IOWLAbstractSyntaxTree)
480     */
481    public synchronized ILibraryEntryDescriptor createEntry(File file, Properties props, IOWLAbstractSyntaxTree oast)
482    {
483       ILibraryEntry le = new LibraryEntry(_library, file, props, oast);
484       return le.createDescriptor();
485    }
486 
487    
488    /*
489     * @see com.bbn.swede.core.libraries.ILibraryDescriptor#open()
490     */
491    public boolean open()
492    {
493       boolean toReturn = false;
494       
495       
496       
497       if(toReturn)
498       {
499          _libraryChangeSupport.fireLibraryChange(new LibraryChangeEvent(this, LibraryChangeEvent.OPENED));
500       }
501       return toReturn;
502    }
503    
504    
505    /***
506     * Compares library descriptors for equality.
507     * Two LibraryDescriptors are considered to be equal iff:
508     * <ul>
509     * <li>they have the same name</li>
510     * </ul>
511     * 
512     * 
513     * @see java.lang.Object#equals(java.lang.Object)
514     */
515    public boolean equals(Object arg0)
516    {
517       boolean toReturn = false;
518       ILibraryDescriptor ild = null;
519       if(arg0 instanceof ILibraryDescriptor)
520       {
521          ild = (ILibraryDescriptor) arg0;
522     
523          if((this.getName() != null)
524             && (ild.getName() != null)
525             && (this.getName().equals(ild.getName())))
526          {
527             toReturn = true;
528          }
529       }
530       return toReturn;
531    }
532    
533    /*
534     * @see com.bbn.swede.core.libraries.ILibraryDescriptor#addEntry(
535     *    com.bbn.swede.core.libraries.ILibraryEntryDescriptor)
536     */
537    public synchronized void addEntry(ILibraryEntryDescriptor newOne)
538    {
539       _library.addEntry(newOne);
540       _entries.add(newOne);
541    }
542    
543    /*
544     * @see com.bbn.swede.core.libraries.ILibraryDescriptor#removeEntry(
545     *    com.bbn.swede.core.libraries.ILibraryEntryDescriptor)
546     */
547    public synchronized void removeEntry(ILibraryEntryDescriptor toRemove)
548    {
549       _library.removeEntry(toRemove);
550       _entries.remove(toRemove);
551    }
552    
553    /*
554     * @see com.bbn.swede.core.libraries.ILibraryDescriptor#getLibrary()
555     */
556    public synchronized ILibrary getLibrary()
557    {
558       return _library;
559    }
560    /*
561     * @see com.bbn.swede.core.libraries.ILibraryDescriptor#getEntryDescriptors()
562     */
563    public synchronized List getEntryDescriptors()
564    {
565       return _entries;
566    }
567    
568    /*
569     * @see com.bbn.swede.core.libraries.ILibraryDescriptor#contains(java.lang.String)
570     */
571    public synchronized boolean contains(String fileName)
572    {
573       boolean toReturn = false;
574       Iterator i = _entries.iterator();
575       ILibraryEntryDescriptor iled = null;
576       while(i.hasNext())
577       {
578          iled = (ILibraryEntryDescriptor) i.next();
579          if(iled.getConfiguration().getName().equals(fileName))
580          {
581             toReturn = true;
582             break;
583          }
584       }
585       return toReturn;
586    }
587    
588    /*
589     * @see com.bbn.swede.core.libraries.ILibraryDescriptor#containsURI(java.lang.String)
590     */
591    public synchronized boolean containsURI(String sUri)
592    {
593       boolean toReturn = false;
594       Iterator i = _entries.iterator();
595       ILibraryEntryDescriptor iled = null;
596       LibraryEntryConfiguration lec = null;
597       while(i.hasNext())
598       {
599          iled = (LibraryEntryDescriptor) i.next();
600          lec = (LibraryEntryConfiguration) iled.getConfiguration();
601          if(lec.getURI() != null)
602          {
603             if(lec.getURI().equals(sUri))
604             {
605                toReturn = true;
606                break;
607             }
608          }
609       }
610       
611       return toReturn;
612    }
613    /*
614     * @see com.bbn.swede.core.libraries.ILibraryDescriptor#getDescriptorFor(java.lang.String)
615     */
616    public synchronized ILibraryEntryDescriptor getDescriptorFor(String fileName)
617    {
618       ILibraryEntryDescriptor toReturn = null;
619       Iterator i = _entries.iterator();
620       ILibraryEntryDescriptor iled = null;
621       while(i.hasNext())
622       {
623          iled = (ILibraryEntryDescriptor) i.next();
624          if(iled.getConfiguration().getName().equals(fileName))
625          {
626             toReturn = iled;
627             break;
628          }
629       }
630       
631       return toReturn;
632    }
633    
634    /*
635     * @see com.bbn.swede.core.libraries.ILibraryDescriptor#getDescriptorForURI(java.lang.String)
636     */
637    public synchronized ILibraryEntryDescriptor getDescriptorForURI(String sUri)
638    {
639       ILibraryEntryDescriptor toReturn = null;
640       Iterator i = _entries.iterator();
641       ILibraryEntryDescriptor iled = null;
642       LibraryEntryConfiguration lec = null;
643       while(i.hasNext())
644       {
645          iled = (ILibraryEntryDescriptor) i.next();
646          lec = (LibraryEntryConfiguration) iled.getConfiguration();
647          if(lec.getURI() != null)
648          {
649             if(lec.getURI().equals(sUri))
650             {
651                toReturn = iled;
652                break;
653             }
654          }
655       }
656       
657       return toReturn;   
658    }
659    
660    private boolean recursiveFileDelete(File toDelete)
661    {
662       boolean toReturn = true;
663       File[] files = null;
664       if(toDelete.isDirectory())
665       {
666          files = toDelete.listFiles();
667          for(int i = 0; i < files.length; i++)
668          {
669             toReturn = toReturn && recursiveFileDelete(files[i]);
670          }
671       }
672       toReturn = toDelete.delete() && toReturn;
673       return toReturn;
674    }
675    
676    
677    private final class ExportOperation implements IRunnableWithProgress
678    {
679       private IPath _exportPath;
680       private ILibraryEntryDescriptor _iled;
681       private MultiStatus _status;
682       
683       /***
684        * Creates a runnable to export a library entry.
685        * @param exportPath The destination path for the export
686        * @param iled The entry to export
687        */
688       public ExportOperation(IPath exportPath, ILibraryEntryDescriptor iled)
689       {
690          _exportPath = exportPath;
691          _iled = iled;
692          _status = new MultiStatus(OWLCore.getID(), IStatus.OK, "Unzip succeeded", null);
693       }
694 
695       /***
696        * Retrieves the status of the export operation.
697        * @return The status of the completed export operation, or 
698        *         <code>null</code> if the operation has not yet been run.
699        */
700       public IStatus getStatus()
701       {
702          return _status;
703       }
704       
705       /*
706        * @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor)
707        */
708       public void run(IProgressMonitor progress)
709          throws InvocationTargetException, InterruptedException
710       {
711          boolean isFileSystem = false;
712          progress.beginTask("Exporting...", IProgressMonitor.UNKNOWN);
713          IFile iFileAttempt = null;
714          try
715          {
716             iFileAttempt = ResourcesPlugin.getWorkspace().getRoot().getFile(
717                _exportPath.append(_iled.getConfiguration().getName()));
718          }
719          catch(Exception e)
720          {
721             isFileSystem = true;
722          }
723          if(isFileSystem || (iFileAttempt.getRawLocation() == null))
724          {
725             isFileSystem = true;
726             _status.add(_library.unzipOne(_exportPath.toFile(),
727                (LibraryEntryDescriptor)_iled, new SubProgressMonitor(progress,
728                   IProgressMonitor.UNKNOWN)));
729          }
730          else
731          {
732             isFileSystem = false;
733             _status.add(_library.unzipOne(iFileAttempt.getRawLocation()
734                .removeLastSegments(1).toFile(), (LibraryEntryDescriptor)_iled,
735                new SubProgressMonitor(progress, IProgressMonitor.UNKNOWN)));
736          }
737          
738          if(!isFileSystem)
739          {
740             try
741             {
742                iFileAttempt.createLink(iFileAttempt.getRawLocation(),
743                   IResource.NONE, new SubProgressMonitor(progress, 100));
744             }
745             catch (CoreException e)
746             {
747                _status
748                   .add(new Status(IStatus.ERROR, OWLCore.getID(), IStatus.OK,
749                      "Core exception when creating local resource", e));
750             }
751          }
752          progress.done();
753       }
754    }
755    
756 }