| /******************************************************************************* |
| * Copyright (c) 2005 BEA Systems, Inc. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * jgarms@bea.com, wharley@bea.com - initial API and implementation |
| * |
| *******************************************************************************/ |
| package org.eclipse.jdt.apt.core.util; |
| |
| import java.io.File; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.resources.ProjectScope; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.preferences.DefaultScope; |
| import org.eclipse.core.runtime.preferences.IEclipsePreferences; |
| import org.eclipse.core.runtime.preferences.IPreferencesService; |
| import org.eclipse.core.runtime.preferences.IScopeContext; |
| import org.eclipse.core.runtime.preferences.InstanceScope; |
| import org.eclipse.jdt.apt.core.AptPlugin; |
| import org.eclipse.jdt.apt.core.internal.AnnotationProcessorFactoryLoader; |
| import org.eclipse.jdt.apt.core.internal.AptProject; |
| import org.eclipse.jdt.apt.core.internal.util.FactoryPath; |
| import org.eclipse.jdt.apt.core.internal.util.FactoryPathUtil; |
| import org.eclipse.jdt.core.IClasspathEntry; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.osgi.service.prefs.BackingStoreException; |
| |
| /** |
| * Accesses configuration data for APT. |
| * Note that some of the code in org.eclipse.jdt.ui reads and writes settings |
| * data directly, rather than calling into the methods of this class. |
| * |
| * This class is static. Instances should not be constructed. |
| * |
| * Helpful information about the Eclipse preferences mechanism can be found at: |
| * http://dev.eclipse.org/viewcvs/index.cgi/~checkout~/platform-core-home/documents/user_settings/faq.html |
| */ |
| public class AptConfig { |
| |
| /* |
| * Hide constructor; this is a static object |
| */ |
| private AptConfig() {} |
| |
| /** |
| * Add the equivalent of -Akey=val to the list of processor options. |
| * @param key must be a nonempty string. It should only include the key; |
| * that is, it should not start with "-A". |
| * @param jproj a project, or null to set the option workspace-wide. |
| * @param val can be null (equivalent to -Akey). This does not mean |
| * remove the key; for that functionality, @see #removeProcessorOption(IJavaProject, String). |
| */ |
| public static void addProcessorOption(IJavaProject jproj, String key, String val) { |
| if (key == null || key.length() < 1) { |
| throw new IllegalArgumentException(); |
| } |
| IScopeContext context = (null != jproj) ? |
| new ProjectScope(jproj.getProject()) : new InstanceScope(); |
| IEclipsePreferences node = context.getNode(AptPlugin.PLUGIN_ID + "/" + //$NON-NLS-1$ |
| AptPreferenceConstants.APT_PROCESSOROPTIONS); |
| String nonNullVal = val == null ? AptPreferenceConstants.APT_NULLVALUE : val; |
| node.put(key, nonNullVal); |
| try { |
| node.flush(); |
| } catch (BackingStoreException e) { |
| AptPlugin.log(e, "Unable to save annotation processor option" + key); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Remove an option from the list of processor options. |
| * @param jproj a project, or null to remove the option workspace-wide. |
| * @param key must be a nonempty string. It should only include the key; |
| * that is, it should not start with "-A". |
| */ |
| public static void removeProcessorOption(IJavaProject jproj, String key) { |
| if (key == null || key.length() < 1) { |
| throw new IllegalArgumentException(); |
| } |
| IScopeContext context = (null != jproj) ? |
| new ProjectScope(jproj.getProject()) : new InstanceScope(); |
| IEclipsePreferences node = context.getNode(AptPlugin.PLUGIN_ID + "/" + //$NON-NLS-1$ |
| AptPreferenceConstants.APT_PROCESSOROPTIONS); |
| node.remove(key); |
| try { |
| node.flush(); |
| } catch (BackingStoreException e) { |
| AptPlugin.log(e, "Unable to save annotation processor option" + key); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Get the options that are presented to annotation processors by the |
| * AnnotationProcessorEnvironment. The -A and = are stripped out, so |
| * (key, value) is the equivalent of -Akey=value. |
| * |
| * This method returns some options which are set programmatically but |
| * are not directly editable, are not displayed in the configuration GUI, |
| * and are not persisted to the preference store. This is meant to |
| * emulate the behavior of Sun's apt command-line tool, which passes |
| * most of its command line options to the processor environment. The |
| * programmatically set options are: |
| * -classpath [set to Java build path] |
| * -sourcepath [set to Java source path] |
| * -s [set to generated src dir] |
| * -d [set to binary output dir] |
| * -target [set to compiler target version] |
| * -source [set to compiler source version] |
| * |
| * @param jproj a project, or null to query the workspace-wide setting. |
| * @return a mutable, possibly empty, map of (key, value) pairs. |
| * The value part of a pair may be null (equivalent to "-Akey"). |
| * The value part can contain spaces, if it is quoted: -Afoo="bar baz". |
| */ |
| public static Map<String, String> getProcessorOptions(IJavaProject jproj) { |
| Map<String,String> options; |
| options = getRawProcessorOptions(jproj); |
| if (jproj == null) { |
| // there are no programmatically set options at the workspace level |
| return options; |
| } |
| |
| IPath workspaceRootPath = jproj.getProject().getWorkspace().getRoot().getLocation(); |
| |
| // Add sourcepath and classpath variables |
| try { |
| IClasspathEntry[] classpathEntries = jproj.getResolvedClasspath(true); |
| StringBuilder classpathSB = new StringBuilder(); |
| StringBuilder sourcepathSB = new StringBuilder(); |
| boolean firstCP = true; |
| boolean firstSP = true; |
| for (IClasspathEntry entry : classpathEntries) { |
| int kind = entry.getEntryKind(); |
| if (kind == IClasspathEntry.CPE_LIBRARY) { |
| if (firstCP) { |
| firstCP = false; |
| } |
| else { |
| classpathSB.append(File.pathSeparatorChar); |
| } |
| classpathSB.append(entry.getPath().makeAbsolute().toOSString()); |
| } |
| else if (kind == IClasspathEntry.CPE_SOURCE) { |
| if (firstSP) { |
| firstSP = false; |
| } |
| else { |
| sourcepathSB.append(File.separatorChar); |
| } |
| // Sourcepath is a bit odd -- it's workspace-relative |
| IPath sourcepath = entry.getPath(); |
| sourcepathSB.append(workspaceRootPath.append(sourcepath).toOSString()); |
| } |
| } |
| // if you add options here, also add them in isAutomaticProcessorOption(), |
| // and document them in docs/reference/automatic_processor_options.html. |
| |
| // Classpath and sourcepath |
| options.put("-classpath",classpathSB.toString()); //$NON-NLS-1$ |
| options.put("-sourcepath", sourcepathSB.toString()); //$NON-NLS-1$ |
| |
| // Get absolute path for generated source dir |
| IFolder genSrcDir = jproj.getProject().getFolder(getGenSrcDir(jproj)); |
| options.put("-s", genSrcDir.getRawLocation().toOSString()); //$NON-NLS-1$ |
| |
| // Absolute path for bin dir as well |
| IPath binPath = jproj.getOutputLocation(); |
| IPath binDir = workspaceRootPath.append(binPath); |
| options.put("-d", binDir.toOSString()); //$NON-NLS-1$ |
| |
| String target = jproj.getOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, true); |
| options.put("-target", target); //$NON-NLS-1$ |
| |
| String source = jproj.getOption(JavaCore.COMPILER_SOURCE, true); |
| options.put("-source", source); //$NON-NLS-1$ |
| } |
| catch (JavaModelException jme) { |
| AptPlugin.log(jme, "Could not get the classpath for project: " + jproj); //$NON-NLS-1$ |
| } |
| |
| return options; |
| } |
| |
| /** |
| * Set all the processor options in one call. This will delete any |
| * options that are not passed in, so callers who do not wish to |
| * destroy pre-existing options should use addProcessorOption() instead. |
| * @param options a map of keys to values. The keys should not include |
| * any automatic options (@see #isAutomaticProcessorOption(String)), |
| * and the "-A" should not be included. That is, to perform the |
| * equivalent of the apt command line "-Afoo=bar", use the key "foo" |
| * and the value "bar". Keys cannot contain spaces; values can |
| * contain anything at all. Keys cannot be null, but values can be. |
| */ |
| public static void setProcessorOptions(Map<String, String> options, IJavaProject jproj) { |
| IScopeContext context = (null != jproj) ? |
| new ProjectScope(jproj.getProject()) : new InstanceScope(); |
| |
| // TODO: this call is needed only for backwards compatibility with |
| // settings files previous to 2005.11.13. At some point it should be |
| // removed. |
| removeOldStyleSettings(context); |
| |
| IEclipsePreferences node = context.getNode(AptPlugin.PLUGIN_ID + "/" + //$NON-NLS-1$ |
| AptPreferenceConstants.APT_PROCESSOROPTIONS); |
| try { |
| node.clear(); |
| for (Entry<String, String> option : options.entrySet()) { |
| String nonNullVal = option.getValue() == null ? |
| AptPreferenceConstants.APT_NULLVALUE : option.getValue(); |
| node.put(option.getKey(), nonNullVal); |
| } |
| node.flush(); |
| } catch (BackingStoreException e) { |
| AptPlugin.log(e, "Unable to save annotation processor options"); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Is the named option automatically generated in getProcessorOptions(), |
| * or did it come from somewhere else, such as a -A processor option? |
| * @param key the name of an AnnotationProcessorEnvironment option |
| * @return true if the option is automatically set. |
| */ |
| public static boolean isAutomaticProcessorOption(String key) { |
| if ("-classpath".equals(key)) //$NON-NLS-1$ |
| return true; |
| if ("-sourcepath".equals(key)) //$NON-NLS-1$ |
| return true; |
| if ("-s".equals(key)) //$NON-NLS-1$ |
| return true; |
| if ("-d".equals(key)) //$NON-NLS-1$ |
| return true; |
| if ("-target".equals(key)) //$NON-NLS-1$ |
| return true; |
| if ("-source".equals(key)) //$NON-NLS-1$ |
| return true; |
| return false; |
| } |
| |
| /** |
| * Get the options that are presented to annotation processors by the |
| * AnnotationProcessorEnvironment. The -A and = are stripped out, so |
| * (key, value) is the equivalent of -Akey=value. |
| * |
| * This method differs from getProcessorOptions in that the options returned |
| * by this method do NOT include any programmatically set options. This |
| * method returns only the options that are persisted to the preference |
| * store and that are displayed in the configuration GUI. |
| * |
| * @param jproj a project, or null to query the workspace-wide setting. |
| * If jproj is not null, but the project has no per-project settings, |
| * this method will fall back to the workspace-wide settings. |
| * @return a mutable, possibly empty, map of (key, value) pairs. |
| * The value part of a pair may be null (equivalent to "-Akey"). |
| * The value part can contain spaces, if it is quoted: -Afoo="bar baz". |
| */ |
| public static Map<String, String> getRawProcessorOptions(IJavaProject jproj) { |
| Map<String, String> options = new HashMap<String, String>(); |
| |
| // TODO: this code is needed only for backwards compatibility with |
| // settings files previous to 2005.11.13. At some point it should be |
| // removed. |
| // If an old-style setting exists, add it into the mix for backward |
| // compatibility. |
| options.putAll(getOldStyleRawProcessorOptions(jproj)); |
| |
| // Fall back from project to workspace scope on an all-or-nothing basis, |
| // not value by value. (Never fall back to default scope; there are no |
| // default processor options.) We can't use IPreferencesService for this |
| // as we would normally do, because we don't know the names of the keys. |
| IScopeContext[] contexts; |
| if (jproj != null) { |
| contexts = new IScopeContext[] { |
| new ProjectScope(jproj.getProject()), new InstanceScope() }; |
| } |
| else { |
| contexts = new IScopeContext[] { new InstanceScope() }; |
| } |
| for (IScopeContext context : contexts) { |
| IEclipsePreferences prefs = context.getNode(AptPlugin.PLUGIN_ID); |
| try { |
| if (prefs.childrenNames().length > 0) { |
| IEclipsePreferences procOptionsNode = context.getNode( |
| AptPlugin.PLUGIN_ID + "/" + AptPreferenceConstants.APT_PROCESSOROPTIONS); //$NON-NLS-1$ |
| if (procOptionsNode != null) { |
| for (String key : procOptionsNode.keys()) { |
| String nonNullVal = procOptionsNode.get(key, null); |
| String val = AptPreferenceConstants.APT_NULLVALUE.equals(nonNullVal) ? |
| null : nonNullVal; |
| options.put(key, val); |
| } |
| break; |
| } |
| } |
| } catch (BackingStoreException e) { |
| AptPlugin.log(e, "Unable to load annotation processor options"); //$NON-NLS-1$ |
| } |
| } |
| return options; |
| } |
| |
| /** |
| * TODO: this code is needed only for backwards compatibility with |
| * settings files previous to 2005.11.13. At some point it should be |
| * removed. |
| * Get the processor options as an APT-style string ("-Afoo=bar -Abaz=quux") |
| */ |
| private static Map<String, String> getOldStyleRawProcessorOptions(IJavaProject jproj) { |
| Map<String, String> options; |
| String allOptions = getString(jproj, AptPreferenceConstants.APT_PROCESSOROPTIONS); |
| if (null == allOptions) { |
| options = new HashMap<String, String>(); |
| } |
| else { |
| ProcessorOptionsParser op = new ProcessorOptionsParser(allOptions); |
| options = op.parse(); |
| } |
| return options; |
| } |
| /** |
| * TODO: this code is needed only for backwards compatibility with |
| * settings files previous to 2005.11.13. At some point it should be |
| * removed. |
| * |
| * Used to parse an apt-style command line string into a map of key/value |
| * pairs. |
| * Parsing ignores errors and simply tries to gobble up as many well-formed |
| * pairs as it can find. |
| */ |
| private static class ProcessorOptionsParser { |
| final String _s; |
| int _start; // everything before this is already parsed. |
| boolean _hasVal; // does the last key found have a value token? |
| |
| public ProcessorOptionsParser(String s) { |
| _s = s; |
| _start = 0; |
| _hasVal = false; |
| } |
| |
| public Map<String, String> parse() { |
| Map<String, String> options = new HashMap<String, String>(); |
| String key; |
| while (null != (key = parseKey())) { |
| options.put(key, parseVal()); |
| } |
| return options; |
| } |
| |
| /** |
| * Skip until a well-formed key (-Akey[=val]) is found, and |
| * return the key. Set _start to the beginning of the value, |
| * or to the first character after the end of the key and |
| * delimiter, for a valueless key. Set _hasVal according to |
| * whether a value was found. |
| * @return a key, or null if no well-formed keys can be found. |
| */ |
| private String parseKey() { |
| String key; |
| int spaceAt = -1; |
| int equalsAt = -1; |
| |
| _hasVal = false; |
| |
| do { |
| _start = _s.indexOf("-A", _start); //$NON-NLS-1$ |
| if (_start < 0) { |
| return null; |
| } |
| |
| // we found a -A. The key is everything up to the next '=' or ' ' or EOL. |
| _start += 2; |
| if (_start >= _s.length()) { |
| // it was just a -A, nothing following. |
| return null; |
| } |
| |
| spaceAt = _s.indexOf(' ', _start); |
| equalsAt = _s.indexOf('=', _start); |
| if (spaceAt == _start || equalsAt == _start) { |
| // false alarm. Keep trying. |
| ++_start; |
| continue; |
| } |
| } while (false); |
| |
| // We found a legitimate -A with some text after it. |
| // Where does the key end? |
| if (equalsAt > 0) { |
| if (spaceAt < 0 || equalsAt < spaceAt) { |
| // there is an equals, so there is a value. |
| key = new String(_s.substring(_start, equalsAt)); |
| _start = equalsAt + 1; |
| _hasVal = (_start < _s.length()); |
| } |
| else { |
| // the next thing is a space, so this is a valueless key |
| key = new String(_s.substring(_start, spaceAt)); |
| _start = spaceAt + 1; |
| } |
| } |
| else { |
| if (spaceAt < 0) { |
| // no equals sign and no spaces: a valueless key, up to the end of the string. |
| key = new String(_s.substring(_start)); |
| _start = _s.length(); |
| } |
| else { |
| // the next thing is a space, so this is a valueless key |
| key = new String(_s.substring(_start, spaceAt)); |
| _start = spaceAt + 1; |
| } |
| } |
| return key; |
| } |
| |
| /** |
| * A value token is delimited by a space; but spaces inside quoted |
| * regions are ignored. A value may include multiple quoted regions. |
| * An unmatched quote is treated as if there was a matching quote at |
| * the end of the string. Quotes are returned as part of the value. |
| * @return the value, up to the next nonquoted space or end of string. |
| */ |
| private String parseVal() { |
| if (!_hasVal || _start < 0 || _start >= _s.length()) { |
| return null; |
| } |
| boolean inQuotedRegion = false; |
| int start = _start; |
| int end = _start; |
| while (end < _s.length()) { |
| char c = _s.charAt(end); |
| if (c == '"') { |
| inQuotedRegion = !inQuotedRegion; |
| } |
| else if (!inQuotedRegion && c == ' ') { |
| // end of token. |
| _start = end + 1; |
| break; |
| } |
| ++end; |
| } |
| |
| return new String(_s.substring(start, end)); |
| } |
| } |
| |
| /** |
| * TODO: this code is needed only for backwards compatibility with |
| * settings files previous to 2005.11.13. At some point it should be |
| * removed. |
| * Delete the key that saves annotation processor options as a single |
| * command-line-type string ("-Afoo=bar -Abaz=quux"). |
| */ |
| private static void removeOldStyleSettings(IScopeContext context) { |
| IEclipsePreferences node = context.getNode(AptPlugin.PLUGIN_ID); |
| node.remove(AptPreferenceConstants.APT_PROCESSOROPTIONS); |
| } |
| |
| /** |
| * Flush unsaved preferences and perform any other config-related shutdown. |
| * This is called once, from AptPlugin.shutdown(). |
| */ |
| public static void dispose() { |
| try { |
| new InstanceScope().getNode(AptPlugin.PLUGIN_ID).flush(); |
| } |
| catch (BackingStoreException e) { |
| // log failure and continue |
| AptPlugin.log(e, "Couldn't flush preferences to disk"); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Initialize preferences lookups, and register change listeners. |
| * This is called once, from AptPlugin.startup(). |
| */ |
| public static void initialize() { |
| // If we cached workspace-level preferences, we would want to install |
| // some change listeners here. |
| } |
| |
| /** |
| * Is annotation processing turned on for this project? |
| * @param jproject an IJavaProject, or null to request workspace preferences. |
| * @return |
| */ |
| public static boolean isEnabled(IJavaProject jproject) { |
| return getBoolean(jproject, AptPreferenceConstants.APT_ENABLED); |
| } |
| |
| /** |
| * Turn annotation processing on or off for this project. |
| * @param jproject an IJavaProject, or null to set workspace preferences. |
| * @param enabled |
| */ |
| public static void setEnabled(IJavaProject jproject, boolean enabled) { |
| if (jproject == null && enabled == true) { |
| IllegalArgumentException e = new IllegalArgumentException(); |
| IStatus status = AptPlugin.createWarningStatus(e, |
| "Illegal attempt to enable annotation processing workspace-wide"); //$NON-NLS-1$ |
| AptPlugin.log(status); |
| throw e; |
| } |
| setBoolean(jproject, AptPreferenceConstants.APT_ENABLED, enabled); |
| } |
| |
| private static boolean getBoolean(IJavaProject jproj, String optionName) { |
| IPreferencesService service = Platform.getPreferencesService(); |
| IScopeContext[] contexts; |
| if (jproj != null) { |
| contexts = new IScopeContext[] { |
| new ProjectScope(jproj.getProject()), new InstanceScope(), new DefaultScope() }; |
| } |
| else { |
| contexts = new IScopeContext[] { new InstanceScope(), new DefaultScope() }; |
| } |
| return service.getBoolean( |
| AptPlugin.PLUGIN_ID, |
| optionName, |
| Boolean.parseBoolean(AptPreferenceConstants.DEFAULT_OPTIONS_MAP.get(optionName)), |
| contexts); |
| } |
| |
| /** |
| * Get a factory path corresponding to the default values: if jproj is |
| * non-null, return the current workspace factory path (workspace prefs |
| * are the default for a project); if jproj is null, return the default |
| * list of plugin factories (which is the "factory default"). |
| */ |
| public static IFactoryPath getDefaultFactoryPath(IJavaProject jproj) { |
| return FactoryPathUtil.getDefaultFactoryPath(jproj); |
| } |
| |
| /** |
| * Get the factory path for a given project or for the workspace. |
| * @param jproj the project, or null to get the factory path for the workspace. |
| * @return a FactoryPath representing the current state of the specified project. |
| * Note that changes made to the project after this call will not affect the |
| * returned object - that is, it behaves like a value, not like a live link to |
| * the project state. |
| */ |
| public static IFactoryPath getFactoryPath(IJavaProject jproj) { |
| return FactoryPathUtil.getFactoryPath(jproj); |
| } |
| |
| /** |
| * Set the factory path for a given project or for the workspace. |
| * Does not perform any validation on the path. |
| * @param jproj the project, or null to set the factory path for the workspace. |
| * @param path a factory path, or null to reset the factory path to the default. |
| */ |
| public static void setFactoryPath(IJavaProject jproj, IFactoryPath path) |
| throws CoreException |
| { |
| FactoryPath fp = (FactoryPath)path; |
| FactoryPathUtil.setFactoryPath(jproj, fp); |
| // Project-specific factory path files are resources, so changes |
| // get picked up by the resource listener. Workspace changes aren't. |
| if (jproj == null) { |
| AnnotationProcessorFactoryLoader.getLoader().resetAll(); |
| } |
| } |
| |
| /** |
| * Has an explicit factory path been set for the specified project, or |
| * is it just defaulting to the workspace settings? |
| * @param project |
| * @return true if there is a project-specific factory path. |
| */ |
| public static boolean hasProjectSpecificFactoryPath(IJavaProject jproj) { |
| if (null == jproj) { |
| // say no, even if workspace-level factory path does exist. |
| return false; |
| } |
| return FactoryPathUtil.doesFactoryPathFileExist(jproj); |
| } |
| |
| /** |
| * Helper method to get a single preference setting, e.g., APT_GENSRCDIR. |
| * This is a different level of abstraction than the processor -A settings! |
| * The -A settings are all contained under one single preference node, |
| * APT_PROCESSOROPTIONS. Use @see #getProcessorOptions(IJavaProject) to |
| * get the -A settings; use @see #getOptions(IJavaProject) to get all the |
| * preference settings as a map; and use this helper method to get a single |
| * preference setting. |
| * |
| * @param jproj the project, or null for workspace. |
| * @param optionName a preference constant from @see AptPreferenceConstants. |
| * @return |
| */ |
| public static String getString(IJavaProject jproj, String optionName) { |
| IPreferencesService service = Platform.getPreferencesService(); |
| IScopeContext[] contexts; |
| if (jproj != null) { |
| contexts = new IScopeContext[] { |
| new ProjectScope(jproj.getProject()), new InstanceScope(), new DefaultScope() }; |
| } |
| else { |
| contexts = new IScopeContext[] { new InstanceScope(), new DefaultScope() }; |
| } |
| return service.getString( |
| AptPlugin.PLUGIN_ID, |
| optionName, |
| AptPreferenceConstants.DEFAULT_OPTIONS_MAP.get(optionName), |
| contexts); |
| } |
| |
| public static String getGenSrcDir(IJavaProject jproject) { |
| String genSrcDir = getString(jproject, AptPreferenceConstants.APT_GENSRCDIR); |
| if (genSrcDir == null) { |
| throw new IllegalStateException("Generated Source Directory was null."); //$NON-NLS-1$ |
| } |
| return genSrcDir; |
| } |
| |
| public static void setGenSrcDir(IJavaProject jproject, String dirString) { |
| if (dirString == null) { |
| throw new IllegalArgumentException("Cannot set the Generated Source Directory to null"); //$NON-NLS-1$ |
| } |
| setString(jproject, AptPreferenceConstants.APT_GENSRCDIR, dirString); |
| } |
| |
| private static void setBoolean(IJavaProject jproject, String optionName, boolean value) { |
| IScopeContext context = (null != jproject) ? |
| new ProjectScope(jproject.getProject()) : new InstanceScope(); |
| IEclipsePreferences node = context.getNode(AptPlugin.PLUGIN_ID); |
| // get old val as a String, so it can be null if setting doesn't exist yet |
| String oldValue = node.get(optionName, null); |
| node.putBoolean(optionName, value); |
| if (jproject != null) { |
| AptProject aproj = AptPlugin.getAptProject(jproject); |
| aproj.handlePreferenceChange(optionName, oldValue, Boolean.toString(value)); |
| } |
| flushPreference(optionName, node); |
| } |
| |
| private static void setString(IJavaProject jproject, String optionName, String value) { |
| IScopeContext context = (null != jproject) ? |
| new ProjectScope(jproject.getProject()) : new InstanceScope(); |
| IEclipsePreferences node = context.getNode(AptPlugin.PLUGIN_ID); |
| String oldValue = node.get(optionName, null); |
| node.put(optionName, value); |
| if (jproject != null) { |
| AptProject aproj = AptPlugin.getAptProject(jproject); |
| aproj.handlePreferenceChange(optionName, oldValue, value); |
| } |
| flushPreference(optionName, node); |
| } |
| |
| private static void flushPreference(String optionName, IEclipsePreferences node) { |
| try { |
| node.flush(); |
| } |
| catch (BackingStoreException e){ |
| AptPlugin.log(e, "Failed to save preference: " + optionName); //$NON-NLS-1$ |
| } |
| } |
| |
| } |