提交 1e6749c1 authored 作者: 黄夏豪's avatar 黄夏豪

fix(base): 修改了socket出参没有统一格式的情况

上级 c0080236
...@@ -21,12 +21,13 @@ import org.matrix.actuators.httpclient.HttpRequestDetail; ...@@ -21,12 +21,13 @@ import org.matrix.actuators.httpclient.HttpRequestDetail;
import org.matrix.actuators.httpclient.HttpResponseDetail; import org.matrix.actuators.httpclient.HttpResponseDetail;
import org.matrix.database.service.IExecutionHistoryService; import org.matrix.database.service.IExecutionHistoryService;
import org.matrix.enums.ExecutionHistoryStatus; import org.matrix.enums.ExecutionHistoryStatus;
import org.matrix.exception.ExecutionRunningException; import org.matrix.exception.JobOrCaseRunningException;
import org.matrix.exception.GlobalException; import org.matrix.exception.GlobalException;
import org.matrix.socket.ExecutionStatusMonitorSocketHandler; import org.matrix.socket.ExecutionStatusMonitorSocketHandler;
import org.matrix.socket.pool.TestCaseExecuteSocketPool; import org.matrix.socket.pool.TestCaseExecuteSocketPool;
import org.matrix.socket.queue.LogQueueRuntime; import org.matrix.socket.queue.LogQueueRuntime;
import org.matrix.socket.vo.CaseExecuteVo; import org.matrix.socket.vo.CaseExecuteVo;
import org.matrix.socket.vo.SocketResponseMessage;
import org.matrix.socket.vo.TestExecuteLog; import org.matrix.socket.vo.TestExecuteLog;
import org.matrix.util.JsonFormatUtil; import org.matrix.util.JsonFormatUtil;
import org.matrix.util.SpringUtils; import org.matrix.util.SpringUtils;
...@@ -95,7 +96,7 @@ public class CaseActuator implements Actuator { ...@@ -95,7 +96,7 @@ public class CaseActuator implements Actuator {
testCaseBto.getTestData()); testCaseBto.getTestData());
//执行中置动作 //执行中置动作
executeMove(testCaseBto.getTestCase().getMoveAfterTest() executeMove(testCaseBto.getTestCase().getMoveAfterTest()
, envId, projectId, baseTestCaseResponseDetail!=null?baseTestCaseResponseDetail.getResponseBody():null, MoveStrategy.MID_MOVE); , envId, projectId, baseTestCaseResponseDetail != null ? baseTestCaseResponseDetail.getResponseBody() : null, MoveStrategy.MID_MOVE);
//进行检验 //进行检验
CheckPointResult checkPointResult = getCheckPointResult(testCaseBto.getTestCase(), CheckPointResult checkPointResult = getCheckPointResult(testCaseBto.getTestCase(),
testCaseBto.getTestData(), testCaseBto.getTestData(),
...@@ -104,7 +105,7 @@ public class CaseActuator implements Actuator { ...@@ -104,7 +105,7 @@ public class CaseActuator implements Actuator {
baseTestCaseResponseDetail); baseTestCaseResponseDetail);
//执行后置动作 //执行后置动作
executeMove(testCaseBto.getTestCase().getMoveAfterCase() executeMove(testCaseBto.getTestCase().getMoveAfterCase()
, envId, projectId, baseTestCaseResponseDetail!=null?baseTestCaseResponseDetail.getResponseBody():null, MoveStrategy.AFT_MOVE); , envId, projectId, baseTestCaseResponseDetail != null ? baseTestCaseResponseDetail.getResponseBody() : null, MoveStrategy.AFT_MOVE);
TestDataExecuteResult testDataExecuteResult = new TestDataExecuteResult( TestDataExecuteResult testDataExecuteResult = new TestDataExecuteResult(
dataStartTime, dataStartTime,
LocalDateTime.now(), LocalDateTime.now(),
...@@ -146,7 +147,7 @@ public class CaseActuator implements Actuator { ...@@ -146,7 +147,7 @@ public class CaseActuator implements Actuator {
LogQueueRuntime.addNewLog(this.getClass(), CASE_ACTUATOR, "[用例执行器] 即将开始执行中置动作"); LogQueueRuntime.addNewLog(this.getClass(), CASE_ACTUATOR, "[用例执行器] 即将开始执行中置动作");
//执行中置动作 //执行中置动作
executeMove(testCaseBto.getTestCase().getMoveAfterTest() executeMove(testCaseBto.getTestCase().getMoveAfterTest()
, envId, projectId, baseTestCaseResponseDetail!=null?baseTestCaseResponseDetail.getResponseBody():null, MoveStrategy.MID_MOVE); , envId, projectId, baseTestCaseResponseDetail != null ? baseTestCaseResponseDetail.getResponseBody() : null, MoveStrategy.MID_MOVE);
CheckPointResult checkPointResult = getCheckPointResult(testCaseBto.getTestCase(), CheckPointResult checkPointResult = getCheckPointResult(testCaseBto.getTestCase(),
testData, testData,
envId, envId,
...@@ -165,7 +166,7 @@ public class CaseActuator implements Actuator { ...@@ -165,7 +166,7 @@ public class CaseActuator implements Actuator {
LogQueueRuntime.addNewLog(this.getClass(), CASE_ACTUATOR, "用例执行结果:" + JsonFormatUtil.formatJson(JSONObject.toJSONString(testDataExecuteResult))); LogQueueRuntime.addNewLog(this.getClass(), CASE_ACTUATOR, "用例执行结果:" + JsonFormatUtil.formatJson(JSONObject.toJSONString(testDataExecuteResult)));
//执行后置动作 //执行后置动作
executeMove(testCaseBto.getTestCase().getMoveAfterCase() executeMove(testCaseBto.getTestCase().getMoveAfterCase()
, envId, projectId, baseTestCaseResponseDetail!=null?baseTestCaseResponseDetail.getResponseBody():null, MoveStrategy.AFT_MOVE); , envId, projectId, baseTestCaseResponseDetail != null ? baseTestCaseResponseDetail.getResponseBody() : null, MoveStrategy.AFT_MOVE);
changeExecutionHistoryStatus(ExecutionHistoryStatus.FINISH); changeExecutionHistoryStatus(ExecutionHistoryStatus.FINISH);
} catch (Exception e) { } catch (Exception e) {
dataSourceService.switchMainDataSource(); dataSourceService.switchMainDataSource();
...@@ -182,7 +183,7 @@ public class CaseActuator implements Actuator { ...@@ -182,7 +183,7 @@ public class CaseActuator implements Actuator {
resultList.add(testDataExecuteResult); resultList.add(testDataExecuteResult);
changeExecutionHistoryStatus(ExecutionHistoryStatus.ERROR); changeExecutionHistoryStatus(ExecutionHistoryStatus.ERROR);
LogQueueRuntime.addNewLog(this.getClass(), CASE_ACTUATOR, String.format("[用例执行器] 执行数据组ID:%s 数据组名称:%s 产生错误:%s", testData.getId(), testData.getName(), e.getMessage())); LogQueueRuntime.addNewLog(this.getClass(), CASE_ACTUATOR, String.format("[用例执行器] 执行数据组ID:%s 数据组名称:%s 产生错误:%s", testData.getId(), testData.getName(), e.getMessage()));
}finally { } finally {
clearMoveData(); clearMoveData();
//将线程中正在执行的DataId清除 //将线程中正在执行的DataId清除
LogQueueRuntime.clearTestData(); LogQueueRuntime.clearTestData();
...@@ -244,6 +245,7 @@ public class CaseActuator implements Actuator { ...@@ -244,6 +245,7 @@ public class CaseActuator implements Actuator {
/** /**
* 根据Case的Detail进行Case的核心部分执行 * 根据Case的Detail进行Case的核心部分执行
*
* @param envId * @param envId
* @param projectId * @param projectId
* @param testCase * @param testCase
...@@ -254,11 +256,11 @@ public class CaseActuator implements Actuator { ...@@ -254,11 +256,11 @@ public class CaseActuator implements Actuator {
Long envId, Long projectId, TestCase testCase, TestData testData) { Long envId, Long projectId, TestCase testCase, TestData testData) {
if (testCase.getType().equals(TestCaseTypeEnum.HTTP.getValue())) { if (testCase.getType().equals(TestCaseTypeEnum.HTTP.getValue())) {
HttpRequestDetail httpRequestDetail = JSON.parseObject(testData.getDetail(), HttpRequestDetail.class); HttpRequestDetail httpRequestDetail = JSON.parseObject(testData.getDetail(), HttpRequestDetail.class);
if (httpRequestDetail==null||httpRequestDetail.getMethod()==null||httpRequestDetail.getRequestType()==null){ if (httpRequestDetail == null || httpRequestDetail.getMethod() == null || httpRequestDetail.getRequestType() == null) {
throw new GlobalException("HTTP请求发送失败,测试数据组中不存在请求数据"); throw new GlobalException("HTTP请求发送失败,测试数据组中不存在请求数据");
} }
return httpClientActuator.sendHttpRequest(httpRequestDetail, envId, projectId); return httpClientActuator.sendHttpRequest(httpRequestDetail, envId, projectId);
}else { } else {
throw new GlobalException("不支持当前测试用例的类型"); throw new GlobalException("不支持当前测试用例的类型");
} }
} }
...@@ -292,7 +294,7 @@ public class CaseActuator implements Actuator { ...@@ -292,7 +294,7 @@ public class CaseActuator implements Actuator {
Long currentThreadId = ThreadUtil.currentThreadId(); Long currentThreadId = ThreadUtil.currentThreadId();
try { try {
if (session != null && session.isOpen()) { if (session != null && session.isOpen()) {
session.sendMessage(new TextMessage(JSONObject.toJSONString(caseExecuteVo))); session.sendMessage(new TextMessage(SocketResponseMessage.success(JSONObject.toJSONString(caseExecuteVo))));
} }
//将websocketSession 加入到socket池子中 //将websocketSession 加入到socket池子中
TestCaseExecuteSocketPool.add(currentThreadId, session); TestCaseExecuteSocketPool.add(currentThreadId, session);
...@@ -316,7 +318,7 @@ public class CaseActuator implements Actuator { ...@@ -316,7 +318,7 @@ public class CaseActuator implements Actuator {
, caseExecuteVo.getType() , caseExecuteVo.getType()
, uniqueKey , uniqueKey
); );
if (!hasInit){ if (!hasInit) {
//建立执行历史(ExecutionHistory) //建立执行历史(ExecutionHistory)
insertExecutionHistory(uniqueKey, caseExecuteVo); insertExecutionHistory(uniqueKey, caseExecuteVo);
hasInit = true; hasInit = true;
...@@ -331,7 +333,7 @@ public class CaseActuator implements Actuator { ...@@ -331,7 +333,7 @@ public class CaseActuator implements Actuator {
LocalDateTime.now(), LocalDateTime.now(),
testCaseListDataBto.getTestCase().getId(), testCaseListDataBto.getTestCase().getId(),
testCaseListDataBto.getTestCase().getName(), testCaseListDataBto.getTestCase().getName(),
TestCaseTypeEnum.getTypeByValue( testCaseListDataBto.getTestCase().getType()).toString(), TestCaseTypeEnum.getTypeByValue(testCaseListDataBto.getTestCase().getType()).toString(),
testCaseListDataBto.getTestCase().getDetail(), testCaseListDataBto.getTestCase().getDetail(),
testCaseListDataBto.getTestCase().getDes(), testCaseListDataBto.getTestCase().getDes(),
testCaseListDataBto.getTestCase().getMoveBefore(), testCaseListDataBto.getTestCase().getMoveBefore(),
...@@ -342,9 +344,10 @@ public class CaseActuator implements Actuator { ...@@ -342,9 +344,10 @@ public class CaseActuator implements Actuator {
); );
runCaseResult.getCaseReports().add(testCaseReport); runCaseResult.getCaseReports().add(testCaseReport);
} }
} catch (ExecutionRunningException runningException) { } catch (JobOrCaseRunningException runningException) {
//如果发生这个错误,说明用例或者任务,被重复执行了
if (session != null && session.isOpen()) { if (session != null && session.isOpen()) {
session.sendMessage(new TextMessage("-1.-1.-1.-1." + runningException.getMessage())); session.sendMessage(new TextMessage(SocketResponseMessage.fail("-1.-1.-1.-1." + runningException.getMessage())));
} }
break; break;
} catch (Exception e) { } catch (Exception e) {
...@@ -354,7 +357,7 @@ public class CaseActuator implements Actuator { ...@@ -354,7 +357,7 @@ public class CaseActuator implements Actuator {
LocalDateTime.now(), LocalDateTime.now(),
testCaseListDataBto.getTestCase().getId(), testCaseListDataBto.getTestCase().getId(),
testCaseListDataBto.getTestCase().getName(), testCaseListDataBto.getTestCase().getName(),
TestCaseTypeEnum.getTypeByValue( testCaseListDataBto.getTestCase().getType()).toString(), TestCaseTypeEnum.getTypeByValue(testCaseListDataBto.getTestCase().getType()).toString(),
testCaseListDataBto.getTestCase().getDetail(), testCaseListDataBto.getTestCase().getDetail(),
testCaseListDataBto.getTestCase().getDes(), testCaseListDataBto.getTestCase().getDes(),
testCaseListDataBto.getTestCase().getMoveBefore(), testCaseListDataBto.getTestCase().getMoveBefore(),
...@@ -376,7 +379,7 @@ public class CaseActuator implements Actuator { ...@@ -376,7 +379,7 @@ public class CaseActuator implements Actuator {
LogQueueRuntime.addNewLog(this.getClass(), CASE_ACTUATOR, e.getMessage()); LogQueueRuntime.addNewLog(this.getClass(), CASE_ACTUATOR, e.getMessage());
} else { } else {
//这里加-1.-1.-1是用来表明这里发出去的数据是不属于任何执行中的用例的 //这里加-1.-1.-1是用来表明这里发出去的数据是不属于任何执行中的用例的
session.sendMessage(new TextMessage(String.format("-1.-1.-1.%s", e.getMessage()))); session.sendMessage(new TextMessage(SocketResponseMessage.success(String.format("-1.-1.-1.-1.%s", e.getMessage()))));
} }
} }
} catch (IOException ioException) { } catch (IOException ioException) {
......
...@@ -120,7 +120,6 @@ public class TestController { ...@@ -120,7 +120,6 @@ public class TestController {
" }\n" + " }\n" +
" ]\n" + " ]\n" +
"}"; "}";
System.out.println(json);
TestCase testCase = new TestCase(); TestCase testCase = new TestCase();
testCase.setName("name"); testCase.setName("name");
testCase.setType(1); testCase.setType(1);
...@@ -134,6 +133,5 @@ public class TestController { ...@@ -134,6 +133,5 @@ public class TestController {
testCaseBTO.setTestCase(testCase); testCaseBTO.setTestCase(testCase);
testCaseBTO.setTestData(testData); testCaseBTO.setTestData(testData);
TestDataExecuteResult testDataExecuteResult = caseActuator.executeTestCase(testCaseBTO, 1L, 1L); TestDataExecuteResult testDataExecuteResult = caseActuator.executeTestCase(testCaseBTO, 1L, 1L);
System.out.println(testDataExecuteResult);
} }
} }
...@@ -7,20 +7,20 @@ package org.matrix.exception; ...@@ -7,20 +7,20 @@ package org.matrix.exception;
* @since 2022/1/19 at 12:53 PM * @since 2022/1/19 at 12:53 PM
* Suffering is the most powerful teacher of life. * Suffering is the most powerful teacher of life.
*/ */
public class ExecutionRunningException extends RuntimeException { public class JobOrCaseRunningException extends RuntimeException {
public ExecutionRunningException(String message) { public JobOrCaseRunningException(String message) {
super(message); super(message);
} }
public ExecutionRunningException(String message, Throwable cause) { public JobOrCaseRunningException(String message, Throwable cause) {
super(message, cause); super(message, cause);
} }
public ExecutionRunningException(Throwable cause) { public JobOrCaseRunningException(Throwable cause) {
super(cause); super(cause);
} }
public ExecutionRunningException() { public JobOrCaseRunningException() {
super(); super();
} }
} }
...@@ -100,7 +100,7 @@ public class ExecutionSocketHandler extends TextWebSocketHandler { ...@@ -100,7 +100,7 @@ public class ExecutionSocketHandler extends TextWebSocketHandler {
TestCase testCase = BeanUtil.mapToBean(objectMap, TestCase.class, false); TestCase testCase = BeanUtil.mapToBean(objectMap, TestCase.class, false);
List<TestData> testDataList = testDataService.list(Wrappers.lambdaQuery(TestData.class).eq(TestData::getTestCaseId, testCase.getId())); List<TestData> testDataList = testDataService.list(Wrappers.lambdaQuery(TestData.class).eq(TestData::getTestCaseId, testCase.getId()));
if (testDataList.size()==0){ if (testDataList.size()==0){
throw new GlobalException(String.format("执行错误,测试任务ID:%s 用例Id:%s 用例名:%s 中不存在需要测试的数据组",caseExecuteVo.getJobId(),testCase.getId(),testCase.getName())); throw new GlobalException(String.format("执行错误,测试任务ID:%s 用例Id:%s 用例名:%s \r\n 该用例中不存在需要测试的数据组",caseExecuteVo.getJobId(),testCase.getId(),testCase.getName()));
} }
TestCaseListDataBto testCaseListDataBto = new TestCaseListDataBto(); TestCaseListDataBto testCaseListDataBto = new TestCaseListDataBto();
testCaseListDataBto.setTestCase(testCase); testCaseListDataBto.setTestCase(testCase);
......
...@@ -14,6 +14,7 @@ import org.matrix.socket.enums.ExecuteStatusSendMessageType; ...@@ -14,6 +14,7 @@ import org.matrix.socket.enums.ExecuteStatusSendMessageType;
import org.matrix.socket.pool.MonitorSocketPool; import org.matrix.socket.pool.MonitorSocketPool;
import org.matrix.socket.vo.ExecutionStatusMonitorVo; import org.matrix.socket.vo.ExecutionStatusMonitorVo;
import org.matrix.socket.vo.ExecutionStatusSendMessageVo; import org.matrix.socket.vo.ExecutionStatusSendMessageVo;
import org.matrix.socket.vo.SocketResponseMessage;
import org.matrix.socket.vo.TestExecuteLog; import org.matrix.socket.vo.TestExecuteLog;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.CloseStatus;
...@@ -74,7 +75,7 @@ public class ExecutionStatusMonitorSocketHandler extends TextWebSocketHandler { ...@@ -74,7 +75,7 @@ public class ExecutionStatusMonitorSocketHandler extends TextWebSocketHandler {
} }
} }
} else { } else {
session.sendMessage(new TextMessage("入参不符合规定")); session.sendMessage(new TextMessage(SocketResponseMessage.fail("入参不符合规定")));
} }
} }
...@@ -94,7 +95,7 @@ public class ExecutionStatusMonitorSocketHandler extends TextWebSocketHandler { ...@@ -94,7 +95,7 @@ public class ExecutionStatusMonitorSocketHandler extends TextWebSocketHandler {
List<WebSocketSession> webSocketSessions = EXECUTE_MONITOR_SOCKET_POOL.get(uniqueKey); List<WebSocketSession> webSocketSessions = EXECUTE_MONITOR_SOCKET_POOL.get(uniqueKey);
if (webSocketSessions!=null){ if (webSocketSessions!=null){
for (WebSocketSession webSocketSession : webSocketSessions) { for (WebSocketSession webSocketSession : webSocketSessions) {
webSocketSession.sendMessage(new TextMessage(JSONObject.toJSONString(sendMessageVo))); webSocketSession.sendMessage(new TextMessage(SocketResponseMessage.success(JSONObject.toJSONString(sendMessageVo))));
} }
} }
} }
...@@ -132,7 +133,7 @@ public class ExecutionStatusMonitorSocketHandler extends TextWebSocketHandler { ...@@ -132,7 +133,7 @@ public class ExecutionStatusMonitorSocketHandler extends TextWebSocketHandler {
); );
if (webSocketSessions!=null){ if (webSocketSessions!=null){
for (WebSocketSession webSocketSession : webSocketSessions) { for (WebSocketSession webSocketSession : webSocketSessions) {
webSocketSession.sendMessage(new TextMessage(JSONObject.toJSONString(sendMessageVo))); webSocketSession.sendMessage(new TextMessage(SocketResponseMessage.success(JSONObject.toJSONString(sendMessageVo))));
} }
} }
......
...@@ -3,14 +3,14 @@ package org.matrix.socket.queue; ...@@ -3,14 +3,14 @@ package org.matrix.socket.queue;
import cn.hutool.log.LogFactory; import cn.hutool.log.LogFactory;
import cn.hutool.log.level.Level; import cn.hutool.log.level.Level;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import org.matrix.actuators.sql.SqlExpActuator;
import org.matrix.actuators.util.ThreadUtil; import org.matrix.actuators.util.ThreadUtil;
import org.matrix.database.entity.ExecutionRecord; import org.matrix.database.entity.ExecutionRecord;
import org.matrix.database.service.IExecutionRecordService; import org.matrix.database.service.IExecutionRecordService;
import org.matrix.enums.ModuleType; import org.matrix.enums.ModuleType;
import org.matrix.exception.ExecutionRunningException; import org.matrix.exception.JobOrCaseRunningException;
import org.matrix.exception.GlobalException; import org.matrix.exception.GlobalException;
import org.matrix.socket.ExecutionSocketHandler; import org.matrix.socket.ExecutionSocketHandler;
import org.matrix.socket.vo.SocketResponseMessage;
import org.matrix.socket.vo.TestExecuteLog; import org.matrix.socket.vo.TestExecuteLog;
import org.matrix.socket.enums.TestExecuteType; import org.matrix.socket.enums.TestExecuteType;
import org.matrix.socket.pool.TestCaseExecuteSocketPool; import org.matrix.socket.pool.TestCaseExecuteSocketPool;
...@@ -117,9 +117,7 @@ public class LogQueueRuntime { ...@@ -117,9 +117,7 @@ public class LogQueueRuntime {
private static void socketSendMessage(WebSocketSession socketSession, String message) { private static void socketSendMessage(WebSocketSession socketSession, String message) {
try { try {
if (socketSession != null && socketSession.isOpen()) { if (socketSession != null && socketSession.isOpen()) {
socketSession.sendMessage(new TextMessage( socketSession.sendMessage(new TextMessage(SocketResponseMessage.success(message)));
message
));
} }
} catch (IOException e) { } catch (IOException e) {
LogFactory.get().log(Level.INFO, "发送socket消息失败,socket已经断开连接"); LogFactory.get().log(Level.INFO, "发送socket消息失败,socket已经断开连接");
...@@ -134,7 +132,7 @@ public class LogQueueRuntime { ...@@ -134,7 +132,7 @@ public class LogQueueRuntime {
testExecuteLog.setType(type); testExecuteLog.setType(type);
testExecuteLog.setUniqueKey(uniqueKey); testExecuteLog.setUniqueKey(uniqueKey);
if (checkIsInRun(testExecuteLog)) { if (checkIsInRun(testExecuteLog)) {
throw new ExecutionRunningException("当前 任务/用例 正在执行中"); throw new JobOrCaseRunningException("当前 任务/用例 正在执行中");
} }
LogQueueRuntime.put(ThreadUtil.currentThreadId(), testExecuteLog); LogQueueRuntime.put(ThreadUtil.currentThreadId(), testExecuteLog);
} }
......
...@@ -17,12 +17,15 @@ public class SocketResponseMessage { ...@@ -17,12 +17,15 @@ public class SocketResponseMessage {
private String message; private String message;
public static String success(String message){ public static String success(String message){
return JSONObject.toJSONString(new SocketResponseMessage(HttpStatus.HTTP_OK,message)); return JSONObject.toJSONString(new SocketResponseMessage(HttpStatus.HTTP_OK,message));
} }
/**
* 慎用,假如返回500的话证明这个socket已经执行不下去了,假如时用例执行的时候,产生的错误日志请不要用这个fail抛出
* @param message
* @return
*/
public static String fail(String message){ public static String fail(String message){
return JSONObject.toJSONString(new SocketResponseMessage(HttpStatus.HTTP_INTERNAL_ERROR,message)); return JSONObject.toJSONString(new SocketResponseMessage(HttpStatus.HTTP_INTERNAL_ERROR,message));
} }
......
...@@ -124,7 +124,6 @@ public class TreeUtils { ...@@ -124,7 +124,6 @@ public class TreeUtils {
StringJoiner joiner = new StringJoiner("\t"); StringJoiner joiner = new StringJoiner("\t");
IntStream.range(0, stackDepth).mapToObj(i -> "").forEach(joiner::add); IntStream.range(0, stackDepth).mapToObj(i -> "").forEach(joiner::add);
joiner.add(printProperty.apply(rootNode).toString()); joiner.add(printProperty.apply(rootNode).toString());
System.out.println(joiner.toString());
for (T childNode : getChild.apply(rootNode)) { for (T childNode : getChild.apply(rootNode)) {
int currentLevel = stackDepth + 1; int currentLevel = stackDepth + 1;
printTreeNode(childNode, printProperty, getChild, currentLevel); printTreeNode(childNode, printProperty, getChild, currentLevel);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论