1. Eclipse中的Command模式,使得具体的实现和Command定义分离,便于维护。
但是在Debug的时候,或者没有souce code的时候,我们想知道每一个commandId对应的Handler是什么,怎么办?
2. 在Eclipse
4.x中,其实当Eclipse启动完成后,它已经创建了commandId和对应Handler的Map,保存在EclipseContext中,
然后通过反射调用到对应的Handler。 见下图:
Eclipse是在上图中我框出来的地方,通过commandId在EclipseContext中查找到。
3. 如何将EclipseContext中的Handler都dump出来呢?
一句话,反射。
注意,以下代码我只在Eclipse 4.3.0上测试通过。
//try to print all handler in eclipse 4.x
result = ReflectionUtils.getField("e4Context", site);
if(!isSuccess(result)) {
return;
}
if(result instanceof IEclipseContext) {
IEclipseContext context = (IEclipseContext)result;
printHandlerForEclipseContext(context, 0);
}
@SuppressWarnings("unchecked")
private void printHandlerForEclipseContext(IEclipseContext context, int step) {
Assert.isNotNull(context);
Object result = null;
if(step != 0) {
result = ReflectionUtils.getField("localValueComputations", context);
} else {
result = ReflectionUtils.getField("localValues", context);
}
if(!isSuccess(result)) {
return;
}
if(result instanceof Map) {
String stepString = makeStep(step);
Map<String, Object> localValueComputations = (Map<String, Object>)result;
for (String string : localValueComputations.keySet()) {
Object object = localValueComputations.get(string);
String last = object.toString();
if(string.startsWith("legacy::handler::")) {
if(object instanceof ArrayList) {
ArrayList list = (ArrayList)object;
//TODO may be more than one item in list
object = list.get(0);
if(object instanceof IHandlerActivation) {
IHandlerActivation activation = (IHandlerActivation)object;
last = activation.getHandler().toString();
}
}
}
System.out.println(stepString + string + ", " + last);
}
}
result = null;
result = ReflectionUtils.invokeMethod(context, "getChildren");
if(!isSuccess(result)) {
return;
}
if(result instanceof Set) {
Set<IEclipseContext> children = (Set<IEclipseContext>)result;
Iterator<IEclipseContext> iterator = children.iterator();
IEclipseContext child = null;
int moreStep = step + 1;
while(iterator.hasNext()) {
child = iterator.next();
printHandlerForEclipseContext(child, moreStep);
}
step ++;
}
}
以下是我的屏幕输出的一部分,输出格式为:commandId, Handler
…
legacy::handler::org.eclipse.ui.edit.text.recenter,
ActionHandler(org.eclipse.ui.texteditor.RecenterAction@7efaa9e2)
legacy::handler::org.eclipse.jdt.ui.edit.text.java.search.declarations.in.hierarchy,
ActionHandler(org.eclipse.jdt.ui.actions.FindDeclarationsInHierarchyAction@14c26e4a)
legacy::handler::org.eclipse.jdt.ui.edit.text.java.search.declarations.in.project,
ActionHandler(org.eclipse.jdt.ui.actions.FindDeclarationsInProjectAction@174043f5)
legacy::handler::org.eclipse.jdt.ui.edit.text.java.surround.with.try.multicatch,
ActionHandler(org.eclipse.jdt.ui.actions.SurroundWithTryMultiCatchAction@49e3c996)
legacy::handler::org.eclipse.jdt.ui.edit.text.java.override.methods,
ActionHandler(org.eclipse.jdt.ui.actions.OverrideMethodsAction@11e18e8c)
legacy::handler:: org.eclipse.ui.edit.findPrevious , ActionHandler(
org.eclipse.ui.texteditor.FindNextAction @69d5ee81)
handler::org.eclipse.jdt.ui.edit.text.java.remove.block.comment,
org.eclipse.ui.internal.handlers.LegacyHandlerService$HandlerSelectionFunction@207462c0
…