Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*******************************************************************************
* Copyright (c) 2004, 2022 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
* Markus Schorn (Wind River) - [108066] Project prefs marked dirty on read
* James Blackburn (Broadcom Corp.) - ongoing development
* Lars Vogel - Bug 473427, 483529
* Christoph Läubrich - Issue #124
*******************************************************************************/
package org.eclipse.core.internal.resources;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import org.eclipse.core.internal.preferences.EclipsePreferences;
import org.eclipse.core.internal.preferences.ExportedPreferences;
import org.eclipse.core.internal.preferences.PreferencesService;
import org.eclipse.core.internal.preferences.SortedProperties;
import org.eclipse.core.internal.utils.Messages;
import org.eclipse.core.internal.utils.Policy;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceRuleFactory;
import org.eclipse.core.resources.IResourceStatus;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ICoreRunnable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.MultiRule;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IExportedPreferences;
import org.eclipse.osgi.util.NLS;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
/**
* Represents a node in the Eclipse preference hierarchy which stores preference
* values for projects.
*
* @since 3.0
*/
public class ProjectPreferences extends EclipsePreferences {
static final String PREFS_REGULAR_QUALIFIER = ResourcesPlugin.PI_RESOURCES;
static final String PREFS_DERIVED_QUALIFIER = PREFS_REGULAR_QUALIFIER + ".derived"; //$NON-NLS-1$
static final String PLACEHOLDER = ""; //$NON-NLS-1$
/**
* Cache which nodes have been loaded from disk
*/
protected static Set loadedNodes = Collections.synchronizedSet(new HashSet<>());
private IFile file;
private boolean initialized = false;
/**
* Flag indicating that this node is currently reading values from disk,
* to avoid flushing during a read.
*/
private boolean isReading;
/**
* Flag indicating that this node is currently writing values to disk,
* to avoid re-reading after the write completes.
*/
private boolean isWriting;
private IEclipsePreferences loadLevel;
private IProject project;
private String qualifier;
// cache
private int segmentCount;
private Workspace workspace;
static void deleted(IFile file) throws CoreException {
IPath path = file.getFullPath();
int count = path.segmentCount();
if (count != 3)
return;
// check if we are in the .settings directory
if (!EclipsePreferences.DEFAULT_PREFERENCES_DIRNAME.equals(path.segment(1)))
return;
Preferences root = Platform.getPreferencesService().getRootNode();
String project = path.segment(0);
String qualifier = path.removeFileExtension().lastSegment();
ProjectPreferences projectNode = (ProjectPreferences) root.node(ProjectScope.SCOPE).node(project);
// if the node isn't known then just return
try {
if (!projectNode.nodeExists(qualifier))
return;
} catch (BackingStoreException e) {
// ignore
}
// clear the preferences
clearNode(projectNode.node(qualifier));
// notifies the CharsetManager if needed
if (qualifier.equals(PREFS_REGULAR_QUALIFIER) || qualifier.equals(PREFS_DERIVED_QUALIFIER))
preferencesChanged(file.getProject());
}
static void deleted(IFolder folder) throws CoreException {
IPath path = folder.getFullPath();
int count = path.segmentCount();
if (count != 2)
return;
// check if we are the .settings directory
if (!EclipsePreferences.DEFAULT_PREFERENCES_DIRNAME.equals(path.segment(1)))
return;
Preferences root = Platform.getPreferencesService().getRootNode();
// The settings dir has been removed/moved so remove all project prefs
// for the resource.
String project = path.segment(0);
Preferences projectNode = root.node(ProjectScope.SCOPE).node(project);
// check if we need to notify the charset manager
boolean hasResourcesSettings = getFile(folder, PREFS_REGULAR_QUALIFIER).exists() || getFile(folder, PREFS_DERIVED_QUALIFIER).exists();
// remove the preferences
removeNode(projectNode);
// notifies the CharsetManager
if (hasResourcesSettings)
preferencesChanged(folder.getProject());
}
/*
* The whole project has been removed so delete all of the project settings
*/
static void deleted(IProject project) throws CoreException {
// The settings dir has been removed/moved so remove all project prefs
// for the resource. We have to do this now because (since we aren't
// synchronizing) there is short-circuit code that doesn't visit the
// children.
Preferences root = Platform.getPreferencesService().getRootNode();
Preferences projectNode = root.node(ProjectScope.SCOPE).node(project.getName());
// check if we need to notify the charset manager
boolean hasResourcesSettings = getFile(project, PREFS_REGULAR_QUALIFIER).exists() || getFile(project, PREFS_DERIVED_QUALIFIER).exists();
// remove the preferences
removeNode(projectNode);
// notifies the CharsetManager
if (hasResourcesSettings)
preferencesChanged(project);
}
static void deleted(IResource resource) throws CoreException {
switch (resource.getType()) {
case IResource.FILE :
deleted((IFile) resource);
return;
case IResource.FOLDER :
deleted((IFolder) resource);
return;
case IResource.PROJECT :
deleted((IProject) resource);
return;
}
}
/*
* Return the preferences file for the given folder and qualifier.
*/
static IFile getFile(IFolder folder, String qualifier) {
Assert.isLegal(folder.getName().equals(DEFAULT_PREFERENCES_DIRNAME));
return folder.getFile(IPath.fromOSString(qualifier).addFileExtension(PREFS_FILE_EXTENSION));
}
/*
* Return the preferences file for the given project and qualifier.
*/
static IFile getFile(IProject project, String qualifier) {
return project.getFile(IPath.fromOSString(DEFAULT_PREFERENCES_DIRNAME).append(qualifier).addFileExtension(PREFS_FILE_EXTENSION));
}
private static Properties loadProperties(IFile file) throws BackingStoreException {
if (Policy.DEBUG_PREFERENCES)
Policy.debug("Loading preferences from file: " + file.getFullPath()); //$NON-NLS-1$
Properties result = new Properties();
try (
InputStream input = new BufferedInputStream(file.getContents(true));
) {
result.load(input);
} catch (CoreException e) {
if (e.getStatus().getCode() == IResourceStatus.RESOURCE_NOT_FOUND) {
if (Policy.DEBUG_PREFERENCES)
Policy.debug(MessageFormat.format("Preference file {0} does not exist.", file.getFullPath())); //$NON-NLS-1$
} else {
String message = NLS.bind(Messages.preferences_loadException, file.getFullPath());
log(new Status(IStatus.ERROR, ResourcesPlugin.PI_RESOURCES, IStatus.ERROR, message, e));
throw new BackingStoreException(message);
}
} catch (IOException e) {
String message = NLS.bind(Messages.preferences_loadException, file.getFullPath());
log(new Status(IStatus.ERROR, ResourcesPlugin.PI_RESOURCES, IStatus.ERROR, message, e));
throw new BackingStoreException(message);
}
return result;
}
private static void preferencesChanged(IProject project) {
Workspace workspace = (Workspace) project.getWorkspace();
workspace.getCharsetManager().projectPreferencesChanged(project);
workspace.getContentDescriptionManager().projectPreferencesChanged(project);
}
private static void read(ProjectPreferences node, IFile file) throws BackingStoreException, CoreException {
if (file == null || !file.exists()) {
if (Policy.DEBUG_PREFERENCES)
Policy.debug("Unable to determine preference file or file does not exist for node: " + node.absolutePath()); //$NON-NLS-1$
return;
}
// Create special "overriding" preferences to be applied
ExportedPreferences myNode = overridingPreferences(node, file);
// flag that we are currently reading, to avoid unnecessary writing
boolean oldIsReading = node.isReading;
node.isReading = true;
try {
Platform.getPreferencesService().applyPreferences(myNode);
} finally {
node.isReading = oldIsReading;
}
}
/**
* Creates new preferences node from given file that can be used to apply via
* preferences service and override the current in-memory preferences state.
*
* @param current in-memory state
* @param file new state on the disk to be loaded
* @return new node that contains everything required to apply new state
* @throws BackingStoreException
* @see PreferencesService#applyPreferences(IExportedPreferences)
*/
private static ExportedPreferences overridingPreferences(ProjectPreferences current, IFile file)
throws BackingStoreException {
Properties fromDisk = loadProperties(file);
Properties fromMemory = new Properties();
current.convertToProperties(fromMemory, ""); //$NON-NLS-1$
// Re-create all the child elements existing in memory but not in the file
// in the node to be applied to preferences, so we can delete previously
// existing node values
Set> set = fromMemory.entrySet();
for (Entry