net.sf.eclipsensis.util.NSISCompileTestUtility.java Source code

Java tutorial

Introduction

Here is the source code for net.sf.eclipsensis.util.NSISCompileTestUtility.java

Source

/*******************************************************************************
 * Copyright (c) 2004-2010 Sunil Kamath (IcemanK).
 * All rights reserved.
 * This program is made available under the terms of the Common Public License
 * v1.0 which is available at http://www.eclipse.org/legal/cpl-v10.html
 *
 * Contributors:
 *     Sunil Kamath (IcemanK) - initial API and implementation
 *******************************************************************************/
package net.sf.eclipsensis.util;

import java.io.*;
import java.util.*;
import java.util.List;
import java.util.regex.Pattern;

import net.sf.eclipsensis.*;
import net.sf.eclipsensis.console.*;
import net.sf.eclipsensis.editor.NSISEditorUtilities;
import net.sf.eclipsensis.makensis.*;
import net.sf.eclipsensis.settings.*;

import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.jface.dialogs.*;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.*;

public class NSISCompileTestUtility {
    public static final NSISCompileTestUtility INSTANCE = new NSISCompileTestUtility();

    private static final long cEclipseStartTime = Long
            .parseLong(System.getProperty("eclipse.startTime", String.valueOf(System.currentTimeMillis()))); //$NON-NLS-1$

    private NSISHeaderAssociationManager mHeaderAssociationManager = NSISHeaderAssociationManager.getInstance();
    private Map<File, MakeNSISResults> mResultsMap;
    private Pattern mNSISExtPattern = Pattern.compile(INSISConstants.NSI_WILDCARD_EXTENSION,
            Pattern.CASE_INSENSITIVE);

    private NSISCompileTestUtility() {
        File stateLocation = EclipseNSISPlugin.getPluginStateLocation();
        final File resultsCacheFile = new File(stateLocation, getClass().getName() + ".ResultsCache.ser"); //$NON-NLS-1$
        EclipseNSISPlugin.getDefault().registerService(new IEclipseNSISService() {
            private boolean mStarted = false;

            public boolean isStarted() {
                return mStarted;
            }

            @SuppressWarnings("unchecked")
            private Map<File, MakeNSISResults> loadMap(File file) {
                Map<File, MakeNSISResults> map = null;
                if (IOUtility.isValidFile(file)) {
                    Object obj = null;
                    try {
                        obj = IOUtility.readObject(file);
                    } catch (Exception e) {
                        obj = null;
                        EclipseNSISPlugin.getDefault().log(e);
                    }
                    if (obj != null && Map.class.isAssignableFrom(obj.getClass())) {
                        map = (Map<File, MakeNSISResults>) obj;
                    }
                }
                if (map == null) {
                    map = new MRUMap<File, MakeNSISResults>(20);
                } else {
                    if (!(map instanceof MRUMap)) {
                        map = new MRUMap<File, MakeNSISResults>(20, map);
                    }
                }
                return map;
            }

            private void storeMap(File file, Map<File, MakeNSISResults> map) {
                if (Common.isEmptyMap(map)) {
                    file.delete();
                } else {
                    try {
                        IOUtility.writeObject(file, map);
                    } catch (IOException e) {
                        EclipseNSISPlugin.getDefault().log(e);
                    }
                }
            }

            public void start(IProgressMonitor monitor) {
                mResultsMap = loadMap(resultsCacheFile);
                mStarted = true;
            }

            public void stop(IProgressMonitor monitor) {
                mStarted = false;
                storeMap(resultsCacheFile, mResultsMap);
            }
        });
    }

    public void removeAssociatedHeader(IFile script, IFile header) {
        mHeaderAssociationManager.removeAssociatedHeader(script, header);
    }

    public void addAssociatedHeader(IFile script, IFile header) {
        mHeaderAssociationManager.addAssociatedHeader(script, header);
    }

    public void cacheResults(File script, MakeNSISResults results) {
        if (results != null) {
            mResultsMap.put(script, results);
        } else {
            removeCachedResults(script);
        }
    }

    public MakeNSISResults getCachedResults(File script) {
        if (IOUtility.isValidFile(script)) {
            if (!MakeNSISRunner.isCompiling()) {
                MakeNSISResults results = mResultsMap.get(script);
                if (results != null) {
                    if (script.lastModified() > results.getCompileTimestamp()) {
                        if (script.lastModified() < cEclipseStartTime) {
                            results = null;
                            mResultsMap.remove(script);
                        }
                    }
                }
                return results;
            }
        }
        return null;
    }

    public void removeCachedResults(File script) {
        if (IOUtility.isValidFile(script)) {
            if (!MakeNSISRunner.isCompiling()) {
                mResultsMap.remove(script);
            }
        }
    }

    public synchronized boolean compile(IPath script) {
        return compile(script, false);
    }

    public boolean compile(IPath script, boolean test) {
        IPath nsisScript = getCompileScript(script);
        if (nsisScript != null && script != null) {
            IFile scriptFile = (script.getDevice() == null
                    ? ResourcesPlugin.getWorkspace().getRoot().getFile(script)
                    : null);
            IFile nsisScriptFile = (nsisScript.getDevice() == null
                    ? ResourcesPlugin.getWorkspace().getRoot().getFile(nsisScript)
                    : null);
            List<IFile> associatedHeaders = (nsisScriptFile == null ? null
                    : NSISHeaderAssociationManager.getInstance().getAssociatedHeaders(nsisScriptFile));
            List<IEditorPart> editorList = new ArrayList<IEditorPart>();
            int beforeCompileSave = NSISPreferences.getInstance().getPreferenceStore()
                    .getInt(INSISPreferenceConstants.BEFORE_COMPILE_SAVE);
            IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows();
            outer: for (int i = 0; i < windows.length; i++) {
                IWorkbenchPage[] pages = windows[i].getPages();
                for (int j = 0; j < pages.length; j++) {
                    IEditorPart[] editors = pages[j].getDirtyEditors();
                    for (int k = 0; k < editors.length; k++) {
                        IPathEditorInput input = NSISEditorUtilities.getPathEditorInput(editors[k]);
                        switch (beforeCompileSave) {
                        case INSISPreferenceConstants.BEFORE_COMPILE_SAVE_ASSOCIATED_CONFIRM:
                        case INSISPreferenceConstants.BEFORE_COMPILE_SAVE_ASSOCIATED_AUTO:
                            if (!Common.isEmptyCollection(associatedHeaders)) {
                                //This will only happen if this is a workspace file.
                                //If not, this will drop through to the next case.
                                if (input instanceof IFileEditorInput) {
                                    IFile file = ((IFileEditorInput) input).getFile();
                                    if (associatedHeaders.contains(file)
                                            || (nsisScriptFile != null && nsisScriptFile.equals(file))) {
                                        editorList.add(editors[k]);
                                    }
                                }
                                continue;
                            }
                            //$FALL-THROUGH$
                        case INSISPreferenceConstants.BEFORE_COMPILE_SAVE_CURRENT_CONFIRM:
                        case INSISPreferenceConstants.BEFORE_COMPILE_SAVE_CURRENT_AUTO:
                            if (scriptFile != null && input instanceof IFileEditorInput) {
                                if (!scriptFile.equals(((IFileEditorInput) input).getFile())) {
                                    continue;
                                }
                            } else if (script.getDevice() != null && input != null) {
                                if (!script.equals(input.getPath())) {
                                    continue;
                                }
                            } else {
                                continue;
                            }
                            editorList.add(editors[k]);
                            break outer;
                        case INSISPreferenceConstants.BEFORE_COMPILE_SAVE_ALL_CONFIRM:
                        case INSISPreferenceConstants.BEFORE_COMPILE_SAVE_ALL_AUTO:
                            String ext;
                            if (input instanceof IFileEditorInput) {
                                ext = ((IFileEditorInput) input).getFile().getFullPath().getFileExtension();
                            } else if (input != null) {
                                ext = input.getPath().getFileExtension();
                            } else {
                                continue;
                            }
                            if (mNSISExtPattern.matcher(ext).matches()) {
                                editorList.add(editors[k]);
                            }
                        }
                    }
                }
            }
            if (!saveEditors(editorList, beforeCompileSave)) {
                return false;
            }
            new Thread(new NSISCompileRunnable(nsisScript, test),
                    EclipseNSISPlugin.getResourceString("makensis.thread.name")).start(); //$NON-NLS-1$
            return true;
        }
        return false;
    }

    private boolean saveEditors(List<IEditorPart> editors, int beforeCompileSave) {
        List<IEditorPart> editors2 = editors;
        if (!Common.isEmptyCollection(editors2)) {
            boolean ok = false;
            String message = null;
            switch (beforeCompileSave) {
            case INSISPreferenceConstants.BEFORE_COMPILE_SAVE_ASSOCIATED_CONFIRM:
                if (editors2.size() > 1) {
                    StringBuffer buf = new StringBuffer();
                    for (Iterator<IEditorPart> iter = editors2.iterator(); iter.hasNext();) {
                        IEditorPart editor = iter.next();
                        buf.append(INSISConstants.LINE_SEPARATOR).append(
                                ((IFileEditorInput) editor.getEditorInput()).getFile().getFullPath().toString());
                    }
                    message = EclipseNSISPlugin.getFormattedString("compile.save.associated.confirmation", //$NON-NLS-1$
                            new String[] { buf.toString() });
                    break;
                }
                //$FALL-THROUGH$
            case INSISPreferenceConstants.BEFORE_COMPILE_SAVE_CURRENT_CONFIRM:
                IEditorPart editor = editors2.get(0);
                if (editors2.size() > 1) {
                    editors2 = editors2.subList(0, 1);
                }
                IPathEditorInput input = NSISEditorUtilities.getPathEditorInput(editor);
                IPath path = (input instanceof IFileEditorInput ? ((IFileEditorInput) input).getFile().getFullPath()
                        : input.getPath());
                message = EclipseNSISPlugin.getFormattedString("compile.save.current.confirmation", //$NON-NLS-1$
                        new String[] { path.toString() });
                break;
            case INSISPreferenceConstants.BEFORE_COMPILE_SAVE_ALL_CONFIRM:
                message = EclipseNSISPlugin.getResourceString("compile.save.all.confirmation"); //$NON-NLS-1$
                break;
            case INSISPreferenceConstants.BEFORE_COMPILE_SAVE_CURRENT_AUTO:
            case INSISPreferenceConstants.BEFORE_COMPILE_SAVE_ASSOCIATED_AUTO:
            case INSISPreferenceConstants.BEFORE_COMPILE_SAVE_ALL_AUTO:
                ok = true;
            }
            Shell shell = Display.getDefault().getActiveShell();
            if (!ok) {
                MessageDialogWithToggle dialog = new MessageDialogWithToggle(shell,
                        EclipseNSISPlugin.getResourceString("confirm.title"), //$NON-NLS-1$
                        EclipseNSISPlugin.getShellImage(), message, MessageDialog.QUESTION,
                        new String[] { IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL }, 0,
                        EclipseNSISPlugin.getResourceString("compile.save.toggle.message"), false); //$NON-NLS-1$
                dialog.open();
                ok = dialog.getReturnCode() == IDialogConstants.OK_ID;
                if (ok && dialog.getToggleState()) {
                    NSISPreferences.getInstance().setBeforeCompileSave(
                            beforeCompileSave | INSISPreferenceConstants.BEFORE_COMPILE_SAVE_AUTO_FLAG);
                    NSISPreferences.getInstance().store();
                }
            }
            if (ok) {
                ProgressMonitorDialog dialog = new ProgressMonitorDialog(shell);
                dialog.open();
                IProgressMonitor progressMonitor = dialog.getProgressMonitor();
                if (editors2.size() > 1) {
                    progressMonitor.beginTask(
                            EclipseNSISPlugin.getResourceString("saving.before.compilation.task.name"), //$NON-NLS-1$
                            editors2.size());
                    for (Iterator<IEditorPart> iter = editors2.iterator(); iter.hasNext();) {
                        IEditorPart editor = iter.next();
                        SubProgressMonitor monitor = new SubProgressMonitor(progressMonitor, 1);
                        editor.doSave(monitor);
                        if (monitor.isCanceled()) {
                            break;
                        }
                    }
                } else {
                    editors2.get(0).doSave(progressMonitor);
                }
                dialog.close();
                if (progressMonitor.isCanceled()) {
                    return false;
                }
            }
            return ok;
        }
        return true;
    }

    public IPath getCompileScript(IPath input) {
        if (input != null) {
            String ext = input.getFileExtension();
            if (Common.stringsAreEqual(INSISConstants.NSI_EXTENSION, ext, true)) {
                return input;
            } else if (Common.stringsAreEqual(INSISConstants.NSH_EXTENSION, ext, true)
                    && input.getDevice() == null) {
                IFile header = getFile(input);
                IFile script = mHeaderAssociationManager.getAssociatedScript(header);
                if (script != null) {
                    IPath path = script.getFullPath();
                    if (path != null) {
                        if (Common.stringsAreEqual(INSISConstants.NSI_EXTENSION, path.getFileExtension(), true)) {
                            return path;
                        }
                    }
                }
            }
        }
        return null;
    }

    public boolean canTest(IPath script) {
        return getExeName(script) != null;
    }

    private String getExeName(IPath script) {
        IPath script2 = getCompileScript(script);
        if (script2 != null) {
            if (script2.getDevice() == null) {
                return getExeName(getFile(script2));
            } else {
                return getExeName(new File(script2.toOSString()));
            }
        }
        return null;
    }

    private boolean validateHeadersTimestamps(long exeTimestamp, Collection<IFile> headers) {
        if (!Common.isEmptyCollection(headers)) {
            for (Iterator<IFile> iter = headers.iterator(); iter.hasNext();) {
                IFile header = iter.next();
                if (header != null && header.exists()) {
                    if (!header.isSynchronized(IResource.DEPTH_ZERO) || header.getLocalTimeStamp() > exeTimestamp) {
                        return false;
                    }
                }
            }
        }
        return true;
    }

    private String getExeName(File file) {
        MakeNSISResults results = getCachedResults(file);
        if (results != null) {
            String outputFileName = results.getOutputFileName();
            if (outputFileName != null) {
                File exeFile = new File(outputFileName);
                if (IOUtility.isValidFile(exeFile)) {
                    long exeTimestamp = exeFile.lastModified();
                    long fileTimestamp = file.lastModified();
                    if (exeTimestamp >= fileTimestamp) {
                        return exeFile.getAbsolutePath();
                    }
                }
            }
        }
        return null;
    }

    private String getExeName(IFile file) {
        if (file != null && file.isSynchronized(IResource.DEPTH_ZERO)) {
            if (!MakeNSISRunner.isCompiling()) {
                try {
                    String temp = file.getPersistentProperty(INSISConstants.NSIS_COMPILE_TIMESTAMP);
                    if (temp != null) {
                        long nsisCompileTimestamp = Long.parseLong(temp);
                        if (nsisCompileTimestamp >= file.getLocalTimeStamp()) {
                            temp = file.getPersistentProperty(INSISConstants.NSIS_EXE_NAME);
                            if (temp != null) {
                                File exeFile = new File(temp);
                                if (exeFile.exists()) {
                                    temp = file.getPersistentProperty(INSISConstants.NSIS_EXE_TIMESTAMP);
                                    if (temp != null) {
                                        long exeTimestamp = exeFile.lastModified();
                                        if (Long.parseLong(temp) == exeTimestamp) {
                                            if (validateHeadersTimestamps(exeTimestamp,
                                                    mHeaderAssociationManager.getAssociatedHeaders(file))) {
                                                return exeFile.getAbsolutePath();
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                } catch (Exception ex) {
                    EclipseNSISPlugin.getDefault().log(ex);
                }
            }
        }
        return null;
    }

    public void test(IPath script) {
        test(getExeName(script), EclipseNSISPlugin.getDefault().getConsole());
    }

    private void test(final String exeName, final INSISConsole console) {
        if (exeName != null) {
            Display.getDefault().asyncExec(new Runnable() {
                public void run() {
                    BusyIndicator.showWhile(Display.getDefault(), new Runnable() {
                        public void run() {
                            MakeNSISRunner.testInstaller(exeName, console);
                        }
                    });
                }
            });
        }
    }

    private IFile getFile(IPath path) {
        return path != null ? ResourcesPlugin.getWorkspace().getRoot().getFile(path) : null;
    }

    private class NSISCompileRunnable implements Runnable, INSISConsoleLineProcessor {
        private String mOutputExeName = null;
        private IPath mScript = null;
        private boolean mTest = false;
        private INSISConsoleLineProcessor mDelegate;

        public NSISCompileRunnable(IPath script, boolean test) {
            mScript = script;
            mTest = test;
            mDelegate = new NSISConsoleLineProcessor(mScript);
        }

        public void run() {
            if (mScript != null) {
                reset();
                MakeNSISResults results;
                if (mScript.getDevice() == null) {
                    results = MakeNSISRunner.compile(getFile(mScript), EclipseNSISPlugin.getDefault().getConsole(),
                            this);
                } else {
                    File file = new File(mScript.toOSString());
                    results = MakeNSISRunner.compile(file, NSISPreferences.getInstance(),
                            EclipseNSISPlugin.getDefault().getConsole(), this);
                }
                if (results != null) {
                    mOutputExeName = results.getOutputFileName();
                    if (mTest && mOutputExeName != null) {
                        test(mOutputExeName, null);
                    }
                }
            }
        }

        public NSISConsoleLine processText(String text) {
            return mDelegate.processText(text);
        }

        public void reset() {
            mOutputExeName = null;
            mDelegate.reset();
        }
    }
}