blob: 9d7bc7e328496a991e88c869d8e8dd8bee8fe6d1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2017 IBM Corporation and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
* 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(...))
}
}