nz.ac.auckland.ptjava.preferences.PTJavaPreferencePage.java Source code

Java tutorial

Introduction

Here is the source code for nz.ac.auckland.ptjava.preferences.PTJavaPreferencePage.java

Source

/*
 * Copyright (C) 2010 Christopher Chong, Oliver Sinnen and others.
 * 
 * This program is free software; you can redistribute it and/or modify 
 * it under the terms of the GNU General Public License as published by 
 * the Free Software Foundation; either version 3 of the License, or 
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License 
 * along with this program; if not, see <http://www.gnu.org/licenses>.
 * 
 * Additional permission under GNU GPL version 3 section 7
 * 
 * If you modify this Program, or any covered work, by linking or 
 * combining it with Eclipse (or a modified version of that library), 
 * containing parts covered by the terms of the Eclipse Public License - v1.0, 
 * the licensors of this Program grant you additional permission to 
 * convey the resulting work. {Corresponding Source for a non-source form 
 * of such a combination shall include the source code for the parts 
 * of Eclipse used as well as that of the covered work.}
 * 
 */
package nz.ac.auckland.ptjava.preferences;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import nz.ac.auckland.ptjava.PTJavaPlugin;
import nz.ac.auckland.ptjava.builder.PTJavaFileBuilderNature;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jface.preference.BooleanFieldEditor;
import org.eclipse.jface.preference.FieldEditorPreferencePage;
import org.eclipse.jface.preference.FileFieldEditor;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;

/**
 * The Preference page for PTJava specific preferences. Contributes to the preferences
 * extension.
 *
 */
public class PTJavaPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {

    /**
     * The String for the allowed compiler extension 
     */
    private static final String fgCompilerExtension = "PTCompiler.jar";

    /**
     * The String for the allowed runtime extension 
     */
    private static final String fgRuntimeExtension = "PTRuntime.jar";

    /**
     * The ID for the Preference page.
     */
    public static final String ID = PTJavaPlugin.PLUGIN_ID + ".preferences.PTJavaPreferencePage";

    /**
     * The path to the default PTRuntime.jar file (on the workspace root by default)
     */
    private static IPath fgDefaultRuntimeJarPath;

    private BooleanFieldEditor fShowErrorsInCompiledPTJava;
    private FileFieldEditor fPTJavaCompilerPathEditor;
    private BooleanFieldEditor fAssociateNature;
    private BooleanFieldEditor fUseCustomCompiler;

    private BooleanFieldEditor fUseCustomRuntime;
    private FileFieldEditor fPTJavaRuntimePathEditor;

    public PTJavaPreferencePage() {
        super(GRID);
        setPreferenceStore(PTJavaPlugin.getDefault().getPreferenceStore());
        setDescription("PTJava Preferences");
    }

    /**
     * Creates the field editors. Field editors are abstractions of
     * the common GUI blocks needed to manipulate various types
     * of preferences. Each field editor knows how to save and
     * restore itself.
     */
    public void createFieldEditors() {
        //  show or hide errors in .java source files generated by the PTJava compiler
        fShowErrorsInCompiledPTJava = new BooleanFieldEditor(PreferenceConstants.PTJAVA_SHOW_HIDDEN_ERRORS,
                "Show errors in .java source files created by the PTJava compiler (refreshes on next build)",
                getFieldEditorParent());
        addField(fShowErrorsInCompiledPTJava);

        //  use custom compiler check box
        fUseCustomCompiler = new BooleanFieldEditor(PreferenceConstants.PTJAVA_USE_CUSTOM_COMPILER,
                "Use a custom compiler instead of the default:", getFieldEditorParent());
        addField(fUseCustomCompiler);

        //  custom compiler field editor
        fPTJavaCompilerPathEditor = new FileFieldEditor(PreferenceConstants.PTJAVA_COMPILER_PATH, "&Compiler jar:",
                getFieldEditorParent());
        String extensions[] = { fgCompilerExtension };
        fPTJavaCompilerPathEditor.setFileExtensions(extensions);
        boolean useCustom = PTJavaPlugin.getDefault().getPreferenceStore()
                .getBoolean(PreferenceConstants.PTJAVA_USE_CUSTOM_COMPILER);
        fPTJavaCompilerPathEditor.setEnabled(useCustom, getFieldEditorParent());

        addField(fPTJavaCompilerPathEditor);

        //  invoke compiler check box
        fAssociateNature = new BooleanFieldEditor(PreferenceConstants.PTJAVA_ASSOCIATE_NATURE,
                "Invoke PTJava Compiler on builds (for PTJava Projects only)", getFieldEditorParent());
        addField(fAssociateNature);

        //  use custom runtime check box
        fUseCustomRuntime = new BooleanFieldEditor(PreferenceConstants.PTJAVA_USE_CUSTOM_RUNTIME,
                "Use a custom runtime library instead of the default:", getFieldEditorParent());
        addField(fUseCustomRuntime);

        //  spacer

        //  custom runtime field editor
        fPTJavaRuntimePathEditor = new FileFieldEditor(PreferenceConstants.PTJAVA_RUNTIME_PATH, "&Runtime jar:",
                getFieldEditorParent());
        String runtimeExtensions[] = { fgRuntimeExtension };
        fPTJavaRuntimePathEditor.setFileExtensions(runtimeExtensions);
        boolean useCustomRuntime = PTJavaPlugin.getDefault().getPreferenceStore()
                .getBoolean(PreferenceConstants.PTJAVA_USE_CUSTOM_RUNTIME);
        fPTJavaRuntimePathEditor.setEnabled(useCustomRuntime, getFieldEditorParent());

        addField(fPTJavaRuntimePathEditor);
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
     */
    public void init(IWorkbench workbench) {
    }

    /**
     * Event handler for when a property is changes in the preferences page.
     * Current implementation updates the preference page widgets as options are selected on the page.
     * 
     * @param event The property change event.
     *
     * @see org.eclipse.jface.preference.FieldEditorPreferencePage#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
     */
    @Override
    public void propertyChange(PropertyChangeEvent event) {
        super.propertyChange(event);
        if (event.getProperty().equals("field_editor_value")) {
            Object obj = event.getSource();
            if (obj instanceof BooleanFieldEditor) {
                BooleanFieldEditor bfe = (BooleanFieldEditor) obj;
                if (bfe.equals(fUseCustomCompiler)) {
                    fPTJavaCompilerPathEditor.setEnabled(fUseCustomCompiler.getBooleanValue(),
                            getFieldEditorParent());
                } else if (bfe.equals(fUseCustomRuntime)) {
                    fPTJavaRuntimePathEditor.setEnabled(fUseCustomRuntime.getBooleanValue(),
                            getFieldEditorParent());
                }
            }
        }
    }

    /*
     * (non-Javadoc)
     * @see org.eclipse.jface.preference.FieldEditorPreferencePage#performDefaults()
     */
    @Override
    protected void performDefaults() {
        super.performDefaults();
        fPTJavaCompilerPathEditor.setEnabled(fUseCustomCompiler.getBooleanValue(), getFieldEditorParent());
        fPTJavaRuntimePathEditor.setEnabled(fUseCustomRuntime.getBooleanValue(), getFieldEditorParent());
    }

    /*
     * (non-Javadoc)
     * @see org.eclipse.jface.preference.FieldEditorPreferencePage#performOk()
     */
    @Override
    public boolean performOk() {
        boolean ret = super.performOk();
        Pattern pattern = Pattern.compile(".*/" + fgRuntimeExtension.replace(".", "\\."));

        IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
        IProject[] projects = root.getProjects();
        for (IProject project : projects) {
            try {
                if (project.hasNature(JavaCore.NATURE_ID) && project.hasNature(PTJavaFileBuilderNature.NATURE_ID)) {
                    IJavaProject jProject = JavaCore.create(project);
                    IClasspathEntry[] entries = jProject.getRawClasspath();
                    List<IClasspathEntry> newEntryList = new ArrayList<IClasspathEntry>();

                    //  remove PTRuntime.jar from Java project class path
                    for (int i = 0; i < entries.length; ++i) {
                        IPath path = entries[i].getPath();
                        Matcher matcher = pattern.matcher(path.toString());
                        if (!matcher.matches()) {
                            newEntryList.add(entries[i]);
                        }
                    }

                    //  add the new runtime to class path
                    if (getPreferenceStore().getBoolean(PreferenceConstants.PTJAVA_USE_CUSTOM_RUNTIME)) {
                        String sPath = fPTJavaRuntimePathEditor.getStringValue();
                        if (sPath.endsWith(fgRuntimeExtension) && Path.EMPTY.isValidPath(sPath)) {
                            IPath runtimePath = new Path(sPath);
                            newEntryList.add(JavaCore.newLibraryEntry(runtimePath, null, null));
                        }
                    } else {
                        IPath runtimePath = getDefaultRuntimeJarPath();
                        newEntryList.add(JavaCore.newLibraryEntry(runtimePath, null, null));
                    }
                    IClasspathEntry[] updatedEntries = new IClasspathEntry[newEntryList.size()];
                    newEntryList.toArray(updatedEntries);

                    jProject.setRawClasspath(updatedEntries, null);

                }
            } catch (CoreException e) {
                e.printStackTrace();
            }
        }
        return ret;
    }

    /**
     * Returns the path to the default Parallel Task runtime library (PTRuntime.jar), which is created in {@link PTJavaPreferencePage#loadRuntimeJarFile()}.
     * @return The path to the default PTRuntime.jar file. 
     */
    public static IPath getDefaultRuntimeJarPath() {
        return fgDefaultRuntimeJarPath;
    }

    /**
     * Loads the default PTRuntime.jar file from the plug-in and puts a copy into the workspace root directory.
     * If PTRuntime.jar already exists in the workspace root, the jar file is overwritten.
     * Stores the path to the created runtime jar file.
     * @throws IOException If the PTRuntime.jar file cannot be found in the plug-in, or written to in the workspace root.
     */
    public static void loadRuntimeJarFile() throws IOException {
        Path path = new Path("/" + fgRuntimeExtension);

        URL installURL = Platform.getBundle(PTJavaPlugin.PLUGIN_ID).getEntry(path.toString());
        if (installURL == null)
            return;

        URL localURL = FileLocator.toFileURL(installURL);

        File srcFile = new File(localURL.getFile());
        File destFile = null;

        IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();

        IPath destFilePath = workspaceRoot.getLocation().append(path);
        destFile = new File(destFilePath.toString());
        destFile.createNewFile();

        //  overwrite the dest file
        FileInputStream input = new FileInputStream(srcFile);
        FileOutputStream output = new FileOutputStream(destFile);

        byte[] buffer = new byte[65536];
        int length;
        while ((length = input.read(buffer)) > 0) {
            output.write(buffer, 0, length);
        }

        output.close();
        input.close();

        fgDefaultRuntimeJarPath = destFilePath;
    }
}