XML 个文件的 Eclipse Project Explorer 过滤器

Eclipse Project Explorer filter for XML files

我在 workbench Project Explorer 中有许多 XML 文件,每个文件都是十种不同 ecore 模型之一的实例。对于每个 ecore 模型,我想为导航器的 navigatorContent 扩展点贡献一个 commonFilter,以使用户能够显示或隐藏相应的 XML 文件。这些是外部工具文件,因此无法仅通过观察文件名或 xml 扩展名来识别内容,并且重命名也不可行。可能使用从 org.eclipse.jface.viewers.ViewerFilter 派生的 class,识别 XML 文件包含哪些 ecore 模型的最佳方法是什么?我认为有一种简单的方法可以使用 EMF 资源、EcoreUtil 或适配器来执行此操作,但我还没有找到成功的技术。或者,直接从扩展点的 filterExpression 或查看器的 viewerContentBinding 执行此操作的方法会很好。所有 genmodel 派生的插件都可用于各种 ecore 模型。

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;
    }

}

您可以使用 org.eclipse.core.contenttype.contentTypes 为您的文件定义新的内容类型。

使用内容类型定义的describer参数指定一个'content describer'class可以检查XML文件是否满足您的要求。已经有一个 XMLContentDescriber class 可以用作描述符的基础。

例如,这是 Ant build.xml 文件的内容类型定义:

<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>

这是 Ant 内容描述器,可让您大致了解您可以做什么:

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
    }
}