问题
I have many XML files in the workbench Project Explorer, each one an instance of one of ten different ecore models. For each ecore model I would like to contribute a commonFilter
to the navigator's navigatorContent
extension point to enable the user to show or hide the corresponding XML files. These are external tool files so there is not a way to identify the content merely by observing the file name or the xml
extension, and renaming is not feasible. Using perhaps a class deriving from org.eclipse.jface.viewers.ViewerFilter
, what is the best way to identify which of the ecore models the XML file contains? I presume there is a simple way to do this with EMF resources, or with EcoreUtil
, or with adapters, but I haven't found a successful technique. Alternatively, a way to do this directly from the extension point's filterExpression
or the viewer's viewerContentBinding
would be fine. All of the genmodel
-derived plugins are available for the various ecore models.
package com.my.navigator;
import org.eclipse.core.resources.IFile;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
public class MyViewerFilter extends ViewerFilter {
public MyViewerFilter() {
}
@Override
public boolean select(Viewer viewer, Object parentElement, Object element) {
if ( element instanceof IFile ) {
IFile file = (IFile)element;
// check whether file is one of our ecore models...
// ...
}
return true;
}
}
回答1:
You could use the org.eclipse.core.contenttype.contentTypes
to define new content types for your file.
Use the describer
argument of the content type definition to specify a 'content describer' class which can check that the XML file meets your requirements. There is already an XMLContentDescriber
class that you can use as a basis for the describer.
For example this is the content type definition for Ant build.xml files:
<extension
point="org.eclipse.core.contenttype.contentTypes">
<content-type
id="antBuildFile"
name="%antBuildFileContentType.name"
base-type="org.eclipse.core.runtime.xml"
file-names="build.xml"
file-extensions="macrodef,ent,xml,ant"
priority="normal">
<describer
class="org.eclipse.ant.internal.core.contentDescriber.AntBuildfileContentDescriber">
</describer>
</content-type>
</extension>
and this is the Ant content describer to give you a rough idea of what you can:
public final class AntBuildfileContentDescriber extends XMLContentDescriber implements IExecutableExtension {
private int checkCriteria(InputSource contents) throws IOException {
AntHandler antHandler = new AntHandler();
try {
if (!antHandler.parseContents(contents)) {
return INDETERMINATE;
}
}
catch (SAXException e) {
// we may be handed any kind of contents... it is normal we fail to parse
return INDETERMINATE;
}
catch (ParserConfigurationException e) {
// some bad thing happened - force this describer to be disabled
String message = "Internal Error: XML parser configuration error during content description for Ant buildfiles"; //$NON-NLS-1$
throw new RuntimeException(message);
}
// Check to see if we matched our criteria.
if (antHandler.hasRootProjectElement()) {
if (antHandler.hasProjectDefaultAttribute() || antHandler.hasTargetElement() || antHandler.hasAntElement()) {
// project and default attribute or project and target element(s)
// or project and top level ant element(s) (classpath, import, macrodef, path, property, taskdef, typedef)
return VALID;
}
// only a top level project element...maybe an Ant buildfile
return INDETERMINATE;
}
return INDETERMINATE;
}
@Override
public int describe(InputStream contents, IContentDescription description) throws IOException {
// call the basic XML describer to do basic recognition
if (super.describe(contents, description) == INVALID) {
return INVALID;
}
// super.describe will have consumed some chars, need to rewind
contents.reset();
// Check to see if we matched our criteria.
return checkCriteria(new InputSource(contents));
}
@Override
public int describe(Reader contents, IContentDescription description) throws IOException {
// call the basic XML describer to do basic recognition
if (super.describe(contents, description) == INVALID) {
return INVALID;
}
// super.describe will have consumed some chars, need to rewind
contents.reset();
// Check to see if we matched our criteria.
return checkCriteria(new InputSource(contents));
}
@Override
public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException {
// do nothing
}
}
来源:https://stackoverflow.com/questions/27971748/eclipse-project-explorer-filter-for-xml-files