6

保存アクションにフックして、goolgeクロージャコンパイラで縮小されたjavascriptファイルを作成するEclipseプラグインを作成しました。以下のファイルを参照してください。それは日食3.7.2まで機能しました。残念ながら、現在Eclipse 4.2.1では、これにより無限ループが発生することがあるようです。ジョブ「compile.min.js」(ResourceChangedListener.javaの64行目)が原因のようです。その結果、workspacedが何度もビルドを開始する場合があります。これは、そのジョブがワークスペースビルドを再度トリガーするファイルを作成または変更し、ビルドをトリガーするジョブなどを再度トリガーするためだと思います。しかし、これを防ぐ方法がわかりません。

// 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();
    }

}
4

1 に答える 1

3

空のEclipseクラシック環境をセットアップした後、そこで新しいEclipseプラグインプロジェクトを開始し、部分的に再び機能するすべてのファイルを再作成しました。この環境でデバッグ セッションを開始すると、.js ファイルを保存でき、.min.js ファイルが自動的に作成されます。ここまでは順調ですね!しかし、プラグインを実際の開発中のEclipse環境にインストールすると、自動保存が機能しません。

せめてあと一歩!

ステップ 2: マニフェストなど、明らかに必要なビルドに含まれていないファイルがいくつかありました。なぜ彼らが選ばれなかったのか分かりません。とにかく、空のEclipse 4クラシックをセットアップし、Eclipseプラグインウィザードを実行するだけで、元の問題が解決したようです。私はまだ実際の問題が何であったか知りたいです...

于 2013-03-11T17:38:16.923 に答える