1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-01 14:15:23 +02:00

Move the persistency of the PathEntry in a different class

and provide an extension point for it.
This commit is contained in:
Alain Magloire 2004-04-26 04:44:29 +00:00
parent e0706f6786
commit d83f3ab70e
9 changed files with 639 additions and 325 deletions

View file

@ -1,3 +1,17 @@
2004-04-26 Alain Magloire
Move the persistency of the IPathEntry in a differenct
class and provide an extension point for it.
* plugin.xml
* model/org/eclipse/cdt/internal/core/model/CProject.java
* model/org/eclipse/cdt/internal/core/model/PathEntryManager.java
* model/org/eclipse/cdt/internal/core/model/PathEntryStore.java
* src/org/eclipe/cdt/core/CCorePlugin.java
* src/org/eclipse/cdt/internal/core/resources/IPathEntryStore.java
* src/org/eclipse/cdt/internal/core/resources/IPathEntryStoreListener.java
* src/org/eclipse/cdt/internal/core/resources/PathEntryStoreChangedEvent.java
2004-04-23 Alain Magloire
Tentative fix for PR 59098.

View file

@ -13,10 +13,10 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.core.BinaryParserConfig;
import org.eclipse.cdt.core.CCProjectNature;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CProjectNature;
import org.eclipse.cdt.core.IBinaryParser;
import org.eclipse.cdt.core.IBinaryParser.IBinaryArchive;
import org.eclipse.cdt.core.IBinaryParser.IBinaryFile;
import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
@ -150,17 +150,13 @@ public class CProject extends Openable implements ICProject {
}
public ILibraryReference[] getLibraryReferences() throws CModelException {
IBinaryParser[] binParsers = null;
try {
binParsers = CCorePlugin.getDefault().getBinaryParser(getProject());
} catch (CoreException e) {
}
BinaryParserConfig[] binConfigs = CModelManager.getDefault().getBinaryParser(getProject());
IPathEntry[] entries = getResolvedPathEntries();
ArrayList list = new ArrayList(entries.length);
for (int i = 0; i < entries.length; i++) {
if (entries[i].getEntryKind() == IPathEntry.CDT_LIBRARY) {
ILibraryEntry entry = (ILibraryEntry) entries[i];
ILibraryReference lib = getLibraryReference(this, binParsers, entry);
ILibraryReference lib = getLibraryReference(this, binConfigs, entry);
if (lib != null) {
list.add(lib);
}
@ -169,19 +165,16 @@ public class CProject extends Openable implements ICProject {
return (ILibraryReference[]) list.toArray(new ILibraryReference[0]);
}
public static ILibraryReference getLibraryReference(ICProject cproject, IBinaryParser[] binParsers, ILibraryEntry entry) {
if (binParsers == null) {
try {
binParsers = CCorePlugin.getDefault().getBinaryParser(cproject.getProject());
} catch (CoreException e) {
}
public static ILibraryReference getLibraryReference(ICProject cproject, BinaryParserConfig[] binConfigs, ILibraryEntry entry) {
if (binConfigs == null) {
binConfigs = CModelManager.getDefault().getBinaryParser(cproject.getProject());
}
ILibraryReference lib = null;
if (binParsers != null) {
for (int i = 0; i < binParsers.length; i++) {
if (binConfigs != null) {
for (int i = 0; i < binConfigs.length; i++) {
IBinaryFile bin;
try {
bin = binParsers[i].getBinary(entry.getPath());
bin = binConfigs[i].getBinaryParser().getBinary(entry.getPath());
if (bin != null) {
if (bin.getType() == IBinaryFile.ARCHIVE) {
lib = new LibraryReferenceArchive(cproject, entry, (IBinaryArchive)bin);

View file

@ -16,17 +16,14 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CDescriptorEvent;
import org.eclipse.cdt.core.ICDescriptor;
import org.eclipse.cdt.core.ICDescriptorListener;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ElementChangedEvent;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICElementDelta;
import org.eclipse.cdt.core.model.ICModelStatus;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.IContainerEntry;
import org.eclipse.cdt.core.model.IElementChangedListener;
import org.eclipse.cdt.core.model.IIncludeEntry;
import org.eclipse.cdt.core.model.ILibraryEntry;
import org.eclipse.cdt.core.model.IMacroEntry;
@ -36,7 +33,9 @@ import org.eclipse.cdt.core.model.IPathEntryContainer;
import org.eclipse.cdt.core.model.IProjectEntry;
import org.eclipse.cdt.core.model.ISourceEntry;
import org.eclipse.cdt.core.model.PathEntryContainerInitializer;
import org.eclipse.cdt.internal.core.CharOperation;
import org.eclipse.cdt.core.resources.IPathEntryStore;
import org.eclipse.cdt.core.resources.IPathEntryStoreListener;
import org.eclipse.cdt.core.resources.PathEntryStoreChangedEvent;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.runtime.CoreException;
@ -49,35 +48,14 @@ import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* @author alain
*
*/
public class PathEntryManager implements ICDescriptorListener {
public class PathEntryManager implements IPathEntryStoreListener, IElementChangedListener {
static String CONTAINER_INITIALIZER_EXTPOINT_ID = "pathEntryContainerInitializer"; //$NON-NLS-1$
static String PATH_ENTRY = "pathentry"; //$NON-NLS-1$
static String PATH_ENTRY_ID = "org.eclipse.cdt.core.pathentry"; //$NON-NLS-1$
static String ATTRIBUTE_KIND = "kind"; //$NON-NLS-1$
static String ATTRIBUTE_PATH = "path"; //$NON-NLS-1$
static String ATTRIBUTE_BASE_PATH = "base-path"; //$NON-NLS-1$
static String ATTRIBUTE_BASE_REF = "base-ref"; //$NON-NLS-1$
static String ATTRIBUTE_EXPORTED = "exported"; //$NON-NLS-1$
static String ATTRIBUTE_SOURCEPATH = "sourcepath"; //$NON-NLS-1$
static String ATTRIBUTE_ROOTPATH = "roopath"; //$NON-NLS-1$
static String ATTRIBUTE_PREFIXMAPPING = "prefixmapping"; //$NON-NLS-1$
static String ATTRIBUTE_EXCLUDING = "excluding"; //$NON-NLS-1$
static String ATTRIBUTE_INCLUDE = "include"; //$NON-NLS-1$
static String ATTRIBUTE_SYSTEM = "system"; //$NON-NLS-1$
static String ATTRIBUTE_NAME = "name"; //$NON-NLS-1$
static String ATTRIBUTE_VALUE = "value"; //$NON-NLS-1$
static String VALUE_TRUE = "true"; //$NON-NLS-1$
final static IPathEntry[] EMPTY = {};
/**
* An empty array of strings indicating that a project doesn't have any prerequesite projects.
*/
@ -90,8 +68,10 @@ public class PathEntryManager implements ICDescriptorListener {
static final IPathEntry[] NO_PATHENTRIES = new IPathEntry[0];
HashMap resolvedMap = new HashMap();
private static PathEntryManager pathEntryManager;
HashMap storeMap = new HashMap();
private static PathEntryManager pathEntryManager;
private PathEntryManager() {
}
@ -101,10 +81,7 @@ public class PathEntryManager implements ICDescriptorListener {
public static PathEntryManager getDefault() {
if (pathEntryManager == null) {
pathEntryManager = new PathEntryManager();
// Register the Core Model on the Descriptor
// Manager, it needs to know about changes.
CCorePlugin.getDefault().getCDescriptorManager().addDescriptorListener(pathEntryManager);
CoreModel.getDefault().addElementChangedListener(pathEntryManager);
}
return pathEntryManager;
}
@ -228,23 +205,14 @@ public class PathEntryManager implements ICDescriptorListener {
}
public IPathEntry[] getRawPathEntries(ICProject cproject) throws CModelException {
CModelManager factory = CModelManager.getDefault();
if (!(CoreModel.hasCNature(cproject.getProject()) || CoreModel.hasCCNature(cproject.getProject()))) {
IProject project = cproject.getProject();
if (!(CoreModel.hasCNature(project) || CoreModel.hasCCNature(project))) {
return NO_PATHENTRIES;
}
ArrayList pathEntries = new ArrayList();
IPathEntry[] pathEntries = NO_PATHENTRIES;
try {
ICDescriptor cdesc = CCorePlugin.getDefault().getCProjectDescription(cproject.getProject());
Element element = cdesc.getProjectData(PATH_ENTRY_ID);
NodeList list = element.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
Node childNode = list.item(i);
if (childNode.getNodeType() == Node.ELEMENT_NODE) {
if (childNode.getNodeName().equals(PATH_ENTRY)) {
pathEntries.add(decodePathEntry(cproject, (Element) childNode));
}
}
}
IPathEntryStore store = getPathEntryStore(project);
pathEntries = store.getRawPathEntries(project);
} catch (CoreException e) {
throw new CModelException(e);
}
@ -254,8 +222,8 @@ public class PathEntryManager implements ICDescriptorListener {
// if no source is specified we return the project
boolean foundSource = false;
boolean foundOutput = false;
for (int i = 0; i < pathEntries.size(); i++) {
IPathEntry rawEntry = (IPathEntry) pathEntries.get(i);
for (int i = 0; i < pathEntries.length; i++) {
IPathEntry rawEntry = (IPathEntry) pathEntries[i];
if (rawEntry.getEntryKind() == IPathEntry.CDT_SOURCE) {
foundSource = true;
}
@ -265,12 +233,18 @@ public class PathEntryManager implements ICDescriptorListener {
}
if (!foundSource) {
pathEntries.add(CoreModel.newSourceEntry(cproject.getPath()));
IPathEntry[] newEntries = new IPathEntry[pathEntries.length + 1];
System.arraycopy(pathEntries, 0, newEntries, 0, pathEntries.length);
newEntries[pathEntries.length] = CoreModel.newSourceEntry(cproject.getPath());
pathEntries = newEntries;
}
if (!foundOutput) {
pathEntries.add(CoreModel.newOutputEntry(cproject.getPath()));
IPathEntry[] newEntries = new IPathEntry[pathEntries.length + 1];
System.arraycopy(pathEntries, 0, newEntries, 0, pathEntries.length);
newEntries[pathEntries.length] = CoreModel.newOutputEntry(cproject.getPath());
pathEntries = newEntries;
}
return (IPathEntry[]) pathEntries.toArray(EMPTY);
return pathEntries;
}
public void setPathEntryContainer(ICProject[] affectedProjects, IPathEntryContainer newContainer, IProgressMonitor monitor)
@ -486,21 +460,9 @@ public class PathEntryManager implements ICDescriptorListener {
public void saveRawPathEntries(ICProject cproject, IPathEntry[] newRawEntries) throws CModelException {
try {
ICDescriptor descriptor = CCorePlugin.getDefault().getCProjectDescription(cproject.getProject());
Element rootElement = descriptor.getProjectData(PATH_ENTRY_ID);
// Clear out all current children
Node child = rootElement.getFirstChild();
while (child != null) {
rootElement.removeChild(child);
child = rootElement.getFirstChild();
}
// Save the entries
if (newRawEntries != null && newRawEntries.length > 0) {
// Serialize the include paths
Document doc = rootElement.getOwnerDocument();
encodePathEntries(cproject.getPath(), doc, rootElement, newRawEntries);
}
descriptor.saveProjectData();
IProject project = cproject.getProject();
IPathEntryStore store = getPathEntryStore(project);
store.setRawPathEntries(project, newRawEntries);
resolvedMap.remove(cproject);
} catch (CoreException e) {
throw new CModelException(e);
@ -653,255 +615,70 @@ public class PathEntryManager implements ICDescriptorListener {
return containerIDs;
}
static IPathEntry decodePathEntry(ICProject cProject, Element element) throws CModelException {
IPath projectPath = cProject.getProject().getFullPath();
// kind
String kindAttr = element.getAttribute(ATTRIBUTE_KIND);
int kind = PathEntry.kindFromString(kindAttr);
// exported flag
boolean isExported = false;
if (element.hasAttribute(ATTRIBUTE_EXPORTED)) {
isExported = element.getAttribute(ATTRIBUTE_EXPORTED).equals(VALUE_TRUE);
}
// get path and ensure it is absolute
//String pathAttr = element.getAttribute(ATTRIBUTE_PATH);
IPath path = new Path(element.getAttribute(ATTRIBUTE_PATH));
if (!path.isAbsolute()) {
path = projectPath.append(path);
}
// check fo the base path
IPath basePath = new Path(element.getAttribute(ATTRIBUTE_BASE_PATH));
// get the base ref
IPath baseRef = new Path(element.getAttribute(ATTRIBUTE_BASE_REF));
// source attachment info (optional)
IPath sourceAttachmentPath = element.hasAttribute(ATTRIBUTE_SOURCEPATH) ? new Path(
element.getAttribute(ATTRIBUTE_SOURCEPATH)) : null;
IPath sourceAttachmentRootPath = element.hasAttribute(ATTRIBUTE_ROOTPATH) ? new Path(
element.getAttribute(ATTRIBUTE_ROOTPATH)) : null;
IPath sourceAttachmentPrefixMapping = element.hasAttribute(ATTRIBUTE_PREFIXMAPPING) ? new Path(
element.getAttribute(ATTRIBUTE_PREFIXMAPPING)) : null;
// exclusion patterns (optional)
String exclusion = element.getAttribute(ATTRIBUTE_EXCLUDING);
IPath[] exclusionPatterns = APathEntry.NO_EXCLUSION_PATTERNS;
if (!exclusion.equals("")) { //$NON-NLS-1$
char[][] patterns = CharOperation.splitOn('|', exclusion.toCharArray());
int patternCount;
if ((patternCount = patterns.length) > 0) {
exclusionPatterns = new IPath[patternCount];
for (int j = 0; j < patterns.length; j++) {
exclusionPatterns[j] = new Path(new String(patterns[j]));
}
}
}
// recreate the entry
switch (kind) {
case IPathEntry.CDT_PROJECT :
return CoreModel.newProjectEntry(path, isExported);
case IPathEntry.CDT_LIBRARY :
if (!baseRef.isEmpty()) {
return CoreModel.newLibraryRefEntry(baseRef, path);
}
return CoreModel.newLibraryEntry(basePath, path, sourceAttachmentPath, sourceAttachmentRootPath,
sourceAttachmentPrefixMapping, isExported);
case IPathEntry.CDT_SOURCE :
{
// must be an entry in this project or specify another
// project
String projSegment = path.segment(0);
if (projSegment != null && projSegment.equals(cProject.getElementName())) { // this
// project
return CoreModel.newSourceEntry(path, exclusionPatterns);
} else { // another project
return CoreModel.newProjectEntry(path, isExported);
}
}
case IPathEntry.CDT_OUTPUT :
{
return CoreModel.newOutputEntry(path, exclusionPatterns);
}
case IPathEntry.CDT_INCLUDE :
{
// include path info
IPath includePath = new Path(element.getAttribute(ATTRIBUTE_INCLUDE));
// isSysteminclude
boolean isSystemInclude = false;
if (element.hasAttribute(ATTRIBUTE_SYSTEM)) {
isSystemInclude = element.getAttribute(ATTRIBUTE_SYSTEM).equals(VALUE_TRUE);
}
if (!baseRef.isEmpty()) {
return CoreModel.newIncludeRefEntry(path, baseRef, includePath);
}
return CoreModel.newIncludeEntry(path, basePath, includePath, isSystemInclude, exclusionPatterns, isExported);
}
case IPathEntry.CDT_MACRO :
{
String macroName = element.getAttribute(ATTRIBUTE_NAME);
String macroValue = element.getAttribute(ATTRIBUTE_VALUE);
if (!baseRef.isEmpty()) {
return CoreModel.newMacroRefEntry(path, baseRef, macroName);
}
return CoreModel.newMacroEntry(path, macroName, macroValue, exclusionPatterns, isExported);
}
case IPathEntry.CDT_CONTAINER :
{
IPath id = new Path(element.getAttribute(ATTRIBUTE_PATH));
return CoreModel.newContainerEntry(id, isExported);
}
default :
{
ICModelStatus status = new CModelStatus(ICModelStatus.ERROR, "PathEntry: unknown kind (" + kindAttr + ")"); //$NON-NLS-1$ //$NON-NLS-2$
throw new CModelException(status);
}
IPathEntryStore getPathEntryStore(IProject project) throws CoreException {
IPathEntryStore store = (IPathEntryStore)storeMap.get(project);
if (store == null) {
store = CCorePlugin.getDefault().getPathEntryStore(project);
storeMap.put(project, store);
store.addPathEntryStoreListener(this);
}
return store;
}
static void encodePathEntries(IPath projectPath, Document doc, Element configRootElement, IPathEntry[] entries) {
Element element;
for (int i = 0; i < entries.length; i++) {
element = doc.createElement(PATH_ENTRY);
configRootElement.appendChild(element);
int kind = entries[i].getEntryKind();
// Set the kind
element.setAttribute(ATTRIBUTE_KIND, PathEntry.kindToString(kind));
// translate the project prefix.
IPath xmlPath = entries[i].getPath();
if (xmlPath == null) {
xmlPath = new Path("");
}
if (kind != IPathEntry.CDT_CONTAINER) {
// translate to project relative from absolute (unless a device path)
if (xmlPath.isAbsolute()) {
if (projectPath != null && projectPath.isPrefixOf(xmlPath)) {
if (xmlPath.segment(0).equals(projectPath.segment(0))) {
xmlPath = xmlPath.removeFirstSegments(1);
xmlPath = xmlPath.makeRelative();
} else {
xmlPath = xmlPath.makeAbsolute();
}
}
}
}
// Save the path
element.setAttribute(ATTRIBUTE_PATH, xmlPath.toString());
// Specifics to the entries
switch(kind) {
case IPathEntry.CDT_SOURCE:
case IPathEntry.CDT_OUTPUT:
case IPathEntry.CDT_PROJECT:
case IPathEntry.CDT_CONTAINER:
break;
case IPathEntry.CDT_LIBRARY: {
ILibraryEntry lib = (ILibraryEntry) entries[i];
IPath sourcePath = lib.getSourceAttachmentPath();
if (sourcePath != null) {
// translate to project relative from absolute
if (projectPath != null && projectPath.isPrefixOf(sourcePath)) {
if (sourcePath.segment(0).equals(projectPath.segment(0))) {
sourcePath = sourcePath.removeFirstSegments(1);
sourcePath = sourcePath.makeRelative();
}
}
element.setAttribute(ATTRIBUTE_SOURCEPATH, sourcePath.toString());
}
if (lib.getSourceAttachmentRootPath() != null) {
element.setAttribute(ATTRIBUTE_ROOTPATH, lib.getSourceAttachmentRootPath().toString());
}
if (lib.getSourceAttachmentPrefixMapping() != null) {
element.setAttribute(ATTRIBUTE_PREFIXMAPPING, lib.getSourceAttachmentPrefixMapping().toString());
}
break;
}
case IPathEntry.CDT_INCLUDE: {
IIncludeEntry include = (IIncludeEntry) entries[i];
IPath includePath = include.getIncludePath();
element.setAttribute(ATTRIBUTE_INCLUDE, includePath.toString());
if (include.isSystemInclude()) {
element.setAttribute(ATTRIBUTE_SYSTEM, VALUE_TRUE);
}
break;
}
case IPathEntry.CDT_MACRO: {
IMacroEntry macro = (IMacroEntry) entries[i];
element.setAttribute(ATTRIBUTE_NAME, macro.getMacroName());
element.setAttribute(ATTRIBUTE_VALUE, macro.getMacroValue());
break;
}
}
if (entries[i] instanceof APathEntry) {
APathEntry entry = (APathEntry) entries[i];
// save the basePath or the baseRef
IPath basePath = entry.getBasePath();
IPath baseRef = entry.getBaseReference();
if (basePath != null && !basePath.isEmpty()) {
element.setAttribute(ATTRIBUTE_BASE_PATH, basePath.toString());
} else if (baseRef != null && !baseRef.isEmpty()) {
element.setAttribute(ATTRIBUTE_BASE_REF, baseRef.toString());
}
// Save the exclusions attributes
IPath[] exclusionPatterns = entry.getExclusionPatterns();
if (exclusionPatterns.length > 0) {
StringBuffer excludeRule = new StringBuffer(10);
for (int j = 0, max = exclusionPatterns.length; j < max; j++) {
if (j > 0) {
excludeRule.append('|');
}
excludeRule.append(exclusionPatterns[j]);
}
element.setAttribute(ATTRIBUTE_EXCLUDING, excludeRule.toString());
}
}
// Save the export attribute
if (entries[i].isExported()) {
element.setAttribute(ATTRIBUTE_EXPORTED, VALUE_TRUE);
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.core.ICDescriptorListener#descriptorChanged(org.eclipse.cdt.core.CDescriptorEvent)
/* (non-Javadoc)
* @see org.eclipse.cdt.core.resources.IPathEntryStoreListener#pathEntryStoreChanged(org.eclipse.cdt.core.resources.PathEntryChangedEvent)
*/
public void descriptorChanged(CDescriptorEvent event) {
if (event.getType() == CDescriptorEvent.CDTPROJECT_CHANGED) {
ICDescriptor cdesc = event.getDescriptor();
if (cdesc != null) {
CModelManager manager = CModelManager.getDefault();
IProject project = cdesc.getProject();
if (CoreModel.hasCNature(project) || CoreModel.hasCCNature(project)) {
ICProject cproject = manager.create(project);
try {
IPathEntry[] oldResolvedEntries = getResolvedPathEntries(cproject);
resolvedMap.remove(cproject);
IPathEntry[] newResolvedEntries = getResolvedPathEntries(cproject);
ICElementDelta[] deltas = generatePathEntryDeltas(cproject, oldResolvedEntries, newResolvedEntries);
if (deltas.length > 0) {
cproject.close();
for (int i = 0; i < deltas.length; i++) {
manager.registerCModelDelta(deltas[i]);
}
manager.fire(ElementChangedEvent.POST_CHANGE);
}
} catch (CModelException e) {
public void pathEntryStoreChanged(PathEntryStoreChangedEvent event) {
IProject project = event.getProject();
if (project != null && (CoreModel.hasCNature(project) || CoreModel.hasCCNature(project))) {
CModelManager manager = CModelManager.getDefault();
ICProject cproject = manager.create(project);
try {
IPathEntry[] oldResolvedEntries = getResolvedPathEntries(cproject);
resolvedMap.remove(cproject);
IPathEntry[] newResolvedEntries = getResolvedPathEntries(cproject);
ICElementDelta[] deltas = generatePathEntryDeltas(cproject, oldResolvedEntries, newResolvedEntries);
if (deltas.length > 0) {
cproject.close();
for (int i = 0; i < deltas.length; i++) {
manager.registerCModelDelta(deltas[i]);
}
manager.fire(ElementChangedEvent.POST_CHANGE);
}
} catch (CModelException e) {
}
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.model.IElementChangedListener#elementChanged(org.eclipse.cdt.core.model.ElementChangedEvent)
*/
public void elementChanged(ElementChangedEvent event) {
try {
processDelta(event.getDelta());
} catch(CModelException e) {
}
}
protected void processDelta(ICElementDelta delta) throws CModelException {
int kind= delta.getKind();
int flags= delta.getFlags();
ICElement element= delta.getElement();
//System.out.println("Processing " + element);
// handle closing and removing of projects
if (((flags & ICElementDelta.F_CLOSED) != 0) || (kind == ICElementDelta.REMOVED)) {
if (element.getElementType() == ICElement.C_PROJECT) {
IProject project = element.getCProject().getProject();
IPathEntryStore store = (IPathEntryStore)storeMap.remove(project);
store.removePathEntryStoreListener(this);
resolvedMap.remove(project);
}
}
ICElementDelta[] affectedChildren= delta.getAffectedChildren();
for (int i= 0; i < affectedChildren.length; i++) {
processDelta(affectedChildren[i]);
}
}
}

View file

@ -0,0 +1,371 @@
/**********************************************************************
* Copyright (c) 2002,2003,2004 QNX Software Systems 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:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.model;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.cdt.core.AbstractCExtension;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CDescriptorEvent;
import org.eclipse.cdt.core.ICDescriptor;
import org.eclipse.cdt.core.ICDescriptorListener;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICModelStatus;
import org.eclipse.cdt.core.model.IIncludeEntry;
import org.eclipse.cdt.core.model.ILibraryEntry;
import org.eclipse.cdt.core.model.IMacroEntry;
import org.eclipse.cdt.core.model.IPathEntry;
import org.eclipse.cdt.core.resources.IPathEntryStore;
import org.eclipse.cdt.core.resources.IPathEntryStoreListener;
import org.eclipse.cdt.core.resources.PathEntryStoreChangedEvent;
import org.eclipse.cdt.internal.core.CharOperation;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* PathEntryStore
*/
public class PathEntryStore extends AbstractCExtension implements IPathEntryStore, ICDescriptorListener {
static String PATH_ENTRY = "pathentry"; //$NON-NLS-1$
static String PATH_ENTRY_ID = "org.eclipse.cdt.core.pathentry"; //$NON-NLS-1$
static String ATTRIBUTE_KIND = "kind"; //$NON-NLS-1$
static String ATTRIBUTE_PATH = "path"; //$NON-NLS-1$
static String ATTRIBUTE_BASE_PATH = "base-path"; //$NON-NLS-1$
static String ATTRIBUTE_BASE_REF = "base-ref"; //$NON-NLS-1$
static String ATTRIBUTE_EXPORTED = "exported"; //$NON-NLS-1$
static String ATTRIBUTE_SOURCEPATH = "sourcepath"; //$NON-NLS-1$
static String ATTRIBUTE_ROOTPATH = "roopath"; //$NON-NLS-1$
static String ATTRIBUTE_PREFIXMAPPING = "prefixmapping"; //$NON-NLS-1$
static String ATTRIBUTE_EXCLUDING = "excluding"; //$NON-NLS-1$
static String ATTRIBUTE_INCLUDE = "include"; //$NON-NLS-1$
static String ATTRIBUTE_SYSTEM = "system"; //$NON-NLS-1$
static String ATTRIBUTE_NAME = "name"; //$NON-NLS-1$
static String ATTRIBUTE_VALUE = "value"; //$NON-NLS-1$
static String VALUE_TRUE = "true"; //$NON-NLS-1$
static final IPathEntry[] NO_PATHENTRIES = new IPathEntry[0];
List listeners;
/**
*
*/
public PathEntryStore() {
super();
listeners = Collections.synchronizedList(new ArrayList());
// Register the Core Model on the Descriptor
// Manager, it needs to know about changes.
CCorePlugin.getDefault().getCDescriptorManager().addDescriptorListener(this);
}
public IPathEntry[] getRawPathEntries(IProject project) throws CoreException {
ArrayList pathEntries = new ArrayList();
ICDescriptor cdesc = CCorePlugin.getDefault().getCProjectDescription(project);
Element element = cdesc.getProjectData(PATH_ENTRY_ID);
NodeList list = element.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
Node childNode = list.item(i);
if (childNode.getNodeType() == Node.ELEMENT_NODE) {
if (childNode.getNodeName().equals(PATH_ENTRY)) {
pathEntries.add(decodePathEntry(project, (Element) childNode));
}
}
}
return (IPathEntry[]) pathEntries.toArray(NO_PATHENTRIES);
}
public void setRawPathEntries(IProject project, IPathEntry[] newRawEntries) throws CoreException {
ICDescriptor descriptor = CCorePlugin.getDefault().getCProjectDescription(project);
Element rootElement = descriptor.getProjectData(PATH_ENTRY_ID);
// Clear out all current children
Node child = rootElement.getFirstChild();
while (child != null) {
rootElement.removeChild(child);
child = rootElement.getFirstChild();
}
// Save the entries
if (newRawEntries != null && newRawEntries.length > 0) {
// Serialize the include paths
Document doc = rootElement.getOwnerDocument();
encodePathEntries(project.getFullPath(), doc, rootElement, newRawEntries);
}
descriptor.saveProjectData();
}
static IPathEntry decodePathEntry(IProject project, Element element) throws CModelException {
IPath projectPath = project.getFullPath();
// kind
String kindAttr = element.getAttribute(ATTRIBUTE_KIND);
int kind = PathEntry.kindFromString(kindAttr);
// exported flag
boolean isExported = false;
if (element.hasAttribute(ATTRIBUTE_EXPORTED)) {
isExported = element.getAttribute(ATTRIBUTE_EXPORTED).equals(VALUE_TRUE);
}
// get path and ensure it is absolute
//String pathAttr = element.getAttribute(ATTRIBUTE_PATH);
IPath path = new Path(element.getAttribute(ATTRIBUTE_PATH));
if (!path.isAbsolute()) {
path = projectPath.append(path);
}
// check fo the base path
IPath basePath = new Path(element.getAttribute(ATTRIBUTE_BASE_PATH));
// get the base ref
IPath baseRef = new Path(element.getAttribute(ATTRIBUTE_BASE_REF));
// source attachment info (optional)
IPath sourceAttachmentPath = element.hasAttribute(ATTRIBUTE_SOURCEPATH) ? new Path(
element.getAttribute(ATTRIBUTE_SOURCEPATH)) : null;
IPath sourceAttachmentRootPath = element.hasAttribute(ATTRIBUTE_ROOTPATH) ? new Path(
element.getAttribute(ATTRIBUTE_ROOTPATH)) : null;
IPath sourceAttachmentPrefixMapping = element.hasAttribute(ATTRIBUTE_PREFIXMAPPING) ? new Path(
element.getAttribute(ATTRIBUTE_PREFIXMAPPING)) : null;
// exclusion patterns (optional)
String exclusion = element.getAttribute(ATTRIBUTE_EXCLUDING);
IPath[] exclusionPatterns = APathEntry.NO_EXCLUSION_PATTERNS;
if (!exclusion.equals("")) { //$NON-NLS-1$
char[][] patterns = CharOperation.splitOn('|', exclusion.toCharArray());
int patternCount;
if ((patternCount = patterns.length) > 0) {
exclusionPatterns = new IPath[patternCount];
for (int j = 0; j < patterns.length; j++) {
exclusionPatterns[j] = new Path(new String(patterns[j]));
}
}
}
// recreate the entry
switch (kind) {
case IPathEntry.CDT_PROJECT :
return CoreModel.newProjectEntry(path, isExported);
case IPathEntry.CDT_LIBRARY :
if (!baseRef.isEmpty()) {
return CoreModel.newLibraryRefEntry(baseRef, path);
}
return CoreModel.newLibraryEntry(basePath, path, sourceAttachmentPath, sourceAttachmentRootPath,
sourceAttachmentPrefixMapping, isExported);
case IPathEntry.CDT_SOURCE :
{
// must be an entry in this project or specify another
// project
String projSegment = path.segment(0);
if (projSegment != null && projSegment.equals(project.getName())) { // this
// project
return CoreModel.newSourceEntry(path, exclusionPatterns);
} else { // another project
return CoreModel.newProjectEntry(path, isExported);
}
}
case IPathEntry.CDT_OUTPUT :
{
return CoreModel.newOutputEntry(path, exclusionPatterns);
}
case IPathEntry.CDT_INCLUDE :
{
// include path info
IPath includePath = new Path(element.getAttribute(ATTRIBUTE_INCLUDE));
// isSysteminclude
boolean isSystemInclude = false;
if (element.hasAttribute(ATTRIBUTE_SYSTEM)) {
isSystemInclude = element.getAttribute(ATTRIBUTE_SYSTEM).equals(VALUE_TRUE);
}
if (!baseRef.isEmpty()) {
return CoreModel.newIncludeRefEntry(path, baseRef, includePath);
}
return CoreModel.newIncludeEntry(path, basePath, includePath, isSystemInclude, exclusionPatterns, isExported);
}
case IPathEntry.CDT_MACRO :
{
String macroName = element.getAttribute(ATTRIBUTE_NAME);
String macroValue = element.getAttribute(ATTRIBUTE_VALUE);
if (!baseRef.isEmpty()) {
return CoreModel.newMacroRefEntry(path, baseRef, macroName);
}
return CoreModel.newMacroEntry(path, macroName, macroValue, exclusionPatterns, isExported);
}
case IPathEntry.CDT_CONTAINER :
{
IPath id = new Path(element.getAttribute(ATTRIBUTE_PATH));
return CoreModel.newContainerEntry(id, isExported);
}
default :
{
ICModelStatus status = new CModelStatus(ICModelStatus.ERROR, "PathEntry: unknown kind (" + kindAttr + ")"); //$NON-NLS-1$ //$NON-NLS-2$
throw new CModelException(status);
}
}
}
static void encodePathEntries(IPath projectPath, Document doc, Element configRootElement, IPathEntry[] entries) {
Element element;
for (int i = 0; i < entries.length; i++) {
element = doc.createElement(PATH_ENTRY);
configRootElement.appendChild(element);
int kind = entries[i].getEntryKind();
// Set the kind
element.setAttribute(ATTRIBUTE_KIND, PathEntry.kindToString(kind));
// translate the project prefix.
IPath xmlPath = entries[i].getPath();
if (xmlPath == null) {
xmlPath = new Path("");
}
if (kind != IPathEntry.CDT_CONTAINER) {
// translate to project relative from absolute (unless a device path)
if (xmlPath.isAbsolute()) {
if (projectPath != null && projectPath.isPrefixOf(xmlPath)) {
if (xmlPath.segment(0).equals(projectPath.segment(0))) {
xmlPath = xmlPath.removeFirstSegments(1);
xmlPath = xmlPath.makeRelative();
} else {
xmlPath = xmlPath.makeAbsolute();
}
}
}
}
// Save the path
element.setAttribute(ATTRIBUTE_PATH, xmlPath.toString());
// Specifics to the entries
switch(kind) {
case IPathEntry.CDT_SOURCE:
case IPathEntry.CDT_OUTPUT:
case IPathEntry.CDT_PROJECT:
case IPathEntry.CDT_CONTAINER:
break;
case IPathEntry.CDT_LIBRARY: {
ILibraryEntry lib = (ILibraryEntry) entries[i];
IPath sourcePath = lib.getSourceAttachmentPath();
if (sourcePath != null) {
// translate to project relative from absolute
if (projectPath != null && projectPath.isPrefixOf(sourcePath)) {
if (sourcePath.segment(0).equals(projectPath.segment(0))) {
sourcePath = sourcePath.removeFirstSegments(1);
sourcePath = sourcePath.makeRelative();
}
}
element.setAttribute(ATTRIBUTE_SOURCEPATH, sourcePath.toString());
}
if (lib.getSourceAttachmentRootPath() != null) {
element.setAttribute(ATTRIBUTE_ROOTPATH, lib.getSourceAttachmentRootPath().toString());
}
if (lib.getSourceAttachmentPrefixMapping() != null) {
element.setAttribute(ATTRIBUTE_PREFIXMAPPING, lib.getSourceAttachmentPrefixMapping().toString());
}
break;
}
case IPathEntry.CDT_INCLUDE: {
IIncludeEntry include = (IIncludeEntry) entries[i];
IPath includePath = include.getIncludePath();
element.setAttribute(ATTRIBUTE_INCLUDE, includePath.toString());
if (include.isSystemInclude()) {
element.setAttribute(ATTRIBUTE_SYSTEM, VALUE_TRUE);
}
break;
}
case IPathEntry.CDT_MACRO: {
IMacroEntry macro = (IMacroEntry) entries[i];
element.setAttribute(ATTRIBUTE_NAME, macro.getMacroName());
element.setAttribute(ATTRIBUTE_VALUE, macro.getMacroValue());
break;
}
}
if (entries[i] instanceof APathEntry) {
APathEntry entry = (APathEntry) entries[i];
// save the basePath or the baseRef
IPath basePath = entry.getBasePath();
IPath baseRef = entry.getBaseReference();
if (basePath != null && !basePath.isEmpty()) {
element.setAttribute(ATTRIBUTE_BASE_PATH, basePath.toString());
} else if (baseRef != null && !baseRef.isEmpty()) {
element.setAttribute(ATTRIBUTE_BASE_REF, baseRef.toString());
}
// Save the exclusions attributes
IPath[] exclusionPatterns = entry.getExclusionPatterns();
if (exclusionPatterns.length > 0) {
StringBuffer excludeRule = new StringBuffer(10);
for (int j = 0, max = exclusionPatterns.length; j < max; j++) {
if (j > 0) {
excludeRule.append('|');
}
excludeRule.append(exclusionPatterns[j]);
}
element.setAttribute(ATTRIBUTE_EXCLUDING, excludeRule.toString());
}
}
// Save the export attribute
if (entries[i].isExported()) {
element.setAttribute(ATTRIBUTE_EXPORTED, VALUE_TRUE);
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.core.ICDescriptorListener#descriptorChanged(org.eclipse.cdt.core.CDescriptorEvent)
*/
public void descriptorChanged(CDescriptorEvent event) {
if (event.getType() == CDescriptorEvent.CDTPROJECT_CHANGED) {
ICDescriptor cdesc = event.getDescriptor();
if (cdesc != null) {
CModelManager manager = CModelManager.getDefault();
IProject project = cdesc.getProject();
// Call the listeners.
PathEntryStoreChangedEvent evt = new PathEntryStoreChangedEvent(project);
IPathEntryStoreListener[] observers = new IPathEntryStoreListener[listeners.size()];
listeners.toArray(observers);
for (int i = 0; i < observers.length; i++) {
observers[i].pathEntryStoreChanged(evt);
}
}
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.resources.IPathEntryStore#addPathEntryStoreListener(org.eclipse.cdt.core.resources.IPathEntryStoreListener)
*/
public void addPathEntryStoreListener(IPathEntryStoreListener listener) {
listeners.add(listener);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.resources.IPathEntryStore#removePathEntryStoreListener(org.eclipse.cdt.core.resources.IPathEntryStoreListener)
*/
public void removePathEntryStoreListener(IPathEntryStoreListener listener) {
listeners.remove(listener);
}
}

View file

@ -39,6 +39,12 @@
<!-- Extension Point: IBinaryParser, use to detect wheter an IFile is a binary -->
<!-- =================================================================================== -->
<extension-point id="BinaryParser" name="BinaryParser"/>
<!-- =================================================================================== -->
<!-- Extension Point: IPathEntryStore, use to provide a storage for PathEtnry -->
<!-- =================================================================================== -->
<extension-point id="PathEntryStore" name="PathEntryStore"/>
<!-- =================================================================================== -->
<!-- =================================================================================== -->
<extension-point id="ScannerInfoProvider" name="Scanner Information Provider"/>
<!-- =================================================================================== -->
<!-- Extension Point: CFileType and CFileTypeAssociation for translation unit ident -->
@ -92,6 +98,20 @@
</cextension>
</extension>
<!-- =================================================================================== -->
<!-- Define the default PathEntry store provided by the CDT -->
<!-- =================================================================================== -->
<extension
id="cdtPathEntryStore"
name="Path Entry Store"
point="org.eclipse.cdt.core.PathEntryStore">
<cextension>
<run
class="org.eclipse.cdt.internal.core.model.PathEntryStore">
</run>
</cextension>
</extension>
<!-- =================================================================================== -->
<!-- Define the list of Error Parser provided by the CDT -->
<!-- =================================================================================== -->
<extension

View file

@ -24,6 +24,7 @@ import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.cdt.core.parser.IScannerInfoProvider;
import org.eclipse.cdt.core.resources.IConsole;
import org.eclipse.cdt.core.resources.IPathEntryStore;
import org.eclipse.cdt.core.search.SearchEngine;
import org.eclipse.cdt.internal.core.CDTLogWriter;
import org.eclipse.cdt.internal.core.CDescriptorManager;
@ -74,7 +75,13 @@ public class CCorePlugin extends Plugin {
public final static String PREF_USE_STRUCTURAL_PARSE_MODE = "useStructualParseMode"; //$NON-NLS-1$
public final static String ERROR_PARSER_SIMPLE_ID = "ErrorParser"; //$NON-NLS-1$
// PathEntry extension
public final static String PATHENTRY_STORE_ID = "PathEntryStore"; //$NON-NLS-1$
public final static String PATHENTRY_STORE_UNIQ_ID = PLUGIN_ID + "." + PATHENTRY_STORE_ID; //$NON-NLS-1$
// default store for pathentry
public final static String DEFAULT_PATHENTRY_STORE_ID = PLUGIN_ID + ".cdtPathEntryStore"; //$NON-NLS-1$
// Build Model Interface Discovery
public final static String BUILD_SCANNER_INFO_SIMPLE_ID = "ScannerInfoProvider"; //$NON-NLS-1$
public final static String BUILD_SCANNER_INFO_UNIQ_ID = PLUGIN_ID + "." + BUILD_SCANNER_INFO_SIMPLE_ID; //$NON-NLS-1$
@ -620,6 +627,53 @@ public class CCorePlugin extends Plugin {
return parser;
}
public IPathEntryStore getPathEntryStore(IProject project) throws CoreException {
IPathEntryStore store = null;
if (project != null) {
try {
ICDescriptor cdesc = getCProjectDescription(project);
ICExtensionReference[] cextensions = cdesc.get(PATHENTRY_STORE_UNIQ_ID, true);
if (cextensions.length > 0) {
ArrayList list = new ArrayList(cextensions.length);
for (int i = 0; i < cextensions.length; i++) {
try {
store = (IPathEntryStore) cextensions[i].createExtension();
break;
} catch (ClassCastException e) {
//
log(e);
}
}
}
} catch (CoreException e) {
// ignore since we fall back to a default....
}
}
if (store == null) {
store = getDefaultPathEntryStore();
}
return store;
}
public IPathEntryStore getDefaultPathEntryStore() throws CoreException {
IPathEntryStore store = null;
IExtensionPoint extensionPoint = getDescriptor().getExtensionPoint(PATHENTRY_STORE_ID);
IExtension extension = extensionPoint.getExtension(DEFAULT_PATHENTRY_STORE_ID);
if (extension != null) {
IConfigurationElement element[] = extension.getConfigurationElements();
for (int i = 0; i < element.length; i++) {
if (element[i].getName().equalsIgnoreCase("cextension")) { //$NON-NLS-1$
store = (IPathEntryStore) element[i].createExecutableExtension("run"); //$NON-NLS-1$
break;
}
}
} else {
IStatus s = new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, -1, CCorePlugin.getResourceString("CCorePlugin.exception.noBinaryFormat"), null); //$NON-NLS-1$
throw new CoreException(s);
}
return store;
}
/**
* Returns the file type object corresponding to the provided
* file name.

View file

@ -0,0 +1,27 @@
/**********************************************************************
* Copyright (c) 2002,2003,2004 QNX Software Systems 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:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.core.resources;
import org.eclipse.cdt.core.model.IPathEntry;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
/**
* IPathEntryStore
*/
public interface IPathEntryStore {
IPathEntry[] getRawPathEntries(IProject project) throws CoreException;
void setRawPathEntries(IProject project, IPathEntry[] engries) throws CoreException;
void addPathEntryStoreListener(IPathEntryStoreListener listener);
void removePathEntryStoreListener(IPathEntryStoreListener listener);
}

View file

@ -0,0 +1,25 @@
/**********************************************************************
* Copyright (c) 2002,2003,2004 QNX Software Systems 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:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.core.resources;
import java.util.EventListener;
/**
* IPathEntryStoreListener
*/
public interface IPathEntryStoreListener extends EventListener {
/**
*
* @param event
*/
void pathEntryStoreChanged(PathEntryStoreChangedEvent event);
}

View file

@ -0,0 +1,33 @@
/**********************************************************************
* Copyright (c) 2002,2003,2004 QNX Software Systems 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:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.core.resources;
import java.util.EventObject;
import org.eclipse.core.resources.IProject;
/**
* PathEntryChangedEvent
*/
public class PathEntryStoreChangedEvent extends EventObject {
/**
*
*/
public PathEntryStoreChangedEvent(Object object) {
super(object);
}
public IProject getProject() {
return (IProject)getSource();
}
}