| /******************************************************************************* |
| * Copyright (c) 2000, 2004 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Common Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/cpl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.core; |
| |
| import java.io.IOException; |
| import java.io.StringReader; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.Set; |
| import org.eclipse.core.resources.IWorkspaceRoot; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Preferences; |
| import org.eclipse.core.runtime.SubProgressMonitor; |
| import org.eclipse.core.runtime.Preferences.IPropertyChangeListener; |
| import org.eclipse.core.runtime.Preferences.PropertyChangeEvent; |
| import org.eclipse.jdt.core.IClasspathContainer; |
| 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.eclipse.jdt.internal.core.util.Util; |
| |
| /** |
| * |
| */ |
| public class UserLibraryManager { |
| |
| public final static String CP_USERLIBRARY_PREFERENCES_PREFIX = JavaCore.PLUGIN_ID+".userLibrary."; //$NON-NLS-1$ |
| public final static String CP_ENTRY_IGNORE = "##<cp entry ignore>##"; //$NON-NLS-1$ |
| |
| private static Map userLibraries; |
| private static final boolean logProblems= false; |
| private static IPropertyChangeListener listener= new IPropertyChangeListener() { |
| |
| public void propertyChange(PropertyChangeEvent event) { |
| String key= event.getProperty(); |
| if (key.startsWith(CP_USERLIBRARY_PREFERENCES_PREFIX)) { |
| try { |
| recreatePersistedUserLibraryEntry(key, (String) event.getNewValue(), false, true); |
| } catch (JavaModelException e) { |
| if (logProblems) { |
| Util.log(e, "Exception while rebinding user library '"+ key.substring(CP_USERLIBRARY_PREFERENCES_PREFIX.length()) +"'."); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| } |
| } |
| } |
| |
| }; |
| |
| private UserLibraryManager() { |
| // do not instantiate |
| } |
| |
| /** |
| * Returns the names of all defined user libraries. The corresponding classpath container path |
| * is the name appended to the CONTAINER_ID. |
| * @return Return an array containing the names of all known user defined. |
| */ |
| public static String[] getUserLibraryNames() { |
| Set set= getLibraryMap().keySet(); |
| return (String[]) set.toArray(new String[set.size()]); |
| } |
| |
| /** |
| * Gets the library for a given name or <code>null</code> if no such library exists. |
| * @param name The name of the library |
| * @return The library registered for the given name or <code>null</code>. |
| */ |
| public static IClasspathContainer getUserLibrary(String name) { |
| return (IClasspathContainer) getLibraryMap().get(name); |
| } |
| |
| /** |
| * Registers user libraries for given names. If a library for the given name already exists, its value will be updated. |
| * This call will also rebind all related classpath container. |
| * @param newNames The names to register the libraries for |
| * @param newLibs The libraries to register |
| * @param monitor A progress monitor used when rebinding the classpath containers |
| * @throws JavaModelException |
| */ |
| public static void setUserLibraries(String[] newNames, UserLibrary[] newLibs, IProgressMonitor monitor) throws JavaModelException { |
| Assert.isTrue(newNames.length == newLibs.length, "names and libraries should have the same length"); //$NON-NLS-1$ |
| |
| if (monitor == null) { |
| monitor= new NullProgressMonitor(); |
| } |
| |
| monitor.beginTask("Configure user libraries...", newNames.length); //$NON-NLS-1$ |
| try { |
| int last= newNames.length - 1; |
| for (int i= 0; i < newLibs.length; i++) { |
| internalSetUserLibrary(newNames[i], newLibs[i], i == last, true, new SubProgressMonitor(monitor, 1)); |
| } |
| } finally { |
| monitor.done(); |
| } |
| } |
| |
| /** |
| * Registers a user library for a given name. If a library for the given name already exists, its value will be updated. |
| * This call will also rebind all related classpath container. |
| * @param name The name to register the library for |
| * @param library The library to register |
| * @param monitor A progress monitor used when rebinding the classpath containers |
| * @throws JavaModelException |
| */ |
| public static void setUserLibrary(String name, UserLibrary library, IProgressMonitor monitor) throws JavaModelException { |
| internalSetUserLibrary(name, library, true, true, monitor); |
| } |
| |
| static Map getLibraryMap() { |
| if (userLibraries == null) { |
| userLibraries= new HashMap(); |
| // load variables and containers from preferences into cache |
| Preferences preferences = JavaCore.getPlugin().getPluginPreferences(); |
| preferences.addPropertyChangeListener(listener); |
| |
| // only get variable from preferences not set to their default |
| String[] propertyNames = preferences.propertyNames(); |
| for (int i = 0; i < propertyNames.length; i++) { |
| String propertyName = propertyNames[i]; |
| if (propertyName.startsWith(CP_USERLIBRARY_PREFERENCES_PREFIX)) { |
| try { |
| recreatePersistedUserLibraryEntry(propertyName, preferences.getString(propertyName), false, false); |
| } catch (JavaModelException e) { |
| // won't happen: no rebinding |
| } |
| } |
| } |
| } |
| return userLibraries; |
| } |
| |
| static void recreatePersistedUserLibraryEntry(String propertyName, String savedString, boolean save, boolean rebind) throws JavaModelException { |
| String libName= propertyName.substring(CP_USERLIBRARY_PREFERENCES_PREFIX.length()); |
| if (savedString == null || savedString.equals(CP_ENTRY_IGNORE)) { |
| internalSetUserLibrary(libName, null, save, rebind, null); |
| } else { |
| try { |
| StringReader reader = new StringReader(savedString); |
| UserLibrary library= UserLibrary.createFromString(reader); |
| internalSetUserLibrary(libName, library, save, rebind, null); |
| } catch (IOException e) { |
| if (logProblems) { |
| Util.log(e, "Exception while retrieving user library '"+ propertyName +"', library will be removed."); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| internalSetUserLibrary(libName, null, save, rebind, null); |
| } |
| } |
| } |
| |
| |
| |
| static void internalSetUserLibrary(String name, UserLibrary library, boolean save, boolean rebind, IProgressMonitor monitor) throws JavaModelException { |
| if (library == null) { |
| Object previous= getLibraryMap().remove(name); |
| if (previous == null) { |
| return; // no change |
| } |
| } else { |
| Object previous= getLibraryMap().put(name, library); |
| if (library.equals(previous)) { |
| return; // no change |
| } |
| } |
| |
| Preferences preferences = JavaCore.getPlugin().getPluginPreferences(); |
| String containerKey = CP_USERLIBRARY_PREFERENCES_PREFIX+name; |
| String containerString = CP_ENTRY_IGNORE; |
| if (library != null) { |
| try { |
| containerString= library.serialize(); |
| } catch (IOException e) { |
| // could not encode entry: leave it as CP_ENTRY_IGNORE |
| } |
| } |
| preferences.removePropertyChangeListener(listener); |
| try { |
| preferences.setDefault(containerKey, CP_ENTRY_IGNORE); // use this default to get rid of removed ones |
| preferences.setValue(containerKey, containerString); |
| if (save) { |
| JavaCore.getPlugin().savePluginPreferences(); |
| } |
| if (rebind) { |
| rebindClasspathEntries(name, monitor); |
| } |
| |
| } finally { |
| preferences.addPropertyChangeListener(listener); |
| } |
| } |
| |
| private static void rebindClasspathEntries(String name, IProgressMonitor monitor) throws JavaModelException { |
| IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot(); |
| IJavaProject[] projects= JavaCore.create(root).getJavaProjects(); |
| IPath containerPath= new Path(JavaCore.USER_LIBRARY_CONTAINER_ID).append(name); |
| |
| ArrayList affectedProjects= new ArrayList(); |
| |
| for (int i= 0; i < projects.length; i++) { |
| IJavaProject project= projects[i]; |
| IClasspathEntry[] entries= project.getRawClasspath(); |
| for (int k= 0; k < entries.length; k++) { |
| IClasspathEntry curr= entries[k]; |
| if (curr.getEntryKind() == IClasspathEntry.CPE_CONTAINER) { |
| if (containerPath.equals(curr.getPath())) { |
| affectedProjects.add(project); |
| break; |
| } |
| } |
| } |
| } |
| if (!affectedProjects.isEmpty()) { |
| IJavaProject[] affected= (IJavaProject[]) affectedProjects.toArray(new IJavaProject[affectedProjects.size()]); |
| IClasspathContainer[] containers= new IClasspathContainer[affected.length]; |
| |
| JavaCore.setClasspathContainer(containerPath, affected, containers, monitor); |
| } else { |
| if (monitor != null) { |
| monitor.done(); |
| } |
| } |
| } |
| |
| |
| |
| } |