1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

2004-08-18 Alain Magloire

Work on the ResolverModel, we make the Core Model aware of the changes.
	Noticeable changes ICFileTypeResolver is tied to a container, this change
	things considerably when extending the implementations.  Sam orignal works
	did not with some pros && cons .. this also has pros and cons.

	* model/org/eclipse/cdt/internal/core/model/CModelManager.java
	* model/org/eclipse/cdt/internal/core/model/ResolverProcessor.java

	* src/org/eclipse/cdt/core/filetype/ICFielTypeResolver.java
	* src/org/eclipse/cdt/core/filetype/IResolverChangeListener.java
	* src/org/eclipse/cdt/core/filetype/IResolverModel.java
	* src/org/eclipse/cdt/core/filetype/ResolverChangeEvent.java
	* src/org/eclipse/cdt/core/filetype/ResolverDelta.java

	* src/org/eclipse/cdt/core/internal/filetype/CFileTypeResolver.java
	* src/org/eclipse/cdt/core/internal/filetype/CustomResolver.java
	* src/org/eclipse/cdt/core/internal/filetype/ResolverModel.java
	* src/org/eclipse/cdt/core/internal/filetype/WorkspaceResolver.java
This commit is contained in:
Alain Magloire 2004-08-20 20:29:57 +00:00
parent f56c0202be
commit c931ca6163
12 changed files with 1292 additions and 752 deletions

View file

@ -1,3 +1,24 @@
2004-08-18 Alain Magloire
Work on the ResolverModel, we make the Core Model aware of the changes.
Noticeable changes ICFileTypeResolver is tied to a container, this change
things considerably when extending the implementations. Sam orignal works
did not with some pros && cons .. this also has pros and cons.
* model/org/eclipse/cdt/internal/core/model/CModelManager.java
* model/org/eclipse/cdt/internal/core/model/ResolverProcessor.java
* src/org/eclipse/cdt/core/filetype/ICFielTypeResolver.java
* src/org/eclipse/cdt/core/filetype/IResolverChangeListener.java
* src/org/eclipse/cdt/core/filetype/IResolverModel.java
* src/org/eclipse/cdt/core/filetype/ResolverChangeEvent.java
* src/org/eclipse/cdt/core/filetype/ResolverDelta.java
* src/org/eclipse/cdt/core/internal/filetype/CFileTypeResolver.java
* src/org/eclipse/cdt/core/internal/filetype/CustomResolver.java
* src/org/eclipse/cdt/core/internal/filetype/ResolverModel.java
* src/org/eclipse/cdt/core/internal/filetype/WorkspaceResolver.java
2004-08-18 Alain Magloire
When running the CDescriptorOperation make sure we have an ICDescriptor.

View file

@ -739,8 +739,8 @@ public class CModelManager implements IResourceChangeListener, ICDescriptorListe
/* (non-Javadoc)
* @see org.eclipse.cdt.core.filetype.IResolverChangeListener#resolverChanged(org.eclipse.cdt.core.filetype.ResolverChangeEvent)
*/
public void resolverChanged(ResolverChangeEvent[] events) {
fResolverProcessor.processResolverChanges(events);
public void resolverChanged(ResolverChangeEvent event) {
fResolverProcessor.processResolverChanges(event);
}
public void fire(int eventType) {

View file

@ -11,21 +11,20 @@
package org.eclipse.cdt.internal.core.model;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.core.filetype.ICFileTypeAssociation;
import org.eclipse.cdt.core.filetype.ResolverChangeEvent;
import org.eclipse.cdt.core.filetype.ResolverDelta;
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.IOpenable;
import org.eclipse.cdt.core.model.ISourceRoot;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
/**
* ResolverProcessor
@ -35,41 +34,27 @@ public class ResolverProcessor {
CModelManager fManager;
CElementDelta fCurrentDelta;
public void processResolverChanges(ResolverChangeEvent[] events) {
public void processResolverChanges(ResolverChangeEvent event) {
ICElement root = CModelManager.getDefault().getCModel();
fCurrentDelta = new CElementDelta(root);
fManager = CModelManager.getDefault();
// Regroup the events per container.
Map map = new HashMap();
for (int i = 0; i < events.length; ++i) {
IContainer container = events[i].getContainer();
List list = (List)map.get(container);
if (list == null) {
list = new ArrayList();
map.put(container, list);
}
list.add(events[i]);
}
// Go through the events and generate deltas
CModelManager manager = CModelManager.getDefault();
Iterator entries = map.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry entry = (Map.Entry)entries.next();
List list = (List)entry.getValue();
for (int i = 0; i < list.size(); ++i) {
ResolverChangeEvent event = (ResolverChangeEvent)list.get(i);
if (event.getElementType() ==ResolverChangeEvent.ELEMENT_ASSOCIATION) {
IContainer container = (IContainer)entry.getKey();
ResolverDelta[] deltas = event.getDeltas();
IContainer container = event.getResolver().getContainer();
ICElement celement = CoreModel.getDefault().create(container);
ICFileTypeAssociation association = (ICFileTypeAssociation)event.getElement();
for (int i = 0; i < deltas.length; ++i) {
ResolverDelta delta = deltas[i];
if (delta.getElementType() == ResolverDelta.ELEMENT_ASSOCIATION) {
ICFileTypeAssociation association = (ICFileTypeAssociation)delta.getElement();
if (association.getType().isTranslationUnit()) {
try {
switch (event.getEventType()) {
case ResolverChangeEvent.EVENT_ADD:
switch (delta.getEventType()) {
case ResolverDelta.EVENT_ADD:
add(celement, association);
break;
case ResolverChangeEvent.EVENT_REMOVE:
case ResolverDelta.EVENT_REMOVE:
remove(celement, association);
break;
}
@ -79,32 +64,27 @@ public class ResolverProcessor {
}
}
}
if (fCurrentDelta.getAffectedChildren().length > 0) {
fManager.fire(fCurrentDelta, ElementChangedEvent.POST_CHANGE);
}
}
void add(ICElement celement, ICFileTypeAssociation association) throws CModelException {
if (celement instanceof IOpenable) {
int type = celement.getElementType();
if (type < ICElement.C_UNIT) {
Object[] elements = null;
CElementInfo info = (CElementInfo)fManager.peekAtInfo(celement);
if (info != null) {
switch (celement.getElementType()) {
case ICElement.C_MODEL:
elements = ((CModelInfo)info).getNonCResources();
break;
case ICElement.C_PROJECT:
elements = ((CProjectInfo)info).getNonCResources(celement.getResource());
break;
case ICElement.C_CCONTAINER:
elements = ((CContainerInfo)info).getNonCResources(celement.getResource());
break;
try {
IResource resource = celement.getResource();
IResource[] members = null;
if (resource instanceof IContainer) {
members = ((IContainer)resource).members();
}
}
if (elements != null) {
for (int i = 0; i < elements.length; ++i) {
if (elements[i] instanceof IFile) {
IFile file = (IFile) elements[i];
if (members != null) {
for (int i = 0; i < members.length; ++i) {
if (members[i] instanceof IFile) {
IFile file = (IFile) members[i];
if (association.matches(file.getName())) {
ICElement newElement = CoreModel.getDefault().create(file);
if (newElement != null) {
@ -118,6 +98,10 @@ public class ResolverProcessor {
add(celements[i], association);
}
}
} catch (CoreException e) {
//
}
}
}
}
}
@ -126,9 +110,8 @@ public class ResolverProcessor {
if (celement instanceof IOpenable) {
int type = celement.getElementType();
if (type < ICElement.C_UNIT) {
CElementInfo info = (CElementInfo)fManager.peekAtInfo(celement);
if (info instanceof CElementInfo) {
CElementInfo cinfo = (CElementInfo)info;
CElementInfo cinfo = (CElementInfo)fManager.peekAtInfo(celement);
if (cinfo != null) {
ICElement[] celements = cinfo.getChildren();
for (int i = 0; i < celements.length; ++i) {
if (celements[i].getElementType() == ICElement.C_UNIT) {
@ -162,6 +145,16 @@ public class ResolverProcessor {
break;
case ICElement.C_CCONTAINER:
((CContainerInfo)info).setNonCResources(null);
if (parent instanceof ISourceRoot) {
// if sourceRoot == Project we nee to update the nonCResource of the project also.
if (parent.getResource() instanceof IProject) {
ICElement cproject = parent.getCProject();
CProjectInfo pinfo = (CProjectInfo)fManager.peekAtInfo(cproject);
if (pinfo != null) {
pinfo.setNonCResources(null);
}
}
}
break;
}
} catch (CModelException e) {

View file

@ -10,6 +10,8 @@
***********************************************************************/
package org.eclipse.cdt.core.filetype;
import org.eclipse.core.resources.IContainer;
/**
* Class responsible for resolving a file name into the
* associated file type.
@ -32,16 +34,9 @@ public interface ICFileTypeResolver {
*/
public ICFileType getFileType(String fileName);
/**
* Add a new file type association to the resolver's list.
* @param assoc file name pattern to add.
*
* @return true if the file type association was added.
*/
public boolean addAssociation(ICFileTypeAssociation assoc);
/**
* Add multiple file type associations to the resolver's list.
* This method does not fire delta changes use adjustAssociations.
*
* @param assocs array of file type associations to add; may be null.
*
@ -49,17 +44,9 @@ public interface ICFileTypeResolver {
*/
public boolean addAssociations(ICFileTypeAssociation[] assocs);
/**
* Remove a file type association from the resolver's list.
*
* @param assoc file type association to remove.
*
* @return true if the file type association was removed.
*/
public boolean removeAssociation(ICFileTypeAssociation assoc);
/**
* Remove multiple file type associations from the resolver's list.
* This method does not fire delta changes use adjustAssociations.
*
* @param assoc array of file type association to remove; may be null
*
@ -70,7 +57,7 @@ public interface ICFileTypeResolver {
/**
* Add and/or remove associations from the resolver in a
* batch operation. Either (or both) of the parameters
* may be null.
* may be null. This method fires delta change events.
*
* @param add associations to add to the resolver; may be null
* @param rem associations to remove from the resolver; may be null
@ -88,4 +75,11 @@ public interface ICFileTypeResolver {
* @return working copy of this file type resolver
*/
public ICFileTypeResolver createWorkingCopy();
/**
* The container of the resolver can be IWorkspaceRoot or IProject.
*
* @return
*/
public IContainer getContainer();
}

View file

@ -15,5 +15,5 @@ package org.eclipse.cdt.core.filetype;
* individual resolver.
*/
public interface IResolverChangeListener {
public void resolverChanged(ResolverChangeEvent[] events);
public void resolverChanged(ResolverChangeEvent event);
}

View file

@ -46,39 +46,42 @@ public interface IResolverModel {
*/
public ICFileType getFileTypeById(String typeId);
/**
* Set the resolver for the current workspace.
*
* The workspace resolver is set to the specified
* resolver, and the resolver data is persisted
* in the workspace.
*
* @param resolver new workspace resolver.
*/
public void setResolver(ICFileTypeResolver resolver);
/**
* Get the resolver for the current workspace.
*
* If the workspace resolver is unavailable (or
* identical to the default resolver), then the
* default resolver is returned.
*
* @return workspace resolver
*/
public ICFileTypeResolver getResolver();
/**
* Set the resolver for the specified project.
* Create a custom resolver for the specified project.
*
* The project resolver is set to the specified
* The project resolver is set to a custom
* resolver, and the resolver data is persisted
* in the project (in the .cdtproject file).
*
* @param project project this resolver applied to
* @param resolver new project resolver
* This method fires changed event
*
* @param project - project this resolver applied to
* @param copyResolver - retrieve associations for the copy to populate the custom resolver.
*/
public void setResolver(IProject project, ICFileTypeResolver resolver);
public ICFileTypeResolver createCustomResolver(IProject project, ICFileTypeResolver copyResolver);
/**
* Remove the custom resolver on the project.
* This method fires changed event
*
* @param project
*/
public void removeCustomResolver(IProject project);
/**
* Return true if the project has a custom resolver.
*
* @param project
* @return true if a custom resolver
*/
public boolean hasCustomResolver(IProject project);
/**
* Get the resolver for the specified project.

View file

@ -10,127 +10,91 @@
***********************************************************************/
package org.eclipse.cdt.core.filetype;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IProject;
public class ResolverChangeEvent extends EventObject {
public static final int EVENT_ADD = 0x10;
public static final int EVENT_REMOVE = 0x20;
public static final int EVENT_SET = 0x40;
public static final int EVENT_MASK = 0xF0;
public static final int ELEMENT_LANGUAGE = 0x01;
public static final int ELEMENT_FILETYPE = 0x02;
public static final int ELEMENT_ASSOCIATION = 0x04;
public static final int ELEMENT_RESOLVER = 0x08;
public static final int ELEMENT_MASK = 0x0F;
private Object fElement;
private int fEventType;
private List fDeltas = new ArrayList();
private ICFileTypeResolver fNewResolver;
private ICFileTypeResolver fOldResolver;
/**
* Create a new change event.
* Create a new resolver change event. The event is empty
* of any change deltas, and references the provided file
* type resolver.
*
* @param resolver file type resolver this event applies to
*/
public ResolverChangeEvent(IContainer container, int eventType, Object element) {
super(container);
fEventType = eventType;
fElement = element;
public ResolverChangeEvent(IResolverModel model, ICFileTypeResolver resolver) {
this(model, resolver, null);
}
public IContainer getContainer() {
return (IContainer)getSource();
/**
* Create a new resolver change event. The event is empty
* of any change deltas, and references the provided file
* type resolver.
*
* @param resolver file type resolver this event applies to
*/
public ResolverChangeEvent(IResolverModel model, ICFileTypeResolver newResolver, ICFileTypeResolver oldResolver) {
super(model);
fNewResolver = newResolver;
fOldResolver = oldResolver;
}
public int getEventType() {
return fEventType & EVENT_MASK;
public boolean resolverHasChanged() {
return fOldResolver != null;
}
public Object getElement() {
return fElement;
/**
* @return resolver affected by this change
*/
public ICFileTypeResolver getResolver() {
return fNewResolver;
}
public int getElementType() {
if (fElement instanceof ICLanguage) {
return ELEMENT_LANGUAGE;
} else if (fElement instanceof ICFileType) {
return ELEMENT_FILETYPE;
} else if (fElement instanceof ICFileTypeAssociation) {
return ELEMENT_ASSOCIATION;
} else if (fElement instanceof ICFileTypeResolver) {
return ELEMENT_RESOLVER;
}
return 0;
/**
* @return number of resolver deltas involved in this change
*/
public int getDeltaCount() {
return fDeltas.size();
}
/**
* @return ResolverDelta[] for this change
*/
public ResolverDelta[] getDeltas() {
return (ResolverDelta[]) fDeltas.toArray(new ResolverDelta[fDeltas.size()]);
}
/**
* Add a new delta to the list of deltas.
*
* @param delta instance of ResolverDelta to add to the list.
*/
public void addDelta(ResolverDelta delta) {
fDeltas.add(delta);
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("ResolverChangeEvent ["); //$NON-NLS-1$
IContainer container = getContainer();
if (container instanceof IProject) {
buf.append("For project "); //$NON-NLS-1$
buf.append(container.getName());
} else {
buf.append("For workspace"); //$NON-NLS-1$
buf.append("ResolverChangeEvent [");
buf.append(fDeltas.size());
buf.append(" delta(s)]");
for (Iterator iter = fDeltas.iterator(); iter.hasNext();) {
ResolverDelta element = (ResolverDelta) iter.next();
buf.append("\n ");
buf.append(element.toString());
}
buf.append(' ');
switch (getEventType()) {
case EVENT_ADD:
buf.append("add"); //$NON-NLS-1$
break;
case EVENT_REMOVE:
buf.append("remove"); //$NON-NLS-1$
break;
case EVENT_SET:
buf.append("set"); //$NON-NLS-1$
break;
default:
buf.append("?unknown event?"); //$NON-NLS-1$
break;
}
buf.append(' ');
switch (getElementType()) {
case ELEMENT_LANGUAGE:
{
ICLanguage lang = (ICLanguage)getElement();
buf.append("language "); //$NON-NLS-1$
buf.append(lang.getName());
break;
}
case ELEMENT_FILETYPE:
{
ICFileType fileType = (ICFileType)getElement();
buf.append("filetype "); //$NON-NLS-1$
buf.append(fileType.getName());
break;
}
case ELEMENT_ASSOCIATION:
{
ICFileTypeAssociation association = (ICFileTypeAssociation)getElement();
buf.append("assoc "); //$NON-NLS-1$
buf.append(association.getPattern());
break;
}
case ELEMENT_RESOLVER:
{
ICFileTypeResolver resolver = (ICFileTypeResolver)getElement();
buf.append("resolver "); //$NON-NLS-1$
break;
}
default:
buf.append("?unknown source?"); //$NON-NLS-1$
break;
}
buf.append(']');
return buf.toString();
}
}

View file

@ -0,0 +1,110 @@
/**********************************************************************
* Copyright (c) 2004 TimeSys 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:
* TimeSys Corporation - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.core.filetype;
public class ResolverDelta {
public static final int EVENT_ADD = 0x10;
public static final int EVENT_REMOVE = 0x20;
public static final int EVENT_SET = 0x40;
public static final int EVENT_MASK = 0xF0;
public static final int ELEMENT_LANGUAGE = 0x01;
public static final int ELEMENT_FILETYPE = 0x02;
public static final int ELEMENT_ASSOCIATION = 0x04;
public static final int ELEMENT_MASK = 0x0F;
private Object fElement;
private int fEvent;
public ResolverDelta(int eventType, int elementType, Object element) {
fElement = element;
fEvent = eventType | elementType;
}
public ResolverDelta(ICLanguage lang, int event) {
this(event, ELEMENT_LANGUAGE, lang);
}
public ResolverDelta(ICFileType type, int event) {
this(event, ELEMENT_FILETYPE, type);
}
public ResolverDelta(ICFileTypeAssociation assoc, int event) {
this(event, ELEMENT_ASSOCIATION, assoc);
}
public Object getElement() {
return fElement;
}
public int getElementType() {
return fEvent & ELEMENT_MASK;
}
public int getEventType() {
return fEvent & EVENT_MASK;
}
public ICLanguage getLanguage() {
return ((fElement instanceof ICLanguage) ? ((ICLanguage) fElement) : null);
}
public ICFileType getFileType() {
return ((fElement instanceof ICFileType) ? ((ICFileType) fElement) : null);
}
public ICFileTypeAssociation getAssociation() {
return ((fElement instanceof ICFileTypeAssociation) ? ((ICFileTypeAssociation) fElement) : null);
}
public int getEvent() {
return fEvent;
}
public String toString() {
StringBuffer buf = new StringBuffer();
switch (getEventType()) {
case EVENT_ADD:
buf.append("add");
break;
case EVENT_REMOVE:
buf.append("remove");
break;
case EVENT_SET:
buf.append("set");
break;
default:
buf.append("?unknown event?");
break;
}
buf.append(" ");
switch (getElementType()) {
case ELEMENT_LANGUAGE:
buf.append("language ");
buf.append(null != getLanguage() ? getLanguage().getName() : "?");
break;
case ELEMENT_FILETYPE:
buf.append("filetype ");
buf.append(null != getFileType() ? getFileType().getName() : "?");
break;
case ELEMENT_ASSOCIATION:
buf.append("assoc ");
buf.append(null != getAssociation() ? getAssociation().getPattern() : "?");
break;
default:
buf.append("?unknown source?");
break;
}
return buf.toString();
}
}

View file

@ -11,37 +11,48 @@
package org.eclipse.cdt.core.internal.filetype;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.eclipse.cdt.core.filetype.ICFileType;
import org.eclipse.cdt.core.filetype.ICFileTypeAssociation;
import org.eclipse.cdt.core.filetype.ICFileTypeResolver;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.ResourcesPlugin;
public class CFileTypeResolver implements ICFileTypeResolver {
public abstract class CFileTypeResolver implements ICFileTypeResolver {
// the container of the resolver
protected IContainer fContainer;
// The association list holds a list of known file associations.
protected List fAssocList = new ArrayList();
protected List fAssocList;
public CFileTypeResolver() {
this(ResourcesPlugin.getWorkspace().getRoot());
}
public CFileTypeResolver(IContainer container) {
fContainer = container;
}
public ICFileTypeAssociation[] getFileTypeAssociations() {
return (ICFileTypeAssociation[]) fAssocList.toArray(new ICFileTypeAssociation[fAssocList.size()]);
/* (non-Javadoc)
* @see org.eclipse.cdt.core.filetype.ICFileTypeResolver#getContainer()
*/
public IContainer getContainer() {
return fContainer;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.filetype.ICFileTypeResolver#addAssociations(org.eclipse.cdt.core.filetype.ICFileTypeAssociation[])
*/
public boolean addAssociations(ICFileTypeAssociation[] assocs) {
return adjustAssociations(assocs, null, false);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.filetype.ICFileTypeResolver#getFileType(java.lang.String)
*/
public ICFileType getFileType(String fileName) {
for (Iterator iter = fAssocList.iterator(); iter.hasNext();) {
ICFileTypeAssociation element = (ICFileTypeAssociation) iter.next();
ICFileTypeAssociation[] assocs = getFileTypeAssociations();
for (int i = 0; i < assocs.length; ++i) {
ICFileTypeAssociation element = assocs[i];
if (element.matches(fileName)) {
return element.getType();
}
@ -49,75 +60,93 @@ public class CFileTypeResolver implements ICFileTypeResolver {
return ResolverModel.DEFAULT_FILE_TYPE;
}
//TODO: the add/remove methods do not generate change notifications...
// They really should be part of an IFileTypeResolverWorkingCopy interface
// For now, just be careful with them...
public boolean addAssociation(ICFileTypeAssociation assoc) {
return addAssociations(new ICFileTypeAssociation[] { assoc } );
}
public boolean addAssociations(ICFileTypeAssociation[] assocs) {
return doAddAssociations(assocs);
}
public boolean removeAssociation(ICFileTypeAssociation assoc) {
return removeAssociations(new ICFileTypeAssociation[] { assoc } );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.filetype.ICFileTypeResolver#removeAssociations(org.eclipse.cdt.core.filetype.ICFileTypeAssociation[])
*/
public boolean removeAssociations(ICFileTypeAssociation[] assocs) {
return doRemoveAssociations(assocs);
return adjustAssociations(null, assocs, false);
}
public boolean adjustAssociations(ICFileTypeAssociation[] add, ICFileTypeAssociation[] remove) {
boolean added = doAddAssociations(add);
boolean removed = doRemoveAssociations(remove);
return (added || removed);
public synchronized ICFileTypeAssociation[] getFileTypeAssociations() {
if (fAssocList == null) {
loadAssociationList();
}
return (ICFileTypeAssociation[]) fAssocList.toArray(new ICFileTypeAssociation[fAssocList.size()]);
}
public boolean adjustAssociations(ICFileTypeAssociation[] addAssocs, ICFileTypeAssociation[] delAssocs) {
return adjustAssociations(addAssocs, delAssocs, true);
}
protected synchronized boolean adjustAssociations(ICFileTypeAssociation[] addAssocs,
ICFileTypeAssociation[] delAssocs, boolean triggerEvent) {
List addList = new ArrayList();
List delList = new ArrayList();
loadAssociationList();
// check the adds
if (null != addAssocs) {
for (int i = 0; i < addAssocs.length; i++) {
if (!fAssocList.contains(addAssocs[i])) {
fAssocList.add(addAssocs[i]);
addList.add(addAssocs[i]);
}
}
}
// check the removes
if (null != delAssocs) {
for (int i = 0; i < delAssocs.length; i++) {
if (fAssocList.remove(delAssocs[i])) {
delList.add(delAssocs[i]);
}
}
}
// Anything change ?
boolean changed = !addList.isEmpty() || !delList.isEmpty();
if (changed) {
Collections.sort(fAssocList, ICFileTypeAssociation.Comparator);
addAssocs = (ICFileTypeAssociation[]) addList.toArray(new ICFileTypeAssociation[addList.size()]);
delAssocs = (ICFileTypeAssociation[]) delList.toArray(new ICFileTypeAssociation[delList.size()]);
doAdjustAssociations(addAssocs, delAssocs, true);
}
return changed;
}
public ICFileTypeResolver createWorkingCopy() {
CFileTypeResolver copy = new CFileTypeResolver(fContainer);
copy.fAssocList.addAll(fAssocList);
final ICFileTypeAssociation[] associations = getFileTypeAssociations();
CFileTypeResolver copy = new CFileTypeResolver(fContainer) {
public void doAdjustAssociations(ICFileTypeAssociation[] add, ICFileTypeAssociation[] del,
boolean triggerEvent) {
//
}
protected ICFileTypeAssociation[] loadAssociations() {
return associations;
}
};
return copy;
}
protected boolean doAddAssociations(ICFileTypeAssociation[] assocs) {
boolean added = false;
if (null != assocs) {
for (int i = 0; i < assocs.length; i++) {
if (!fAssocList.contains(assocs[i])) {
if (fAssocList.add(assocs[i])) {
added = true;
}
}
}
}
if (added) {
protected abstract void doAdjustAssociations(ICFileTypeAssociation[] addAssocs, ICFileTypeAssociation[] delAssocs,
boolean triggerEvent);
protected abstract ICFileTypeAssociation[] loadAssociations();
private synchronized List loadAssociationList() {
if (fAssocList == null) {
fAssocList = new ArrayList();
ICFileTypeAssociation[] assocs = loadAssociations();
if (assocs != null) {
fAssocList.addAll(Arrays.asList(assocs));
Collections.sort(fAssocList, ICFileTypeAssociation.Comparator);
}
return added;
}
return fAssocList;
}
public boolean doRemoveAssociations(ICFileTypeAssociation[] assocs) {
boolean removed = false;
if (null != assocs) {
for (int i = 0; i < assocs.length; i++) {
if (fAssocList.remove(assocs[i])) {
removed = true;
}
}
}
if (removed) {
Collections.sort(fAssocList, ICFileTypeAssociation.Comparator);
}
return removed;
}
private static boolean isDebugging() {
return ResolverModel.VERBOSE;
}
private static void debugLog(String message) {
System.out.println("CDT Resolver: " + message); //$NON-NLS-1$
}
}

View file

@ -0,0 +1,311 @@
/*******************************************************************************
* Copyright (c) 2000, 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.internal.filetype;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.ICDescriptor;
import org.eclipse.cdt.core.filetype.ICFileTypeAssociation;
import org.eclipse.cdt.core.filetype.IResolverModel;
import org.eclipse.cdt.core.filetype.ResolverChangeEvent;
import org.eclipse.cdt.core.filetype.ResolverDelta;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
*/
public class CustomResolver extends CFileTypeResolver {
// XML tag names, etc.
private static final String OLD_RESOLVER = "cdt_resolver"; //$NON-NLS-1$
private static final String CDT_RESOLVER = CCorePlugin.PLUGIN_ID + ".resolver"; //$NON-NLS-1$
private static final String TAG_CUSTOM = "custom"; //$NON-NLS-1$
private static final String TAG_ASSOC = "associations"; //$NON-NLS-1$
private static final String TAG_ENTRY = "entry"; //$NON-NLS-1$
private static final String ATTR_TYPE = "type"; //$NON-NLS-1$
private static final String ATTR_PATTERN = "pattern"; //$NON-NLS-1$
private static final String ATTR_VALUE = "value"; //$NON-NLS-1$
private ResolverModel fModel;
public CustomResolver(ResolverModel model, IProject p) {
super(p);
fModel = model;
}
public static boolean hasCustomResolver(IProject project) {
Boolean custom = new Boolean(false);
// Check for old custom resolver but do not convert
Element data = getProjectOldResolverData(project, false);
custom = hasCustomTag(data);
if (!custom.booleanValue()) {
data = getProjectResolverData(project, false);
custom = hasCustomTag(data);
}
return custom.booleanValue();
}
/**
* @param project
*/
public static void removeCustomResover(IProject project) {
Element root = getProjectResolverData(project, false);
if (root != null) {
Node child = root.getFirstChild();
Element element = null;
// Clear the old stuff.
while (child != null) {
root.removeChild(child);
child = root.getFirstChild();
}
try {
getProjectDescriptor(project, true).saveProjectData();
} catch (CoreException e) {
CCorePlugin.log(e);
}
}
}
protected void doAdjustAssociations(ICFileTypeAssociation[] addAssocs, ICFileTypeAssociation[] delAssocs,
boolean triggerEvent) {
IProject project = (IProject)getContainer();
List deltas = new ArrayList();
// add
if (triggerEvent && null != addAssocs && addAssocs.length > 0) {
for (int i = 0; i < addAssocs.length; i++) {
deltas.add(new ResolverDelta(addAssocs[i], ResolverDelta.EVENT_ADD));
}
}
// remove
if (triggerEvent && null != delAssocs && delAssocs.length > 0) {
for (int i = 0; i < delAssocs.length; i++) {
deltas.add(new ResolverDelta(delAssocs[i], ResolverDelta.EVENT_REMOVE));
}
}
// fire the deltas.
if (triggerEvent && !deltas.isEmpty()) {
ResolverChangeEvent event = new ResolverChangeEvent(fModel, this);
for (int i = 0; i < deltas.size(); ++i) {
ResolverDelta delta = (ResolverDelta)deltas.get(i);
event.addDelta(delta);
}
fModel.fireEvent(event);
}
// Save to the file.
Element root = getProjectResolverData(project, true);
Document doc = root.getOwnerDocument();
Node child = root.getFirstChild();
Element element = null;
// Clear the old stuff.
while (child != null) {
root.removeChild(child);
child = root.getFirstChild();
}
element = doc.createElement(TAG_CUSTOM);
element.setAttribute(ATTR_VALUE, Boolean.TRUE.toString());
root.appendChild(element);
element = doc.createElement(TAG_ASSOC);
root.appendChild(element);
root = element; // Note that root changes...
ICFileTypeAssociation[] assoc = getFileTypeAssociations();
for (int i = 0; i < assoc.length; i++) {
element = doc.createElement(TAG_ENTRY);
element.setAttribute(ATTR_PATTERN, assoc[i].getPattern());
element.setAttribute(ATTR_TYPE, assoc[i].getType().getId());
root.appendChild(element);
}
try {
getProjectDescriptor(project, true).saveProjectData();
} catch (CoreException e) {
CCorePlugin.log(e);
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.internal.filetype.CFileTypeResolver#loadAssociations()
*/
protected ICFileTypeAssociation[] loadAssociations() {
IProject project = (IProject)getContainer();
convert20(project);
List assocs = new ArrayList();
Element data = getProjectResolverData(project, false);
Node child = ((null != data) ? data.getFirstChild() : null);
while (child != null) {
if (child.getNodeName().equals(TAG_ASSOC)) {
Node assoc = child.getFirstChild();
while (assoc != null) {
if (assoc.getNodeName().equals(TAG_ENTRY)) {
Element element = (Element) assoc;
String pattern = element.getAttribute(ATTR_PATTERN);
String typeId = element.getAttribute(ATTR_TYPE);
try {
assocs.add(fModel.createAssocation(pattern, fModel.getFileTypeById(typeId)));
} catch (IllegalArgumentException e) {
CCorePlugin.log(e);
}
}
assoc = assoc.getNextSibling();
}
}
child = child.getNextSibling();
}
return (ICFileTypeAssociation[]) assocs.toArray(new ICFileTypeAssociation[assocs.size()]);
}
private static Element getProjectResolverData(IProject project, boolean create) {
Element data = null;
try {
ICDescriptor desc = getProjectDescriptor(project, create);
if (desc != null) {
data = desc.getProjectData(CDT_RESOLVER);
}
} catch (CoreException e) {
// ignore
}
return data;
}
private static ICDescriptor getProjectDescriptor(IProject project, boolean create) throws CoreException {
ICDescriptor descriptor = null;
descriptor = CCorePlugin.getDefault().getCProjectDescription(project, create);
return descriptor;
}
private static Element getProjectOldResolverData(IProject project, boolean create) {
Element data = null;
try {
ICDescriptor desc = getProjectDescriptor(project, create);
if (desc != null) {
data = desc.getProjectData(OLD_RESOLVER);
}
} catch (CoreException e) {
// ignore
}
return data;
}
private static void convert20(IProject project) {
Element root = getProjectOldResolverData(project, false);
if (root != null) {
IResolverModel model = ResolverModel.getDefault();
List assocList = new ArrayList();
// 1 - get the old stuff
Node child = root.getFirstChild();
while (child != null) {
if (child.getNodeName().equals(TAG_ASSOC)) {
Node assoc = child.getFirstChild();
while (assoc != null) {
if (assoc.getNodeName().equals(TAG_ENTRY)) {
Element element = (Element) assoc;
String pattern = element.getAttribute(ATTR_PATTERN);
String typeId = element.getAttribute(ATTR_TYPE);
try {
assocList.add(model.createAssocation(pattern, model.getFileTypeById(typeId)));
} catch (IllegalArgumentException e) {
CCorePlugin.log(e);
}
}
assoc = assoc.getNextSibling();
}
}
child = child.getNextSibling();
}
// 2 - Clear the old stuff.
child = root.getFirstChild();
while (child != null) {
root.removeChild(child);
child = root.getFirstChild();
}
ICFileTypeAssociation[] assocs = (ICFileTypeAssociation[]) assocList.toArray(new ICFileTypeAssociation[assocList.size()]);
if (assocs.length > 0) {
// 3 - save the old stuff on the new id
root = getProjectResolverData(project, true);
if (root != null) {
Document doc = root.getOwnerDocument();
child = root.getFirstChild();
Element element = null;
// Clear the old stuff.
while (child != null) {
root.removeChild(child);
child = root.getFirstChild();
}
element = doc.createElement(TAG_CUSTOM);
element.setAttribute(ATTR_VALUE, Boolean.TRUE.toString());
root.appendChild(element);
element = doc.createElement(TAG_ASSOC);
root.appendChild(element);
root = element; // Note that root changes...
for (int i = 0; i < assocs.length; i++) {
element = doc.createElement(TAG_ENTRY);
element.setAttribute(ATTR_PATTERN, assocs[i].getPattern());
element.setAttribute(ATTR_TYPE, assocs[i].getType().getId());
root.appendChild(element);
}
}
}
try {
getProjectDescriptor(project, true).saveProjectData();
} catch (CoreException e) {
CCorePlugin.log(e);
}
}
}
private static Boolean hasCustomTag(Element data) {
Node child = ((null != data) ? data.getFirstChild() : null);
Boolean custom = new Boolean(false);
while (child != null) {
if (child.getNodeName().equals(TAG_CUSTOM)) {
return Boolean.valueOf(((Element)child).getAttribute(ATTR_VALUE));
}
child = child.getNextSibling();
}
return Boolean.FALSE;
}
}

View file

@ -10,14 +10,9 @@
***********************************************************************/
package org.eclipse.cdt.core.internal.filetype;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@ -29,7 +24,6 @@ import java.util.Properties;
import java.util.Vector;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.ICDescriptor;
import org.eclipse.cdt.core.filetype.ICFileType;
import org.eclipse.cdt.core.filetype.ICFileTypeAssociation;
import org.eclipse.cdt.core.filetype.ICFileTypeConstants;
@ -38,9 +32,8 @@ import org.eclipse.cdt.core.filetype.ICLanguage;
import org.eclipse.cdt.core.filetype.IResolverChangeListener;
import org.eclipse.cdt.core.filetype.IResolverModel;
import org.eclipse.cdt.core.filetype.ResolverChangeEvent;
import org.eclipse.core.resources.IContainer;
import org.eclipse.cdt.core.filetype.ResolverDelta;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
@ -52,11 +45,10 @@ import org.eclipse.core.runtime.IRegistryChangeListener;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.Status;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.eclipse.core.runtime.Preferences.PropertyChangeEvent;
/**
* Implementation of the file type resolver interface.
@ -89,27 +81,16 @@ public class ResolverModel implements IResolverModel {
// Default resolver
private ICFileTypeResolver fDefaultResolver = null;
// Workspace resolver
private ICFileTypeResolver fWkspResolver = null;
// XML tag names, etc.
private static final String EXTENSION_LANG = "CLanguage"; //$NON-NLS-1$
private static final String EXTENSION_TYPE = "CFileType"; //$NON-NLS-1$
private static final String EXTENSION_ASSOC = "CFileTypeAssociation"; //$NON-NLS-1$
private static final String TAG_CUSTOM = "custom"; //$NON-NLS-1$
private static final String TAG_ASSOC = "associations"; //$NON-NLS-1$
private static final String TAG_ENTRY = "entry"; //$NON-NLS-1$
private static final String ATTR_TYPE = "type"; //$NON-NLS-1$
private static final String ATTR_PATTERN = "pattern"; //$NON-NLS-1$
private static final String ATTR_FILE = "file"; //$NON-NLS-1$
private static final String ATTR_ID = "id"; //$NON-NLS-1$
private static final String ATTR_LANGUAGE = "language"; //$NON-NLS-1$
private static final String ATTR_NAME = "name"; //$NON-NLS-1$
private static final String ATTR_VAL_SOURCE = "source"; //$NON-NLS-1$
private static final String ATTR_VAL_HEADER = "header"; //$NON-NLS-1$
private static final String ATTR_VALUE = "value"; //$NON-NLS-1$
private static final String WKSP_STATE_FILE = "resolver.properties"; //$NON-NLS-1$
private static final String CDT_RESOLVER = "cdt_resolver"; //$NON-NLS-1$
// Trace flag
public static boolean VERBOSE = false;
@ -118,8 +99,8 @@ public class ResolverModel implements IResolverModel {
private static ResolverModel fInstance = null;
// Qualified names used to identify project session properties
private static final String RESOLVER_MODEL_ID = CCorePlugin.PLUGIN_ID + ".resolver"; //$NON-NLS-1$
private static final QualifiedName QN_CUSTOM_RESOLVER = new QualifiedName(RESOLVER_MODEL_ID, TAG_CUSTOM);
private static final String QN_RESOLVER_MODEL_ID = CCorePlugin.PLUGIN_ID + ".resolver"; //$NON-NLS-1$
private static final QualifiedName QN_CUSTOM_RESOLVER = new QualifiedName(QN_RESOLVER_MODEL_ID, "custom"); //$NON-NLS-1$
// List of listeners on the model
private List fListeners = new Vector();
@ -131,9 +112,10 @@ public class ResolverModel implements IResolverModel {
loadDeclaredTypes();
fDefaultResolver = loadDefaultResolver();
fWkspResolver = loadWorkspaceResolver();
convertFrom20();
initRegistryChangeListener();
initPreferenceChangeListener();
} catch (Exception e) {
CCorePlugin.log(e);
}
@ -169,56 +151,6 @@ public class ResolverModel implements IResolverModel {
return ((null != type) ? type : DEFAULT_FILE_TYPE);
}
public void setResolver(ICFileTypeResolver newResolver) {
ICFileTypeResolver oldResolver = getResolver();
fWkspResolver = newResolver;
saveWorkspaceResolver(newResolver);
fireResolverChangeEvent(null, oldResolver);
}
public ICFileTypeResolver getResolver() {
return ((null != fWkspResolver) ? fWkspResolver : fDefaultResolver) ;
}
public void setResolver(IProject project, ICFileTypeResolver newResolver) {
ICFileTypeResolver oldResolver = getResolver(project);
try {
project.setSessionProperty(QN_CUSTOM_RESOLVER, newResolver);
} catch (CoreException e) {
}
saveProjectResolver(project, newResolver);
fireResolverChangeEvent(project, oldResolver);
}
public ICFileTypeResolver getResolver(IProject project) {
ICFileTypeResolver resolver = null;
if (null != project) {
try {
Object obj = project.getSessionProperty(QN_CUSTOM_RESOLVER);
if (obj instanceof ICFileTypeResolver) {
resolver = (ICFileTypeResolver) obj;
}
} catch (CoreException e) {
}
if (null == resolver) {
if (customProjectResolverExists(project)) {
resolver = loadProjectResolver(project);
}
}
}
if (null == resolver) {
resolver = getResolver();
}
return resolver;
}
public ICFileTypeAssociation createAssocation(String pattern, ICFileType type) {
return new CFileTypeAssociation(pattern, type);
}
/**
* Add an instance of a language to the languages known to the
* resolver.
@ -230,14 +162,11 @@ public class ResolverModel implements IResolverModel {
*
* @return true if the language is added, false otherwise
*/
public boolean addLanguage(ICLanguage lang) {
IContainer root = ResourcesPlugin.getWorkspace().getRoot();
List list = new ArrayList(1);
boolean result = addLanguage(root, list, lang);
public boolean addLanguages(ICLanguage[] langs) {
ResolverChangeEvent event = new ResolverChangeEvent(this, getResolver());
boolean result = addLanguages(langs, event);
if (true == result) {
ResolverChangeEvent[] events = new ResolverChangeEvent[list.size()];
list.toArray(events);
fireEvent(events);
fireEvent(event);
}
return result;
}
@ -253,14 +182,11 @@ public class ResolverModel implements IResolverModel {
*
* @return true if the file type is added, false otherwise
*/
public boolean addFileType(ICFileType type) {
IContainer root = ResourcesPlugin.getWorkspace().getRoot();
List list = new ArrayList(1);
boolean result = addFileType(root, list, type);
public boolean addFileTypes(ICFileType[] types) {
ResolverChangeEvent event = new ResolverChangeEvent(this, getResolver());
boolean result = addFileTypes(types, event);
if (true == result) {
ResolverChangeEvent[] events = new ResolverChangeEvent[list.size()];
list.toArray(events);
fireEvent(events);
fireEvent(event);
}
return result;
}
@ -272,14 +198,11 @@ public class ResolverModel implements IResolverModel {
*
* @return true if the language is removed, false otherwise
*/
public boolean removeLanguage(ICLanguage lang) {
IContainer root = ResourcesPlugin.getWorkspace().getRoot();
List list = new ArrayList(1);
boolean result = removeLanguage(root, list, lang);
public boolean removeLanguages(ICLanguage[] langs) {
ResolverChangeEvent event = new ResolverChangeEvent(this, getResolver());
boolean result = removeLanguages(langs, event);
if (true == result) {
ResolverChangeEvent[] events = new ResolverChangeEvent[list.size()];
list.toArray(events);
fireEvent(events);
fireEvent(event);
}
return result;
}
@ -291,18 +214,113 @@ public class ResolverModel implements IResolverModel {
*
* @return true if the file type is removed, false otherwise
*/
public boolean removeFileType(ICFileType type) {
IContainer root = ResourcesPlugin.getWorkspace().getRoot();
List list = new ArrayList(1);
boolean result = removeFileType(root, list, type);
public boolean removeFileTypes(ICFileType[] types) {
ResolverChangeEvent event = new ResolverChangeEvent(this, getResolver());
boolean result = removeFileTypes(types, event);
if (true == result) {
ResolverChangeEvent[] events = new ResolverChangeEvent[list.size()];
list.toArray(events);
fireEvent(events);
fireEvent(event);
}
return result;
}
public ICFileTypeResolver getResolver() {
return fDefaultResolver;
}
public boolean hasCustomResolver(IProject project) {
return CustomResolver.hasCustomResolver(project);
}
public ICFileTypeResolver createCustomResolver(IProject project, ICFileTypeResolver copy) {
ICFileTypeAssociation[] oldAssocs = null;
ICFileTypeAssociation[] newAssocs = null;
// get the old resolver first, creating the new will erase stuff in the cdescriptor.
ICFileTypeResolver oldResolver = getResolver(project);
if (oldResolver != null) {
oldAssocs = oldResolver.getFileTypeAssociations();
}
ICFileTypeResolver newResolver = new CustomResolver(this, project);
if (copy != null) {
newAssocs = copy.getFileTypeAssociations();
newResolver.addAssociations(newAssocs);
}
// cache the result in project session property.
try {
project.setSessionProperty(QN_CUSTOM_RESOLVER, newResolver);
} catch (CoreException e) {
}
ResolverChangeEvent event = new ResolverChangeEvent(this, newResolver, oldResolver);
fireResolverChangeEvent(event, newAssocs, oldAssocs);
return newResolver;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.filetype.IResolverModel#removeCustomResolver(org.eclipse.core.resources.IProject)
*/
public void removeCustomResolver(IProject project) {
ICFileTypeAssociation[] oldAssocs = null;
ICFileTypeAssociation[] newAssocs = null;
// get the old resolver first, creating the new will erase stuff in the cdescriptor.
ICFileTypeResolver oldResolver = getResolver(project);
if (oldResolver != null) {
oldAssocs = oldResolver.getFileTypeAssociations();
}
ICFileTypeResolver newResolver = getResolver();
// cache the result in project session property.
try {
project.setSessionProperty(QN_CUSTOM_RESOLVER, null);
} catch (CoreException e) {
}
CustomResolver.removeCustomResover(project);
ResolverChangeEvent event = new ResolverChangeEvent(this, newResolver, oldResolver);
fireResolverChangeEvent(event, newAssocs, oldAssocs);
}
public ICFileTypeResolver getResolver(IProject project) {
ICFileTypeResolver resolver = null;
if (null != project) {
try {
Object obj = project.getSessionProperty(QN_CUSTOM_RESOLVER);
if (obj instanceof ICFileTypeResolver) {
resolver = (ICFileTypeResolver) obj;
}
} catch (CoreException e) {
}
if (null == resolver) {
if (hasCustomResolver(project)) {
resolver = new CustomResolver(this, project);
// cache the result in the session property.
try {
project.setSessionProperty(QN_CUSTOM_RESOLVER, resolver);
} catch (CoreException e) {
}
}
}
}
if (null == resolver) {
resolver = getResolver();
}
return resolver;
}
public ICFileTypeAssociation createAssocation(String pattern, ICFileType type) {
return new CFileTypeAssociation(pattern, type);
}
public void addResolverChangeListener(IResolverChangeListener listener) {
fListeners.add(listener);
}
@ -327,82 +345,14 @@ public class ResolverModel implements IResolverModel {
System.out.println("CDT Resolver: " + message); //$NON-NLS-1$
}
//----------------------------------------------------------------------
// Registry change event handling
//----------------------------------------------------------------------
public void fireEvent(final ResolverChangeEvent event) {
private boolean addLanguage(IContainer container, List list, ICLanguage lang) {
boolean added = false;
if (!fLangMap.containsValue(lang)) {
fLangMap.put(lang.getId(), lang);
if (null != list) {
ResolverChangeEvent event = new ResolverChangeEvent(container, ResolverChangeEvent.EVENT_ADD, lang);
list.add(event);
}
added = true;
}
return added;
}
private boolean addFileType(IContainer container, List list, ICFileType type) {
boolean added = false;
if (!fTypeMap.containsValue(type)) {
fTypeMap.put(type.getId(), type);
if (null != list) {
ResolverChangeEvent event = new ResolverChangeEvent(container, ResolverChangeEvent.EVENT_ADD, type);
list.add(event);
}
added = true;
}
return added;
}
private boolean removeLanguage(IContainer container, List list, ICLanguage lang) {
boolean removed = (null != fLangMap.remove(lang.getId()));
if (removed) {
if (null != list) {
ResolverChangeEvent event = new ResolverChangeEvent(container, ResolverChangeEvent.EVENT_REMOVE, lang);
list.add(event);
}
ArrayList removeList = new ArrayList();
for (Iterator iter = fTypeMap.values().iterator(); iter.hasNext();) {
ICFileType type = (ICFileType) iter.next();
if (lang.equals(type.getLanguage())) {
removeList.add(type);
}
}
for (Iterator iter = removeList.iterator(); iter.hasNext();) {
removeFileType(container, list, (ICFileType) iter.next());
}
}
return removed;
}
private boolean removeFileType(IContainer container, List list, ICFileType type) {
boolean removed = (null != fTypeMap.remove(type.getId()));
if (removed) {
if (null != list) {
ResolverChangeEvent event = new ResolverChangeEvent(container, ResolverChangeEvent.EVENT_REMOVE, type);
list.add(event);
}
// TODO: must remove any associations based on this file type as well
// Unforuntately, at this point, that means iterating over the contents
// of the default, workspace, and project resolvers. Ugh.
}
return removed;
}
private void fireEvent(final ResolverChangeEvent[] events) {
if (events == null || events.length == 0) {
if (event == null) {
return;
}
if (isDebugging()) {
for (int i = 0; i < events.length; i++) {
debugLog(events[i].toString());
}
debugLog(event.toString());
}
if (fListeners.isEmpty()) {
@ -421,49 +371,30 @@ public class ResolverModel implements IResolverModel {
CCorePlugin.log(status);
}
public void run() throws Exception {
listeners[index].resolverChanged(events);
listeners[index].resolverChanged(event);
}
});
}
}
private void fireResolverChangeEvent(IProject project, ICFileTypeResolver oldResolver) {
IContainer container = project;
ICFileTypeResolver newResolver = getResolver(project);
//ResolverChangeEvent event = new ResolverChangeEvent(newResolver);
//int element = ResolverDelta.ELEMENT_WORKSPACE;
//if (null != project) {
// element = ResolverDelta.ELEMENT_PROJECT;
//}
//event.addDelta(new ResolverDelta(ResolverDelta.EVENT_SET, element, project));
private void fireResolverChangeEvent(ResolverChangeEvent event, ICFileTypeAssociation[] newAssocs,
ICFileTypeAssociation[] oldAssocs) {
List list = new ArrayList();
if (container == null) {
container = ResourcesPlugin.getWorkspace().getRoot();
}
list.add(new ResolverChangeEvent(container, ResolverChangeEvent.EVENT_SET, newResolver));
if ((null != oldAssocs) && (null != newAssocs)) {
if ((null != oldResolver) && (null != newResolver)) {
ICFileTypeAssociation[] oldAssoc = oldResolver.getFileTypeAssociations();
ICFileTypeAssociation[] newAssoc = newResolver.getFileTypeAssociations();
for (int i = 0; i < oldAssoc.length; i++) {
if (Arrays.binarySearch(newAssoc, oldAssoc[i], ICFileTypeAssociation.Comparator) < 0) {
//event.addDelta(new ResolverDelta(oldAssoc[i], ResolverDelta.EVENT_REMOVE));
list.add(new ResolverChangeEvent(container, ResolverChangeEvent.EVENT_REMOVE, oldAssoc[i]));
for (int i = 0; i < oldAssocs.length; i++) {
if (Arrays.binarySearch(newAssocs, oldAssocs[i], ICFileTypeAssociation.Comparator) < 0) {
event.addDelta(new ResolverDelta(oldAssocs[i], ResolverDelta.EVENT_REMOVE));
}
}
for (int i = 0; i < newAssoc.length; i++) {
if (Arrays.binarySearch(oldAssoc, newAssoc[i], ICFileTypeAssociation.Comparator) < 0) {
//event.addDelta(new ResolverDelta(newAssoc[i], ResolverDelta.EVENT_ADD));
list.add(new ResolverChangeEvent(container, ResolverChangeEvent.EVENT_ADD, newAssoc[i]));
for (int i = 0; i < newAssocs.length; i++) {
if (Arrays.binarySearch(oldAssocs, newAssocs[i], ICFileTypeAssociation.Comparator) < 0) {
event.addDelta(new ResolverDelta(newAssocs[i], ResolverDelta.EVENT_ADD));
}
}
}
ResolverChangeEvent[] events = new ResolverChangeEvent[list.size()];
list.toArray(events);
fireEvent(events);
fireEvent(event);
}
private void initRegistryChangeListener() {
@ -474,33 +405,122 @@ public class ResolverModel implements IResolverModel {
}, CCorePlugin.PLUGIN_ID);
}
private void initPreferenceChangeListener() {
Preferences prefs = CCorePlugin.getDefault().getPluginPreferences();
prefs.addPropertyChangeListener(new Preferences.IPropertyChangeListener() {
/* (non-Javadoc)
* @see org.eclipse.core.runtime.Preferences.IPropertyChangeListener#propertyChange(org.eclipse.core.runtime.Preferences.PropertyChangeEvent)
*/
public void propertyChange(PropertyChangeEvent event) {
handlePropertyChanged(event);
}
});
}
protected void handlePropertyChanged(Preferences.PropertyChangeEvent event) {
String property = event.getProperty();
if (property != null) {
if (WorkspaceResolver.PREFS_ASSOCIATIONS_EXCLUSION.equals(property) ||
WorkspaceResolver.PREFS_ASSOCIATIONS_INCLUSION.equals(property)) {
fDefaultResolver = loadDefaultResolver();
}
}
}
protected void handleRegistryChanged(IRegistryChangeEvent event) {
IExtensionDelta[] deltas = null;
//ResolverChangeEvent modelEvent = new ResolverChangeEvent(null);
List list = new ArrayList();
IContainer container = ResourcesPlugin.getWorkspace().getRoot();
ResolverChangeEvent modelEvent = new ResolverChangeEvent(this, getResolver());
deltas = event.getExtensionDeltas(CCorePlugin.PLUGIN_ID, EXTENSION_LANG);
for (int i = 0; i < deltas.length; i++) {
processLanguageExtension(container, list, deltas[i].getExtension(), IExtensionDelta.ADDED == deltas[i].getKind());
processLanguageExtension(modelEvent, deltas[i].getExtension(), IExtensionDelta.ADDED == deltas[i].getKind());
}
deltas = event.getExtensionDeltas(CCorePlugin.PLUGIN_ID, EXTENSION_TYPE);
for (int i = 0; i < deltas.length; i++) {
processTypeExtension(container, list, deltas[i].getExtension(), IExtensionDelta.ADDED == deltas[i].getKind());
processTypeExtension(modelEvent, deltas[i].getExtension(), IExtensionDelta.ADDED == deltas[i].getKind());
}
deltas = event.getExtensionDeltas(CCorePlugin.PLUGIN_ID, EXTENSION_ASSOC);
if (deltas.length != 0) {
fDefaultResolver = loadDefaultResolver();
fWkspResolver = loadWorkspaceResolver();
//fWkspResolver = loadWorkspaceResolver();
}
if (!list.isEmpty()) {
ResolverChangeEvent[] events = new ResolverChangeEvent[list.size()];
list.toArray(events);
fireEvent(events);
fireEvent(modelEvent);
}
private boolean addLanguages(ICLanguage[] langs, ResolverChangeEvent event) {
boolean added = false;
for (int i = 0; i < langs.length; ++i) {
ICLanguage lang = langs[i];
if (!fLangMap.containsValue(lang)) {
fLangMap.put(lang.getId(), lang);
if (null != event) {
event.addDelta(new ResolverDelta(lang, ResolverDelta.EVENT_ADD));
}
added = true;
}
}
return added;
}
private boolean addFileTypes(ICFileType[] types, ResolverChangeEvent event) {
boolean added = false;
for (int i = 0; i < types.length; ++i) {
ICFileType type = types[i];
if (!fTypeMap.containsValue(type)) {
fTypeMap.put(type.getId(), type);
event.addDelta(new ResolverDelta(type, ResolverDelta.EVENT_ADD));
added = true;
}
}
return added;
}
private boolean removeLanguages(ICLanguage[] langs, ResolverChangeEvent event) {
boolean del = false;
ArrayList removeTypeList = new ArrayList(langs.length);
for (int i = 0; i < langs.length; ++i) {
ICLanguage lang = langs[i];
boolean removed = (null != fLangMap.remove(lang.getId()));
if (removed) {
event.addDelta(new ResolverDelta(lang, ResolverDelta.EVENT_REMOVE));
del = true;
for (Iterator iter = fTypeMap.values().iterator(); iter.hasNext();) {
ICFileType type = (ICFileType) iter.next();
if (lang.equals(type.getLanguage())) {
removeTypeList.add(type);
}
}
}
}
if (!removeTypeList.isEmpty()) {
ICFileType[] types = (ICFileType[]) removeTypeList.toArray(new ICFileType[removeTypeList.size()]);
removeFileTypes(types, event);
}
return del;
}
private boolean removeFileTypes(ICFileType[] types, ResolverChangeEvent event) {
boolean changed = false;
for (int i = 0; i < types.length; ++i) {
ICFileType type = types[i];
boolean removed = (null != fTypeMap.remove(type.getId()));
if (removed) {
changed = true;
if (null != event) {
event.addDelta(new ResolverDelta(type, ResolverDelta.EVENT_REMOVE));
}
// TODO: must remove any associations based on this file type as well
// Unforuntately, at this point, that means iterating over the contents
// of the default, workspace, and project resolvers. Ugh.
}
}
return changed;
}
//----------------------------------------------------------------------
// Extension point handling
@ -512,22 +532,16 @@ public class ResolverModel implements IResolverModel {
private void loadDeclaredLanguages() {
IExtensionPoint point = getExtensionPoint(EXTENSION_LANG);
IExtension[] extensions = point.getExtensions();
//ResolverChangeEvent event = new ResolverChangeEvent(null);
IContainer root = ResourcesPlugin.getWorkspace().getRoot();
List list = new ArrayList();
ResolverChangeEvent event = new ResolverChangeEvent(this, getResolver());
for (int i = 0; i < extensions.length; i++) {
processLanguageExtension(root, list, extensions[i], true);
processLanguageExtension(event, extensions[i], true);
}
// Shouldn't have anything listening here, but generating
// the events helps maintain internal consistency w/logging
if (!list.isEmpty()) {
ResolverChangeEvent[] events = new ResolverChangeEvent[list.size()];
list.toArray(events);
fireEvent(events);
}
fireEvent(event);
}
/**
@ -536,44 +550,42 @@ public class ResolverModel implements IResolverModel {
private void loadDeclaredTypes() {
IExtensionPoint point = getExtensionPoint(EXTENSION_TYPE);
IExtension[] extensions = point.getExtensions();
//ResolverChangeEvent event = new ResolverChangeEvent(null);
IContainer root = ResourcesPlugin.getWorkspace().getRoot();
List list = new ArrayList();
ResolverChangeEvent event = new ResolverChangeEvent(this, getResolver());
for (int i = 0; i < extensions.length; i++) {
processTypeExtension(root, list, extensions[i], true);
processTypeExtension(event, extensions[i], true);
}
// Shouldn't have anything listening here, but generating
// the events helps maintain internal consistency w/logging
if (!list.isEmpty()) {
ResolverChangeEvent[] events = new ResolverChangeEvent[list.size()];
list.toArray(events);
fireEvent(events);
}
fireEvent(event);
}
private void processLanguageExtension(IContainer container, List list, IExtension extension, boolean add) {
private void processLanguageExtension(ResolverChangeEvent event, IExtension extension, boolean add) {
IConfigurationElement[] elements = extension.getConfigurationElements();
List list = new ArrayList(elements.length);
for (int i = 0; i < elements.length; i++) {
String id = elements[i].getAttribute(ATTR_ID);
String name = elements[i].getAttribute(ATTR_NAME);
try {
ICLanguage element = new CLanguage(id, name);
if (add) {
addLanguage(container, list, element);
} else {
removeLanguage(container, list, element);
}
list.add (element);
} catch (IllegalArgumentException e) {
CCorePlugin.log(e);
}
}
ICLanguage[] langs = (ICLanguage[]) list.toArray(new ICLanguage[list.size()]);
if (add) {
addLanguages(langs, event);
} else {
removeLanguages(langs, event);
}
}
private void processTypeExtension(IContainer container, List list, IExtension extension, boolean add) {
private void processTypeExtension(ResolverChangeEvent event, IExtension extension, boolean add) {
IConfigurationElement[] elements = extension.getConfigurationElements();
List list = new ArrayList(elements.length);
for (int i = 0; i < elements.length; i++) {
String id = elements[i].getAttribute(ATTR_ID);
String lang = elements[i].getAttribute(ATTR_LANGUAGE);
@ -582,15 +594,17 @@ public class ResolverModel implements IResolverModel {
try {
ICFileType element = new CFileType(id, getLanguageById(lang), name, parseType(type));
if (add) {
addFileType(container, list, element);
} else {
removeFileType(container, list, element);
}
list.add(element);
} catch (IllegalArgumentException e) {
CCorePlugin.log(e);
}
}
ICFileType[] types = (ICFileType[]) list.toArray(new ICFileType[list.size()]);
if (add) {
addFileTypes(types, event);
} else {
removeFileTypes(types, event);
}
}
/**
@ -622,97 +636,29 @@ public class ResolverModel implements IResolverModel {
* declared extension points.
*/
private ICFileTypeResolver loadDefaultResolver() {
List assoc = new ArrayList();
ICFileTypeResolver resolver = new CFileTypeResolver(ResourcesPlugin.getWorkspace().getRoot());
IExtensionPoint point = getExtensionPoint(EXTENSION_ASSOC);
IExtension[] extensions = point.getExtensions();
IConfigurationElement[] elements = null;
for (int i = 0; i < extensions.length; i++) {
elements = extensions[i].getConfigurationElements();
for (int j = 0; j < elements.length; j++) {
ICFileType typeRef = getFileTypeById(elements[j].getAttribute(ATTR_TYPE));
if (null != typeRef) {
assoc.addAll(getAssocFromPattern(typeRef, elements[j]));
assoc.addAll(getAssocFromFile(typeRef, elements[j]));
}
}
}
resolver.addAssociations((ICFileTypeAssociation[]) assoc.toArray(new ICFileTypeAssociation[assoc.size()]));
return resolver;
}
/**
* Associate one or more file extensions with an ICFileType instance.
*
* @param typeRef reference to the ICFileType instance
*
* @param element configuration element to get file extensions from
*/
private List getAssocFromPattern(ICFileType typeRef, IConfigurationElement element) {
List assocs = new ArrayList();
String attr = element.getAttribute(ATTR_PATTERN);
if (null != attr) {
String[] item = attr.split(","); //$NON-NLS-1$
for (int i = 0; i < item.length; i++) {
try {
assocs.add(createAssocation(item[i].trim(), typeRef));
} catch (IllegalArgumentException e) {
CCorePlugin.log(e);
}
}
}
return assocs;
}
/**
* Associate the contents of a file with an ICFileType instance.
*
* The file is read, one entry per line; each line is taken as
* a pattern that should be associated with the specified ICFileType
* instance.
*
* @param typeRef reference to the ICFileType instance
*
* @param element configuration element to get file extensions from
*/
private List getAssocFromFile(ICFileType typeRef, IConfigurationElement element) {
List assocs = new ArrayList();
String attr = element.getAttribute(ATTR_FILE);
if (null != attr) {
URL baseURL = null;
URL fileURL = null;
BufferedReader in = null;
String line = null;
try {
baseURL = Platform.getBundle(element.getDeclaringExtension().getNamespace()).getEntry("/"); //$NON-NLS-1$
fileURL = new URL(baseURL, attr);
in = new BufferedReader(new InputStreamReader(fileURL.openStream()));
line = in.readLine();
while (null != line) {
try {
assocs.add(createAssocation(line.trim(), typeRef));
} catch (IllegalArgumentException e) {
CCorePlugin.log(e);
}
line = in.readLine();
}
in.close();
} catch (IOException e) {
CCorePlugin.log(e);
}
}
return assocs;
return new WorkspaceResolver(this);
}
//----------------------------------------------------------------------
// Workspace resolver
//----------------------------------------------------------------------
private static final String WKSP_STATE_FILE = "resolver.properties"; //$NON-NLS-1$
private void convertFrom20() {
if (customWorkspaceResolverExists()) {
ICFileTypeAssociation[] assocs = loadWorkspaceResolver();
if (assocs != null && assocs.length > 0) {
getResolver().addAssociations(assocs);
}
try {
getWorkspaceResolverStateFilePath().toFile().delete();
} catch (Exception e) {
//
}
}
}
private boolean customWorkspaceResolverExists() {
return getWorkspaceResolverStateFilePath().toFile().exists();
}
@ -721,17 +667,14 @@ public class ResolverModel implements IResolverModel {
return CCorePlugin.getDefault().getStateLocation().append(WKSP_STATE_FILE);
}
private ICFileTypeResolver loadWorkspaceResolver() {
private ICFileTypeAssociation[] loadWorkspaceResolver() {
List assocs = new ArrayList();
ICFileTypeResolver resolver = null;
File file = getWorkspaceResolverStateFilePath().toFile();
if (file.exists()) {
Properties props = new Properties();
FileInputStream in = null;
resolver = new CFileTypeResolver(ResourcesPlugin.getWorkspace().getRoot());
try {
in = new FileInputStream(file);
@ -747,151 +690,20 @@ public class ResolverModel implements IResolverModel {
}
}
} catch (IOException e) {
CCorePlugin.log(e);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
CCorePlugin.log(e);
//
}
if (null != in) {
in = null;
}
resolver.addAssociations((ICFileTypeAssociation[]) assocs.toArray(new ICFileTypeAssociation[assocs.size()]));
}
return resolver;
}
private void saveWorkspaceResolver(ICFileTypeResolver resolver) {
File file = getWorkspaceResolverStateFilePath().toFile();
BufferedWriter out = null;
try {
if (null == resolver) {
file.delete();
} else {
out = new BufferedWriter(new FileWriter(file));
ICFileTypeAssociation[] assoc = resolver.getFileTypeAssociations();
for (int i = 0; i < assoc.length; i++) {
out.write(assoc[i].getPattern() + '=' + assoc[i].getType().getId() + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
}
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
if (null != out) {
out = null;
}
}
//----------------------------------------------------------------------
// Project resolver
//----------------------------------------------------------------------
private boolean customProjectResolverExists(IProject project) {
Element data = getProjectData(project, false);
Node child = ((null != data) ? data.getFirstChild() : null);
Boolean custom = new Boolean(false);
while (child != null) {
if (child.getNodeName().equals(TAG_CUSTOM)) {
custom = Boolean.valueOf(((Element)child).getAttribute(ATTR_VALUE));
}
child = child.getNextSibling();
return ((ICFileTypeAssociation[]) assocs.toArray(new ICFileTypeAssociation[assocs.size()]));
}
return custom.booleanValue();
}
private ICDescriptor getProjectDescriptor(IProject project, boolean create) throws CoreException {
ICDescriptor descriptor = null;
descriptor = CCorePlugin.getDefault().getCProjectDescription(project, create);
return descriptor;
}
private Element getProjectData(IProject project, boolean create) {
Element data = null;
try {
ICDescriptor desc = getProjectDescriptor(project, create);
if (desc != null) {
data = desc.getProjectData(CDT_RESOLVER);
}
} catch (CoreException e) {
}
return data;
}
private ICFileTypeResolver loadProjectResolver(IProject project) {
List assocs = new ArrayList();
ICFileTypeResolver resolver = new CFileTypeResolver(project);
Element data = getProjectData(project, false);
Node child = ((null != data) ? data.getFirstChild() : null);
while (child != null) {
if (child.getNodeName().equals(TAG_ASSOC)) {
Node assoc = child.getFirstChild();
while (assoc != null) {
if (assoc.getNodeName().equals(TAG_ENTRY)) {
Element element = (Element) assoc;
String pattern = element.getAttribute(ATTR_PATTERN);
String typeId = element.getAttribute(ATTR_TYPE);
try {
assocs.add(createAssocation(pattern, getFileTypeById(typeId)));
} catch (IllegalArgumentException e) {
CCorePlugin.log(e);
}
}
assoc = assoc.getNextSibling();
}
}
child = child.getNextSibling();
}
resolver.addAssociations((ICFileTypeAssociation[]) assocs.toArray(new ICFileTypeAssociation[assocs.size()]));
return resolver;
}
private void saveProjectResolver(IProject project, ICFileTypeResolver resolver) {
Element root = getProjectData(project, true);
Document doc = root.getOwnerDocument();
Node child = root.getFirstChild();
Element element = null;
while (child != null) {
root.removeChild(child);
child = root.getFirstChild();
}
element = doc.createElement(TAG_CUSTOM);
element.setAttribute(ATTR_VALUE, new Boolean(null != resolver).toString());
root.appendChild(element);
if (null != resolver) {
element = doc.createElement(TAG_ASSOC);
root.appendChild(element);
root = element; // Note that root changes...
ICFileTypeAssociation[] assoc = resolver.getFileTypeAssociations();
for (int i = 0; i < assoc.length; i++) {
element = doc.createElement(TAG_ENTRY);
element.setAttribute(ATTR_PATTERN, assoc[i].getPattern());
element.setAttribute(ATTR_TYPE, assoc[i].getType().getId());
root.appendChild(element);
}
}
try {
getProjectDescriptor(project, true).saveProjectData();
} catch (CoreException e) {
CCorePlugin.log(e);
}
}
}

View file

@ -0,0 +1,303 @@
/*******************************************************************************
* Copyright (c) 2000, 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.internal.filetype;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.filetype.ICFileType;
import org.eclipse.cdt.core.filetype.ICFileTypeAssociation;
import org.eclipse.cdt.core.filetype.ResolverChangeEvent;
import org.eclipse.cdt.core.filetype.ResolverDelta;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Preferences;
/**
*/
public class WorkspaceResolver extends CFileTypeResolver {
public static final String PREFS_ASSOCIATIONS_INCLUSION = CCorePlugin.PLUGIN_ID + ".associationInclusion";
public static final String PREFS_ASSOCIATIONS_EXCLUSION = CCorePlugin.PLUGIN_ID + ".associationExclusion";
ResolverModel fModel;
private static final String EXTENSION_ASSOC = "CFileTypeAssociation"; //$NON-NLS-1$
private static final String ATTR_TYPE = "type"; //$NON-NLS-1$
private static final String ATTR_PATTERN = "pattern"; //$NON-NLS-1$
private static final String ATTR_FILE = "file"; //$NON-NLS-1$
public WorkspaceResolver() {
this(ResolverModel.getDefault());
}
public WorkspaceResolver(ResolverModel model) {
super(ResourcesPlugin.getWorkspace().getRoot());
fModel = model;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.internal.filetype.CFileTypeResolver#doAdjustAssociations(org.eclipse.cdt.core.filetype.ICFileTypeAssociation[], org.eclipse.cdt.core.filetype.ICFileTypeAssociation[], boolean, org.eclipse.core.runtime.IProgressMonitor)
*/
protected void doAdjustAssociations(ICFileTypeAssociation[] addAssocs,
ICFileTypeAssociation[] delAssocs, boolean triggerEvent) {
List deltas = new ArrayList();
// add
if (triggerEvent && null != addAssocs && addAssocs.length > 0) {
for (int i = 0; i < addAssocs.length; i++) {
deltas.add(new ResolverDelta(addAssocs[i], ResolverDelta.EVENT_ADD));
}
}
// remove
if (triggerEvent && null != delAssocs && delAssocs.length > 0) {
for (int i = 0; i < delAssocs.length; i++) {
deltas.add(new ResolverDelta(delAssocs[i], ResolverDelta.EVENT_REMOVE));
}
}
// fire the deltas.
if (triggerEvent && !deltas.isEmpty()) {
ResolverChangeEvent event = new ResolverChangeEvent(fModel, this);
for (int i = 0; i < deltas.size(); ++i) {
ResolverDelta delta = (ResolverDelta)deltas.get(i);
event.addDelta(delta);
}
fModel.fireEvent(event);
}
// add
if (null != addAssocs && addAssocs.length > 0) {
List inclusion = getInclusionAssociations();
inclusion.addAll(Arrays.asList(addAssocs));
ICFileTypeAssociation[] newInclusion = ((ICFileTypeAssociation[]) inclusion.toArray(new ICFileTypeAssociation[inclusion.size()]));
setInclusionAssociations(newInclusion);
}
// remove
if (null != delAssocs && delAssocs.length > 0) {
List exclusion = getExclusionAssociations();
exclusion.addAll(Arrays.asList(delAssocs));
ICFileTypeAssociation[] newExclusion = ((ICFileTypeAssociation[]) exclusion.toArray(new ICFileTypeAssociation[exclusion.size()]));
setExclusionAssociations(newExclusion);
}
if ((null != addAssocs && addAssocs.length > 0) || (null != delAssocs && delAssocs.length > 0)) {
CCorePlugin.getDefault().savePluginPreferences();
}
}
public List getExtensionsAssociations() {
List assoc = new ArrayList();
IExtensionPoint point = getExtensionPoint(EXTENSION_ASSOC);
IExtension[] extensions = point.getExtensions();
IConfigurationElement[] elements = null;
for (int i = 0; i < extensions.length; i++) {
elements = extensions[i].getConfigurationElements();
for (int j = 0; j < elements.length; j++) {
ICFileType typeRef = fModel.getFileTypeById(elements[j].getAttribute(ATTR_TYPE));
if (null != typeRef) {
assoc.addAll(getAssocFromExtension(typeRef, elements[j]));
assoc.addAll(getAssocFromFile(typeRef, elements[j]));
}
}
}
return assoc;
}
public List getDefaultInclusionAssociations() {
Preferences prefs = CCorePlugin.getDefault().getPluginPreferences();
String s = prefs.getDefaultString(PREFS_ASSOCIATIONS_INCLUSION);
String[] items = s.split(";"); //$NON-NLS-1$
List assoc = getAssocFromPreferences(items);
return assoc;
}
public List getInclusionAssociations() {
Preferences prefs = CCorePlugin.getDefault().getPluginPreferences();
String s = prefs.getString(PREFS_ASSOCIATIONS_INCLUSION);
String[] items = s.split(";"); //$NON-NLS-1$
List assoc = getAssocFromPreferences(items);
return assoc;
}
private void setInclusionAssociations(ICFileTypeAssociation[] addAssocs) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < addAssocs.length; ++i) {
if (sb.length() > 0) {
sb.append(';');
}
sb.append(addAssocs[i].getPattern());
sb.append("!!"); //$NON-NLS-1
sb.append(addAssocs[i].getType().getId());
}
Preferences prefs = CCorePlugin.getDefault().getPluginPreferences();
String s = prefs.getString(PREFS_ASSOCIATIONS_INCLUSION);
if (s.length() > 0) {
sb.append(';').append(s);
}
prefs.setValue(PREFS_ASSOCIATIONS_INCLUSION, sb.toString());
}
public List getDefaultExclusionAssociations() {
Preferences prefs = CCorePlugin.getDefault().getPluginPreferences();
String s = prefs.getDefaultString(PREFS_ASSOCIATIONS_EXCLUSION);
String[] items = s.split(";"); //$NON-NLS-1$
List assocs = getAssocFromPreferences(items);
return assocs;
}
public List getExclusionAssociations() {
Preferences prefs = CCorePlugin.getDefault().getPluginPreferences();
String s = prefs.getString(PREFS_ASSOCIATIONS_EXCLUSION);
String[] items = s.split(";"); //$NON-NLS-1$
List assocs = getAssocFromPreferences(items);
return assocs;
}
private void setExclusionAssociations(ICFileTypeAssociation[] addAssocs) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < addAssocs.length; ++i) {
if (sb.length() > 0) {
sb.append(';');
}
sb.append(addAssocs[i].getPattern());
sb.append("!!"); //$NON-NLS-1
sb.append(addAssocs[i].getType().getId());
}
Preferences prefs = CCorePlugin.getDefault().getPluginPreferences();
String s = prefs.getString(PREFS_ASSOCIATIONS_EXCLUSION);
if (s.length() > 0) {
sb.append(';').append(s);
}
prefs.setValue(PREFS_ASSOCIATIONS_EXCLUSION, sb.toString());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.internal.filetype.CFileTypeResolver#loadAssociations()
*/
protected ICFileTypeAssociation[] loadAssociations() {
List assocs = new ArrayList();
List exclusion = getExclusionAssociations();
List inclusion = getInclusionAssociations();
for (int i = 0; i < inclusion.size(); ++i) {
Object inc = inclusion.get(i);
if (!exclusion.contains(inc)) {
assocs.add(inc);
}
}
List extensions = getExtensionsAssociations();
for (int i = 0; i < extensions.size(); ++i) {
Object ext = extensions.get(i);
if (!exclusion.contains(ext)) {
assocs.add(ext);
}
}
return ((ICFileTypeAssociation[]) assocs.toArray(new ICFileTypeAssociation[assocs.size()]));
}
/**
* Associate one or more file extensions with an ICFileType instance.
*
* @param typeRef reference to the ICFileType instance
*
* @param element configuration element to get file extensions from
*/
private List getAssocFromExtension(ICFileType typeRef, IConfigurationElement element) {
List assocs = new ArrayList();
String attr = element.getAttribute(ATTR_PATTERN);
if (null != attr) {
String[] item = attr.split(","); //$NON-NLS-1$
for (int i = 0; i < item.length; i++) {
try {
assocs.add(fModel.createAssocation(item[i].trim(), typeRef));
} catch (IllegalArgumentException e) {
CCorePlugin.log(e);
}
}
}
return assocs;
}
private List getAssocFromPreferences(String[] items) {
List assocs = new ArrayList();
for (int i = 0; i < items.length; ++i) {
String[] item = items[i].split("!!"); //$NON-NLS-1$
if (item.length == 2) {
String pattern = item[0].trim();
ICFileType typeRef = fModel.getFileTypeById(item[1]);
try {
assocs.add(fModel.createAssocation(pattern, typeRef));
} catch (IllegalArgumentException e) {
CCorePlugin.log(e);
}
}
}
return assocs;
}
/**
* Associate the contents of a file with an ICFileType instance.
*
* The file is read, one entry per line; each line is taken as
* a pattern that should be associated with the specified ICFileType
* instance.
*
* @param typeRef reference to the ICFileType instance
*
* @param element configuration element to get file extensions from
*/
private List getAssocFromFile(ICFileType typeRef, IConfigurationElement element) {
List assocs = new ArrayList();
String attr = element.getAttribute(ATTR_FILE);
if (null != attr) {
URL baseURL = null;
URL fileURL = null;
BufferedReader in = null;
String line = null;
try {
baseURL = Platform.getBundle(element.getDeclaringExtension().getNamespace()).getEntry("/"); //$NON-NLS-1$
fileURL = new URL(baseURL, attr);
in = new BufferedReader(new InputStreamReader(fileURL.openStream()));
line = in.readLine();
while (null != line) {
try {
assocs.add(fModel.createAssocation(line.trim(), typeRef));
} catch (IllegalArgumentException e) {
CCorePlugin.log(e);
}
line = in.readLine();
}
in.close();
} catch (IOException e) {
CCorePlugin.log(e);
}
}
return assocs;
}
private IExtensionPoint getExtensionPoint(String extensionPointId) {
return Platform.getExtensionRegistry().getExtensionPoint(CCorePlugin.PLUGIN_ID, extensionPointId);
}
}