上一篇文章我们知道了Eclipse弹出菜单的基本用法。其实Eclipse的弹出菜单可以用来做很多文章,简单一点的根据文件类别,我们可以进行不同的文件操作,比如Ant的build.xml我们可以用来build,Java文件我们可以用Java Editor打开,这些基于文件类型的操作我们都可以很容易的实现。但是还有一种情况,如果文件类型一样,我们想进行不同的操作,该怎么实现呢?实际上这样的应用很多,比如同样是Java文件,含有main方法的Java文件有Run和Debug的选项,其它的都没有。还有现在的框架都是基于XML文件进行配置的,如果一个项目使用了多个框架,我们怎么根据不同的XML文件进行框架的区分呢?答案就是enablement的test。
<!ELEMENT test EMPTY><!ATTLIST testproperty CDATA #REQUIRED args CDATA #IMPLIED value CDATA #IMPLIED>
This element is used to evaluate the property state of the object in focus. The set of testable properties can be extended using the propery tester extension point. The test expression returns EvaluationResult.NOT_LOADED if teh property tester doing the actual testing isn't loaded yet.
property - the name of an object's property to test. args - additional arguments passed to the property tester. Multiple arguments are seperated by commas. Each individual argument is converted into a Java base type using the same rules as defined for the value attribute of the test expression. value - the expected value of the property. Can be omitted if the property is a boolean property. The test expression is supposed to return EvaluationResult.TRUE if the property matches the value and EvaluationResult.FALSE otherwise. The value attribute is converted into a Java base type using the following rules: the string "true" is converted into Boolean.TRUE the string "false" is converted into Boolean.FALSE if the string contains a dot then the interpreter tries to convert the value into a Float object. If this fails the string is treated as a java.lang.String if the string only consists of numbers then the interpreter converts the value in an Integer object. in all other cases the string is treated as a java.lang.String the conversion of the string into a Boolean, Float, or Integer can be suppressed by surrounding the string with single quotes. For example, the attribute value="'true'" is converted into the string "true"比如我们要让含有main方法的Java文件它的右键弹出菜单包含一个额外的选项“This is main class”,需要编写如下的Plugin.xml:
< plugin > < extension point ="org.eclipse.ui.popupMenus" > < objectContribution id ="Advanced.PopupMenus" objectClass ="java.lang.Object" > < action id ="Advanced.PopupMenus.Action" label ="AdvancedPopupMenus" style ="pulldown" menubarPath ="additions" class ="advancedpopupmenus.popup.actions.AdvancedPopupMenusAction" enablesFor ="+" > </ action > < enablement > < test property ="advancedpopupmenus.popup.visable" /> </ enablement > </ objectContribution > </ extension > < extension point ="org.eclipse.core.expressions.propertyTesters" > < propertyTester namespace ="advancedpopupmenus.popup" properties ="visable" type ="java.lang.Object" class ="advancedpopupmenus.popup.actions.VisablePropertyTester" id ="advancedpopupmenus.popup.propertyTesters.visable" > </ propertyTester > </ extension > </ plugin >我们需要检测在当前情况下是否需要显示这个菜单项,使用扩展点 org.eclipse.core.expressions.propertyTesters :<!ELEMENT propertyTester EMPTY><!ATTLIST propertyTesterid CDATA #REQUIREDtype CDATA #REQUIREDnamespace CDATA #REQUIREDproperties CDATA #REQUIREDclass CDATA #REQUIRED>
id - unique identifier for the property tester type - the type to be extended by this property tester namespace - a unique id determining the name space the properties are added to properties - a comma separated list of properties provided by this property tester class - the name of the class that implements the testing methods. The class must be public and extend org.eclipse.core.expressions.PropertyTester with a public 0-argument constructor. 这里只须注意 propertyTester的namespace和properties正好对应test的property。至于检测的逻辑我们在advancedpopupmenus.popup.actions.VisablePropertyTester中实现,这个类必须继承自org.eclipse.core.expressions.PropertyTester。
package advancedpopupmenus.popup.actions;import org.eclipse.core.expressions.PropertyTester;import org.eclipse.jdt.core.IMethod;import org.eclipse.jdt.core.IType;import org.eclipse.jdt.core.JavaModelException;import org.eclipse.jdt.internal.core.CompilationUnit;public class VisablePropertyTester extends PropertyTester{ public boolean test( Object receiver, String property, Object[] args, Object expectedValue ) { if ( ! ( receiver instanceof CompilationUnit ) ) return false ; CompilationUnit unit = (CompilationUnit) receiver; try { IType[] types = unit.getTypes( ); if ( types == null ) return false ; for ( int i = 0 ; i < types.length; i ++ ) { IMethod[] methods = types[i].getMethods( ); if ( methods == null ) return false ; for ( int j = 0 ; j < methods.length; j ++ ) { if ( methods[j].isMainMethod( ) ) return true ; } } } catch ( JavaModelException e ) { e.printStackTrace( ); } return false ; }}我们只要判断接受的Java文件中是否含有main方法,如果有,则返回True,没有则返回False。如果我们是要接受一个Web开发的配置文件,我们可以这样写:
< plugin > < extension point ="org.eclipse.ui.popupMenus" > < objectContribution id ="Advanced.PopupMenus" objectClass ="org.eclipse.core.resources.IFile" nameFilter ="*.xml" > < action id ="Advanced.PopupMenus.Action" label ="This is web xml" style ="pulldown" menubarPath ="additions" class ="advancedpopupmenus.popup.actions.AdvancedPopupMenusAction" enablesFor ="+" > </ action > < enablement > < test property ="advancedpopupmenus.popup.visable" /> </ enablement > </ objectContribution > </ extension > < extension point ="org.eclipse.core.expressions.propertyTesters" > < propertyTester namespace ="advancedpopupmenus.popup" properties ="visable" type ="org.eclipse.core.resources.IFile" class ="advancedpopupmenus.popup.actions.VisablePropertyTester" id ="advancedpopupmenus.popup.propertyTesters.visable" > </ propertyTester > </ extension > </ plugin >注意和上一个例子不同的地方,objectClass,nameFileter和type(在上一个例子中,我们也可以使用objectClass="org.eclipse.core.resources.IFile" nameFilter ="*.java" ),相应的我们的VisablePropertyTester类也要做一些改动:
package advancedpopupmenus.popup.actions;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import org.eclipse.core.expressions.PropertyTester;import org.eclipse.core.resources.IFile;import org.w3c.dom.Document;import org.w3c.dom.DocumentType;public class VisablePropertyTester extends PropertyTester{ public boolean test( Object receiver, String property, Object[] args, Object expectedValue ) { if ( ! ( receiver instanceof IFile ) ) return false ; IFile xml = (IFile) receiver; try { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance( ); DocumentBuilder db = dbf.newDocumentBuilder( ); Document doc = db.parse( xml.getContents( ) ); DocumentType type = doc.getDoctype( ); if (type.getSystemId( ).equalsIgnoreCase( " http://java.sun.com/j2ee/dtds/web-app_2_2.dtd " )) return true ; } catch ( Exception e ) { e.printStackTrace( ); } return false ; }}这样根据不同的xml SystemID,我们就能够知道到底这是哪一种框架的配置文件了。
备注:本文转载自:http://www.blogjava.net/mlzry0612/articles/221505.html