Eclipse 4.x中Command是如何映射到Handler的

本文介绍了Eclipse 4.x中Command模式的设计,如何在没有源码时确定Command对应的Handler。Eclipse在启动后创建了一个CommandId与Handler的映射并存储在EclipseContext中。通过反射,可以将EclipseContext中的Handler信息导出。内容展示了部分具体的CommandId与其对应的ActionHandler实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

...

IWAB0503E Unable to update Java build path. Please check your system environment. java.io.FileNotFoundException: /lib/axis.jar at org.eclipse.osgi.storage.url.bundleentry.Handler.findBundleEntry(Handler.java:55) at org.eclipse.osgi.storage.url.BundleResourceHandler.openConnection(BundleResourceHandler.java:186) at java.base/java.net.URL.openConnection(URL.java:1094) at org.eclipse.osgi.storage.url.BundleURLConverter.toFileURL(BundleURLConverter.java:41) at org.eclipse.core.runtime.FileLocator.toFileURL(FileLocator.java:277) at org.eclipse.core.runtime.Platform.asLocalURL(Platform.java:640) at org.eclipse.jst.ws.internal.axis.consumption.ui.task.CopyAxisJarCommand.getTheJarPath(CopyAxisJarCommand.java:434) at org.eclipse.jst.ws.internal.axis.consumption.ui.task.CopyAxisJarCommand.addAxisJarsToBuildPath(CopyAxisJarCommand.java:319) at org.eclipse.jst.ws.internal.axis.consumption.ui.task.CopyAxisJarCommand.execute(CopyAxisJarCommand.java:129) at org.eclipse.jst.ws.internal.axis.consumption.ui.task.ClientCodeGenOperation$ClientWSModifyOperation.execute(ClientCodeGenOperation.java:137) at org.eclipse.ui.actions.WorkspaceModifyOperation.lambda$0(WorkspaceModifyOperation.java:112) at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2448) at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2473) at org.eclipse.ui.actions.WorkspaceModifyOperation.run(WorkspaceModifyOperation.java:131) at org.eclipse.jst.ws.internal.axis.consumption.ui.task.ClientCodeGenOperation.execute(ClientCodeGenOperation.java:69) at org.eclipse.wst.command.internal.env.core.fragment.CommandFragmentEngine.runCommand(CommandFragmentEngine.java:421) at org.eclipse.wst.command.internal.env.core.fragment.CommandFragmentEngine.visitTop(CommandFragmentEngine.java:361) at org.eclipse.wst.command.internal.env.core.fragment.CommandFragmentEngine.moveForwardToNextStop(CommandFragmentEngine.java:256) at
03-13
at org.eclipse.ui.internal.handlers.LegacyHandlerService$HandlerSelectionFunction.compute(LegacyHandlerService.java:143) at org.eclipse.e4.core.internal.contexts.ValueComputation.get(ValueComputation.java:70) at org.eclipse.e4.core.internal.contexts.EclipseContext.internalGet(EclipseContext.java:243) at org.eclipse.e4.core.internal.contexts.EclipseContext.get(EclipseContext.java:230) at org.eclipse.e4.core.commands.internal.HandlerServiceImpl.lookUpHandler(HandlerServiceImpl.java:99) at org.eclipse.e4.core.commands.internal.HandlerServiceHandler.setEnabled(HandlerServiceHandler.java:81) at org.eclipse.core.commands.Command.setEnabled(Command.java:856) at org.eclipse.e4.core.commands.internal.HandlerServiceImpl.canExecute(HandlerServiceImpl.java:170) at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem.canExecuteItem(HandledContributionItem.java:465) at org.eclipse.e4.ui.workbench.renderers.swt.AbstractContributionItem$1.run(AbstractContributionItem.java:512) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:47) at org.eclipse.e4.ui.workbench.renderers.swt.AbstractContributionItem.updateItemEnablement(AbstractContributionItem.java:553) at org.eclipse.e4.ui.workbench.renderers.swt.ToolItemUpdater.run(ToolItemUpdater.java:87) at org.eclipse.swt.widgets.Display.timerProc(Display.java:5738) at org.eclipse.swt.internal.gtk3.GTK3.gtk_main_iteration_do(Native Method) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:4521) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1151) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1042) at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:668) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:576) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:173) at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:178) at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:208) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:149) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:115) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:467) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:298) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:670) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:607) at org.eclipse.equinox.launcher.Main.run(Main.java:1492) at org.eclipse.equinox.launcher.Main.main(Main.java:1465)
最新发布
06-01
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值