Author: dsavage
Date: Sat Sep 11 05:29:15 2010
New Revision: 996072

URL: http://svn.apache.org/viewvc?rev=996072&view=rev
Log:
patch to store classpath results between restarts to aid performance 
(FELIX-2595)

Modified:
    
felix/trunk/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/internal/classpath/SigilClassPathContainer.java
    
felix/trunk/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/internal/classpath/SigilClasspathContainerInitializer.java

Modified: 
felix/trunk/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/internal/classpath/SigilClassPathContainer.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/internal/classpath/SigilClassPathContainer.java?rev=996072&r1=996071&r2=996072&view=diff
==============================================================================
--- 
felix/trunk/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/internal/classpath/SigilClassPathContainer.java
 (original)
+++ 
felix/trunk/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/internal/classpath/SigilClassPathContainer.java
 Sat Sep 11 05:29:15 2010
@@ -19,15 +19,24 @@
 
 package org.apache.felix.sigil.eclipse.ui.internal.classpath;
 
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.apache.felix.sigil.eclipse.job.ThreadProgressMonitor;
 import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
+import org.apache.felix.sigil.eclipse.ui.SigilUI;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.Path;
 import org.eclipse.jdt.core.IClasspathContainer;
 import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
 
 /**
  * @author dave
@@ -36,9 +45,13 @@ import org.eclipse.jdt.core.IClasspathEn
 public class SigilClassPathContainer implements IClasspathContainer
 {
 
-    private IClasspathEntry[] entries;
-    private ISigilProjectModel sigil;
+    private static final String CLASSPATH = "classpath";
+    private static final String EMPTY = "empty";
 
+    private IClasspathEntry[] entries;
+    
+    private final ISigilProjectModel sigil;
+    
     public SigilClassPathContainer(ISigilProjectModel sigil)
     {
         this.sigil = sigil;
@@ -90,9 +103,15 @@ public class SigilClassPathContainer imp
     {
         try
         {
-            IProgressMonitor monitor = 
ThreadProgressMonitor.getProgressMonitor();
             if (sigil.exists()) {
-                entries = sigil.findExternalClasspath(monitor).toArray(new 
IClasspathEntry[0]);
+                entries = getCachedClassPath(sigil);
+                
+                if ( entries == null ) {
+                    IProgressMonitor monitor = 
ThreadProgressMonitor.getProgressMonitor();
+                    entries = sigil.findExternalClasspath(monitor).toArray(new 
IClasspathEntry[0]);
+                    
+                    cacheClassPath(sigil, entries);
+                }
             }
         }
         catch (CoreException e)
@@ -107,4 +126,146 @@ public class SigilClassPathContainer imp
             }
         }
     }
+    
+    static IClasspathEntry[] getCachedClassPath(ISigilProjectModel project) {
+        File f = getClassPathDir(project);
+        if ( f == null || !f.exists() ) return null;
+        
+        File[] entries = f.listFiles();
+        if ( entries == null || entries.length == 0 ) return null;
+        
+        ArrayList<IClasspathEntry> list = new 
ArrayList<IClasspathEntry>(entries.length);
+        for(File entry : entries ) {
+            if ( EMPTY.equals(entry.getName() ) ) {
+                list.clear();
+                break;
+            }
+            else {
+                try
+                {
+                    list.add(readClassPath(project.getJavaModel(), entry));
+                }
+                catch (IOException e)
+                {
+                    SigilCore.warn("Failed to read classpath entry " + entry, 
e);
+                }
+            }
+        }
+        return list.toArray(new IClasspathEntry[list.size()]);
+    }
+
+    private static File getClassPathDir(ISigilProjectModel project)
+    {
+        IPath loc = project.getProject().getWorkingLocation(SigilUI.PLUGIN_ID);
+        
+        if ( loc == null ) return null;
+        
+        loc = loc.append(CLASSPATH);
+        
+        return new File(loc.toOSString());
+    }
+
+    static void cacheClassPath(ISigilProjectModel project, IClasspathEntry[] 
entries)
+    {
+        File f = getClassPathDir(project);
+        
+        if ( f == null ) return;
+        
+        if ( !f.exists() ) {
+            if (!f.mkdirs()) {
+                SigilCore.warn("Failed to create temp working directory " + f);
+                return;
+            }
+        }
+        
+        try
+        {
+            if (entries.length == 0)
+            {
+                File empty = new File(f, EMPTY);
+                empty.createNewFile();
+            }
+            else {
+                int i = 0;
+                for(IClasspathEntry e : entries) {
+                    File entry = new File(f, Integer.toString(i++));
+                    writeClassPath(project.getJavaModel(), entry, e);
+                }
+            }
+        }
+        catch (IOException e)
+        {
+            SigilCore.warn("Failed to read write classpath entries", e);
+        }
+    }
+
+    /**
+     * @param sigil
+     */
+    static void flushCachedClassPath(ISigilProjectModel project)
+    {
+        File f = getClassPathDir(project);
+        
+        if ( f == null || !f.exists() ) return;
+        
+        File[] files = f.listFiles();
+        if ( files == null ) return;
+        
+        for (File entry : files) {
+            entry.delete();
+        }
+    }
+    
+    private static IClasspathEntry readClassPath(IJavaProject javaModel, File 
entry) throws IOException
+    {
+        FileInputStream in = new FileInputStream(entry);
+        
+        try
+        {
+            ByteArrayOutputStream buf = new ByteArrayOutputStream();
+            
+            byte[] b = new byte[1024];
+            
+            for(;;) {
+                int r = in.read(b);
+                if ( r == -1 ) break;
+                buf.write(b, 0, r);
+            }
+            
+            String enc = buf.toString();
+            return javaModel.decodeClasspathEntry(enc);
+        }
+        finally
+        {
+            try
+            {
+                in.close();
+            }
+            catch (IOException e)
+            {
+                SigilCore.warn("Failed to close stream to " + entry, e);
+            }
+        }
+    }
+
+    private static void writeClassPath(IJavaProject javaModel, File file, 
IClasspathEntry entry) throws IOException 
+    {
+        String enc = javaModel.encodeClasspathEntry(entry);
+        FileOutputStream out = new FileOutputStream(file);
+        try {
+            out.write(enc.getBytes());
+            out.flush();
+        }
+        finally {
+            try
+            {
+                out.close();
+            }
+            catch (IOException e)
+            {
+                SigilCore.warn("Failed to close stream to " + entry, e);
+            }            
+        }
+    }
+    
 }

Modified: 
felix/trunk/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/internal/classpath/SigilClasspathContainerInitializer.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/internal/classpath/SigilClasspathContainerInitializer.java?rev=996072&r1=996071&r2=996072&view=diff
==============================================================================
--- 
felix/trunk/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/internal/classpath/SigilClasspathContainerInitializer.java
 (original)
+++ 
felix/trunk/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/internal/classpath/SigilClasspathContainerInitializer.java
 Sat Sep 11 05:29:15 2010
@@ -46,6 +46,8 @@ public class SigilClasspathContainerInit
         throws CoreException
     {
         ISigilProjectModel sigil = SigilCore.create(project.getProject());
+        
+        SigilClassPathContainer.flushCachedClassPath(sigil);
 
         IClasspathContainer sigilContainer = new 
SigilClassPathContainer(sigil);
 
@@ -53,15 +55,24 @@ public class SigilClasspathContainerInit
 
         IClasspathContainer[] respectiveContainers = new IClasspathContainer[] 
{ sigilContainer };
 
+        
+        JavaCore.setClasspathContainer(containerPath, affectedProjects,
+            respectiveContainers, getMonitor());
+    }
+
+    /**
+     * @return
+     */
+    private IProgressMonitor getMonitor()
+    {
         IProgressMonitor monitor = ThreadProgressMonitor.getProgressMonitor();
 
         if (monitor == null)
         {
             monitor = Job.getJobManager().createProgressGroup();
         }
-
-        JavaCore.setClasspathContainer(containerPath, affectedProjects,
-            respectiveContainers, monitor);
+        
+        return monitor;
     }
 
     @Override
@@ -76,10 +87,7 @@ public class SigilClasspathContainerInit
 
         IClasspathContainer[] respectiveContainers = new IClasspathContainer[] 
{ sigilContainer };
 
-        IProgressMonitor monitor = Job.getJobManager().createProgressGroup();
-
         JavaCore.setClasspathContainer(containerPath, affectedProjects,
-            respectiveContainers, monitor);
+            respectiveContainers, getMonitor());
     }
-
 }


Reply via email to