Java tutorial
/* * 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; } }