diff --git a/core/src/main/java/com/taobao/arthas/core/command/view/ResultViewResolver.java b/core/src/main/java/com/taobao/arthas/core/command/view/ResultViewResolver.java index 6e46a00a9..0ef7d8d30 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/view/ResultViewResolver.java +++ b/core/src/main/java/com/taobao/arthas/core/command/view/ResultViewResolver.java @@ -3,16 +3,21 @@ package com.taobao.arthas.core.command.view; import com.alibaba.arthas.deps.org.slf4j.Logger; import com.alibaba.arthas.deps.org.slf4j.LoggerFactory; import com.taobao.arthas.core.command.model.*; +import com.taobao.arthas.core.shell.command.CommandProcess; +import java.lang.reflect.Method; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** + * Result view resolver for term + * * @author gongdewei 2020/3/27 */ public class ResultViewResolver { private static final Logger logger = LoggerFactory.getLogger(ResultViewResolver.class); + // modelClass -> view private Map resultViewMap = new ConcurrentHashMap(); private static ResultViewResolver viewResolver; @@ -32,13 +37,13 @@ public class ResultViewResolver { private void registerResultViews() { try { - registerView(new StatusModel(), new StatusView()); - registerView(new VersionModel(), new VersionView()); - registerView(new MessageModel(), new MessageView()); - registerView(new HelpModel(), new HelpView()); - //registerView(new HistoryModel(), new HistoryView()); - registerView(new EchoModel(), new EchoView()); - registerView(new CatModel(), new CatView()); + registerView(StatusView.class); + registerView(VersionView.class); + registerView(MessageView.class); + registerView(HelpView.class); + //registerView(HistoryView.class); + registerView(EchoView.class); + registerView(CatView.class); } catch (Throwable e) { logger.error("register result view failed", e); } @@ -47,20 +52,55 @@ public class ResultViewResolver { private ResultViewResolver() { } -// public void registerView(Class resultClass, ResultView view) throws IllegalAccessException, InstantiationException { -// ExecResult instance = resultClass.newInstance(); -// this.registerView(instance.getType(), view); -// } - - public void registerView(T resultObject, ResultView view) { - this.registerView(resultObject.getType(), view); + public void registerView(Class modelClass, ResultView view) { + //TODO 检查model的type是否重复,减少复制代码带来的bug + this.resultViewMap.put(modelClass.getName(), view); } - public void registerView(String resultType, ResultView view) { - resultViewMap.put(resultType, view); + public void registerView(ResultView view) { + Class modelClass = getModelClass(view); + if (modelClass == null) { + throw new NullPointerException("model class is null"); + } + this.registerView(modelClass, view); } - public ResultView getResultView(String resultType) { - return resultViewMap.get(resultType); + public void registerView(Class viewClass) { + ResultView view = null; + try { + view = viewClass.newInstance(); + } catch (Throwable e) { + throw new RuntimeException("create view instance failure, viewClass:" + viewClass, e); + } + this.registerView(view); + } + + public ResultView getResultView(ResultModel model) { + return resultViewMap.get(model.getClass().getName()); + } + + + /** + * Get model class of result view + * + * @return + */ + public static Class getModelClass(V view) { + //类反射获取子类的draw方法第二个参数的ResultModel具体类型 + Class viewClass = view.getClass(); + Method[] declaredMethods = viewClass.getDeclaredMethods(); + for (int i = 0; i < declaredMethods.length; i++) { + Method method = declaredMethods[i]; + if (method.getName().equals("draw")) { + Class[] parameterTypes = method.getParameterTypes(); + if (parameterTypes.length == 2 + && parameterTypes[0] == CommandProcess.class + && parameterTypes[1] != ResultModel.class + && ResultModel.class.isAssignableFrom(parameterTypes[1])) { + return parameterTypes[1]; + } + } + } + return null; } } diff --git a/core/src/main/java/com/taobao/arthas/core/distribution/impl/TermResultDistributorImpl.java b/core/src/main/java/com/taobao/arthas/core/distribution/impl/TermResultDistributorImpl.java index c47d69e04..cc460a4fe 100644 --- a/core/src/main/java/com/taobao/arthas/core/distribution/impl/TermResultDistributorImpl.java +++ b/core/src/main/java/com/taobao/arthas/core/distribution/impl/TermResultDistributorImpl.java @@ -22,10 +22,10 @@ public class TermResultDistributorImpl implements ResultDistributor { } @Override - public void appendResult(ResultModel result) { - ResultView resultView = resultViewResolver.getResultView(result.getType()); + public void appendResult(ResultModel model) { + ResultView resultView = resultViewResolver.getResultView(model); if (resultView != null) { - resultView.draw(commandProcess, result); + resultView.draw(commandProcess, model); } }