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:
parent
f56c0202be
commit
c931ca6163
12 changed files with 1292 additions and 752 deletions
|
@ -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.
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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$
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue