/******************************************************************************* * Copyright (c) 2000, 2017 IBM Corporation and others. * 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: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.dltk.internal.core; import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.dltk.core.DLTKCore; import org.eclipse.dltk.core.DLTKLanguageManager; import org.eclipse.dltk.core.IBuildpathContainer; import org.eclipse.dltk.core.IBuildpathEntry; import org.eclipse.dltk.core.IDLTKLanguageToolkit; import org.eclipse.dltk.core.IScriptProject; import org.eclipse.dltk.core.ModelException; import org.eclipse.dltk.internal.core.util.Util; import org.osgi.service.prefs.BackingStoreException; /** * */ public class UserLibraryManager { public final static String BP_USERLIBRARY_PREFERENCES_PREFIX = DLTKCore.PLUGIN_ID + ".userLibrary."; //$NON-NLS-1$ private final Map<String, UserLibrary> userLibraries = new HashMap<>(); public UserLibraryManager() { initialize(); } /* * Gets the library for a given name or <code>null</code> if no such library * exists. */ public UserLibrary getUserLibrary(String libName, IDLTKLanguageToolkit toolkit) { synchronized (userLibraries) { return userLibraries.get(makeLibraryName(libName, toolkit)); } } public static String makeLibraryName(String libName, IDLTKLanguageToolkit toolkit) { if (toolkit == null) { return "#" + libName; //$NON-NLS-1$ } return toolkit.getNatureId() + "#" + libName; //$NON-NLS-1$ } private String getLibraryName(String key) { int pos = key.indexOf("#"); //$NON-NLS-1$ if (pos != -1) { return key.substring(pos + 1); } return key; } private IDLTKLanguageToolkit getToolkitFromKey(String key) { int pos = key.indexOf("#"); //$NON-NLS-1$ if (pos != -1) { String nature = key.substring(0, pos); return DLTKLanguageManager.getLanguageToolkit(nature); } return null; } /* * Returns the names of all defined user libraries. The corresponding * classpath container path is the name appended to the CONTAINER_ID. */ public String[] getUserLibraryNames(IDLTKLanguageToolkit toolkit) { final Set<String> result = new HashSet<>(); synchronized (userLibraries) { for (String key : userLibraries.keySet()) { int pos = key.indexOf("#"); //$NON-NLS-1$ if (pos != -1) { String nature = key.substring(0, pos); if (toolkit.getNatureId().equals(nature)) { result.add(getLibraryName(key)); } } } } return result.toArray(new String[result.size()]); } private void initialize() { IEclipsePreferences instancePreferences = ModelManager.getModelManager() .getInstancePreferences(); String[] propertyNames; try { propertyNames = instancePreferences.keys(); } catch (BackingStoreException e) { Util.log(e, "Exception while initializing user libraries"); //$NON-NLS-1$ return; } boolean preferencesNeedFlush = false; for (int i = 0, length = propertyNames.length; i < length; i++) { String propertyName = propertyNames[i]; if (propertyName.startsWith(BP_USERLIBRARY_PREFERENCES_PREFIX)) { String propertyValue = instancePreferences.get(propertyName, null); if (propertyValue != null) { String libName = propertyName.substring( BP_USERLIBRARY_PREFERENCES_PREFIX.length()); StringReader reader = new StringReader(propertyValue); UserLibrary library; try { library = UserLibrary.createFromString(reader); } catch (IOException e) { Util.log(e, "Exception while initializing user library " //$NON-NLS-1$ + libName); instancePreferences.remove(propertyName); preferencesNeedFlush = true; continue; } this.userLibraries.put(libName, library); } } } if (preferencesNeedFlush) { try { instancePreferences.flush(); } catch (BackingStoreException e) { Util.log(e, "Exception while flusing instance preferences"); //$NON-NLS-1$ } } } public void updateUserLibrary(String libName, String encodedUserLibrary) { try { // find affected projects IPath containerPath = new Path(DLTKCore.USER_LIBRARY_CONTAINER_ID) .append(getLibraryName(libName)); IScriptProject[] allJavaProjects = DLTKCore .create(ResourcesPlugin.getWorkspace().getRoot()) .getScriptProjects(); ArrayList affectedProjects = new ArrayList(); for (int i = 0; i < allJavaProjects.length; i++) { IScriptProject javaProject = allJavaProjects[i]; IBuildpathEntry[] entries = javaProject.getRawBuildpath(); for (int j = 0; j < entries.length; j++) { IBuildpathEntry entry = entries[j]; if (entry.getEntryKind() == IBuildpathEntry.BPE_CONTAINER) { if (containerPath.equals(entry.getPath())) { affectedProjects.add(javaProject); break; } } } } // decode user library UserLibrary userLibrary = encodedUserLibrary == null ? null : UserLibrary.createFromString( new StringReader(encodedUserLibrary)); // update user libraries map synchronized (userLibraries) { if (userLibrary != null) { userLibraries.put(libName, userLibrary); } else { userLibraries.remove(libName); } } // update affected projects int length = affectedProjects.size(); if (length == 0) return; IScriptProject[] projects = new IScriptProject[length]; affectedProjects.toArray(projects); IBuildpathContainer[] containers = new IBuildpathContainer[length]; IDLTKLanguageToolkit toolkit = getToolkitFromKey(libName); if (userLibrary != null && toolkit != null) { UserLibraryBuildpathContainer container = new UserLibraryBuildpathContainer( getLibraryName(libName), toolkit); for (int i = 0; i < length; i++) { containers[i] = container; } } DLTKCore.setBuildpathContainer(containerPath, projects, containers, null); } catch (IOException e) { Util.log(e, "Exception while decoding user library '" + libName + "'."); //$NON-NLS-1$ //$NON-NLS-2$ } catch (ModelException e) { Util.log(e, "Exception while setting user library '" + libName + "'."); //$NON-NLS-1$ //$NON-NLS-2$ } } public void removeUserLibrary(String libName, IDLTKLanguageToolkit toolkit) { IEclipsePreferences instancePreferences = ModelManager.getModelManager() .getInstancePreferences(); String propertyName = BP_USERLIBRARY_PREFERENCES_PREFIX + makeLibraryName(libName, toolkit); instancePreferences.remove(propertyName); try { instancePreferences.flush(); } catch (BackingStoreException e) { Util.log(e, "Exception while removing user library " + libName); //$NON-NLS-1$ } // this.userLibraries was updated during the PreferenceChangeEvent (see // preferenceChange(...)) } public void setUserLibrary(String libName, IBuildpathEntry[] entries, boolean isSystemLibrary, IDLTKLanguageToolkit toolkit) { setUserLibrary(libName, entries, isSystemLibrary, null, toolkit); } public void setUserLibrary(String libName, IBuildpathEntry[] entries, boolean isSystemLibrary, Map<String, String> attributes, IDLTKLanguageToolkit toolkit) { IEclipsePreferences instancePreferences = ModelManager.getModelManager() .getInstancePreferences(); String propertyName = BP_USERLIBRARY_PREFERENCES_PREFIX + makeLibraryName(libName, toolkit); try { String propertyValue = UserLibrary.serialize(entries, isSystemLibrary, attributes); instancePreferences.put(propertyName, propertyValue); // sends out // a // PreferenceChangeEvent // (see // preferenceChange(...)) } catch (IOException e) { Util.log(e, "Exception while serializing user library " + libName); //$NON-NLS-1$ return; } try { instancePreferences.flush(); } catch (BackingStoreException e) { Util.log(e, "Exception while saving user library " + libName); //$NON-NLS-1$ } // this.userLibraries was updated during the PreferenceChangeEvent (see // preferenceChange(...)) } }