2013-03-01 33 views
6

Kaza kapatma derleyicisiyle minimize edilmiş bir javascript dosyası oluşturmak için kaydetme eylemine girecek bir tutulması gereken eklenti oluşturdum. Aşağıdaki dosyalara bakın. Tutuluncaya kadar çalıştı 3.7.2. Ne yazık ki şimdi tutulma 4.2.1'de, bu bazen bir sonsuz döngü yaratıyor gibi görünüyor. "Compile .min.js" işi (ResourceChangedListener.java'daki 64 satır) işin nedeni gibi görünüyor. İşlerin tekrar tekrar inşa edilmeye başlamasıyla sonuçlanır. Bunun nedeni, bu işin, çalışma alanı oluşturmayı yeniden başlatan bir dosyayı oluşturması veya değiştirmesidir. Bu da, yapıyı tetikleyen işi tekrar tetikler. Ama bunu nasıl önleyeceğimi anlayamıyorum.eclipse eklentisi, güncellemeden sonra çalışmaz (eclipse 4)

// Activator.java

package closure_compiler_save; 

import org.eclipse.core.resources.ResourcesPlugin; 
import org.eclipse.ui.plugin.AbstractUIPlugin; 
import org.osgi.framework.BundleContext; 

/** 
* The activator class controls the plug-in life cycle 
*/ 
public class Activator extends AbstractUIPlugin { 

    // The plug-in ID 
    public static final String PLUGIN_ID = "closure-compiler-save"; //$NON-NLS-1$ 

    // The shared instance 
    private static Activator plugin; 

    /** 
    * The constructor 
    */ 
    public Activator() { 
    } 

    @Override 
     public void start(BundleContext context) throws Exception { 
     super.start(context); 
     Activator.plugin = this; 

     ResourceChangedListener listener = new ResourceChangedListener(); 
      ResourcesPlugin.getWorkspace().addResourceChangeListener(listener); 
    } 

    @Override 
     public void stop(BundleContext context) throws Exception { 
     Activator.plugin = null; 
     super.stop(context); 
    } 

    /** 
    * Returns the shared instance 
    * 
    * @return the shared instance 
    */ 
    public static Activator getDefault() { 
     return plugin; 
    } 
} 

// ResourceChangedListener.java

package closure_compiler_save; 

import java.io.ByteArrayInputStream; 
import java.io.IOException; 
import java.io.InputStream; 

import org.eclipse.core.resources.IFile; 
import org.eclipse.core.resources.IProject; 
import org.eclipse.core.resources.IResource; 
import org.eclipse.core.resources.IResourceChangeEvent; 
import org.eclipse.core.resources.IResourceChangeListener; 
import org.eclipse.core.resources.IResourceDelta; 
import org.eclipse.core.runtime.CoreException; 
import org.eclipse.core.runtime.IPath; 
import org.eclipse.core.runtime.IProgressMonitor; 
import org.eclipse.core.runtime.IStatus; 
import org.eclipse.core.runtime.Status; 
import org.eclipse.core.runtime.jobs.Job; 

public class ResourceChangedListener implements IResourceChangeListener { 

    public void resourceChanged(IResourceChangeEvent event) { 
     if (event.getType() != IResourceChangeEvent.POST_CHANGE) 
      return; 

     IResourceDelta delta = event.getDelta(); 
     try { 
      processDelta(delta); 
     } catch (CoreException e) { 
      e.printStackTrace(); 
     } 
    } 

    // find out which class files were just built 
    private void processDelta(IResourceDelta delta) throws CoreException { 

     IResourceDelta[] kids = delta.getAffectedChildren(); 
     for (IResourceDelta delta2 : kids) { 
      if (delta2.getAffectedChildren().length == 0) { 
       if (delta.getKind() != IResourceDelta.CHANGED) 
        return; 

       IResource res = delta2.getResource(); 
       if (res.getType() == IResource.FILE && "js".equalsIgnoreCase(res.getFileExtension())) { 
        if (res.getName().contains("min")) 
         return; 
        compile(res); 
       } 
      } 
      processDelta(delta2); 
     } 
    } 

    private void compile(final IResource res) throws CoreException { 

     final IPath fullPath = res.getFullPath(); 
     final IPath fullLocation = res.getLocation(); 
     final String fileName = fullPath.lastSegment().toString(); 
     final String outputFilename = fileName.substring(0, fileName.lastIndexOf(".")).concat(".min.js"); 
     final String outputPath = fullPath.removeFirstSegments(1).removeLastSegments(1).toString(); 

     final IProject project = res.getProject(); 
     final IFile newFile = project.getFile(outputPath.concat("/".concat(outputFilename))); 
     Job compileJob = new Job("Compile .min.js") { 
      public IStatus run(IProgressMonitor monitor) { 
       byte[] bytes = null; 
       try { 
        bytes = CallCompiler.compile(fullLocation.toString(), CallCompiler.SIMPLE_OPTIMIZATION).getBytes(); 

        InputStream source = new ByteArrayInputStream(bytes); 
        if (!newFile.exists()) { 
         newFile.create(source, IResource.NONE, null); 
        } else { 
         newFile.setContents(source, IResource.NONE, null); 
        } 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } catch (CoreException e) { 
        e.printStackTrace(); 
       } 
       return Status.OK_STATUS; 
      } 
     }; 
     compileJob.setRule(newFile.getProject()); // this will ensure that no two jobs are writing simultaneously on the same file 
     compileJob.schedule(); 
    } 

} 

cevap

3

Ben kurulum boş Tutulma klasik çevre sonra orada yeni bir Tutulma eklenti projesini başlatan ve işe yarıyor tüm dosyaları yeniden yine kısmen. Bu ortamda bir hata ayıklama oturumu başlatarak .js dosyaları kaydedebilir ve .min.js dosyaları otomatik olarak oluşturulur. Şimdiye kadar çok iyi! Ancak eklentiyi gerçek gelişmekte olan eclipse ortamıma yüklediğimde otomatik kaydetme çalışmaz.

En az bir adım daha!

Adım 2: Açıkça gerekli olan, manifest gibi yapıya dahil olmayan bazı dosyalar vardı. Neden seçilmedikleri konusunda bir fikir yok. Her neyse sadece boş bir tutulma 4 klasik kurma ve tutulması eklentisi sihirbazı geçiyor orijinal sorunumu düzeltmek gibi görünüyor. Hala asıl sorunun ne olduğunu bilmek isterim ...

+0

CallCompiler nereden geliyor? Bu Eclipse eklenti klasörüne dahil ettiğiniz 3. parti bir kavanozdan belki bir/lib dir içinde mi? Eğer yapmış olsaydınız, 3. parti kavanozun Manifest.mf çalışma zamanı yolunda olduğundan (manifest.mf editöründe düzenlenmiş) olduğundan emin olun ve ayrıca bin.includes dosyasında 3. parti kavanozunu içerdiğinden emin olun. . – gamerson

+0

CallCompiler kendi sınıfım, söz konusu dosya için kapatma derleyicisini çağırır. Bu sınıftaki mantık işe yarıyor. Aynı CallCompiler sınıfına sahip bir dosya için küçültme işlemini tetikleyen bir açılır menüye de sahibim. Sadece otomatik kaydetme işlemi artık çalışmayacak. – DarsVaeda

+0

Garip, bu yüzden çalışma alanınızda/çalışma zamanı çalışma tezgahında çalışır, ancak tek başına yüklemeyi değil. Bunu defalarca gördüm. Koduna bakarak res.getLocation() çağrısına dikkat edin. Bazı durumlarda bu dönüşü null olarak gördüm. Tek önerim, sürümlerin sürüm ve sürüm arasında ne olduğunu görmek için derleme() yönteminiz için daha fazla hata ayıklama çıkışı eklemektir. – gamerson