Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,11 @@ build/

### VS Code ###
.vscode/
.codex/

### Mac OS ###
.DS_Store

### Maven ###
.flattened-pom.xml
dependency-reduced-pom.xml
dependency-reduced-pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,25 @@
import com.intellij.openapi.ui.ComboBox;
import io.github.future0923.debug.tools.base.utils.DebugToolsThreadUtils;
import io.github.future0923.debug.tools.common.protocal.http.AllClassLoaderRes;
import io.github.future0923.debug.tools.idea.action.ExecuteLastWithDefaultClassLoaderEditorPopupMenuAction;
import io.github.future0923.debug.tools.idea.client.http.HttpClientUtils;
import io.github.future0923.debug.tools.idea.utils.StateUtils;

import javax.swing.*;
import java.awt.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
* @author future0923
*/
public class ClassLoaderComboBox extends ComboBox<AllClassLoaderRes.Item> {

private static final Logger logger = Logger.getInstance(ExecuteLastWithDefaultClassLoaderEditorPopupMenuAction.class);
private static final Logger logger = Logger.getInstance(ClassLoaderComboBox.class);

private final Project project;

private final AtomicInteger refreshVersion = new AtomicInteger();

public ClassLoaderComboBox(Project project) {
this(project, -1, true);
}
Expand Down Expand Up @@ -75,11 +77,48 @@ public Component getListCellRendererComponent(JList<?> list, Object value, int i
* @param changeDefaultClassLoader 是否修改默认ClassLoader
*/
public void refreshClassLoaderLater(boolean changeDefaultClassLoader) {
ApplicationManager.getApplication().invokeLater(() -> refreshClassLoader(changeDefaultClassLoader));
refreshClassLoader(changeDefaultClassLoader, null);
}

public void refreshClassLoader(boolean changeDefaultClassLoader) {
removeAllItems();
refreshClassLoader(changeDefaultClassLoader, null);
}

public void refreshClassLoader(boolean changeDefaultClassLoader, Runnable successUiCallback) {
int currentRefresh = refreshVersion.incrementAndGet();
ApplicationManager.getApplication().invokeLater(() -> {
removeAllItems();
setEnabled(false);
}, project.getDisposed());
ApplicationManager.getApplication().executeOnPooledThread(() -> {
AllClassLoaderRes allClassLoaderRes = loadAllClassLoader();
ApplicationManager.getApplication().invokeLater(() -> {
if (refreshVersion.get() != currentRefresh) {
return;
}
removeAllItems();
if (allClassLoaderRes != null) {
AllClassLoaderRes.Item defaultClassLoader = null;
for (AllClassLoaderRes.Item item : allClassLoaderRes.getItemList()) {
if (item.getIdentity().equals(allClassLoaderRes.getDefaultIdentity())) {
defaultClassLoader = item;
}
addItem(item);
}
if (changeDefaultClassLoader && defaultClassLoader != null) {
setSelectedItem(defaultClassLoader);
StateUtils.setProjectDefaultClassLoader(project, defaultClassLoader);
}
if (successUiCallback != null) {
successUiCallback.run();
}
}
setEnabled(true);
}, project.getDisposed());
});
}

private AllClassLoaderRes loadAllClassLoader() {
AllClassLoaderRes allClassLoaderRes = null;
int retryCount = 0;
while (!Thread.currentThread().isInterrupted() && retryCount < 20) {
Expand All @@ -90,23 +129,13 @@ public void refreshClassLoader(boolean changeDefaultClassLoader) {
retryCount++;
}
if (!DebugToolsThreadUtils.sleep(1, TimeUnit.SECONDS)) {
return;
return null;
}
}
if (allClassLoaderRes == null) {
return;
}
AllClassLoaderRes.Item defaultClassLoader = null;
for (AllClassLoaderRes.Item item : allClassLoaderRes.getItemList()) {
if (item.getIdentity().equals(allClassLoaderRes.getDefaultIdentity())) {
defaultClassLoader = item;
}
addItem(item);
}
if (changeDefaultClassLoader && defaultClassLoader != null) {
setSelectedItem(defaultClassLoader);
StateUtils.setProjectDefaultClassLoader(project, defaultClassLoader);
logger.warn("Failed to load classloader list after retries");
}
return allClassLoaderRes;
}

public void setSelectedClassLoader(AllClassLoaderRes.Item identity) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,17 @@
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import io.github.future0923.debug.tools.base.hutool.core.io.FileUtil;
import io.github.future0923.debug.tools.base.hutool.core.util.StrUtil;
import io.github.future0923.debug.tools.base.utils.DebugToolsDigestUtil;
import io.github.future0923.debug.tools.common.dto.RunContentDTO;
import io.github.future0923.debug.tools.common.dto.RunDTO;
import io.github.future0923.debug.tools.common.dto.TraceMethodDTO;
import io.github.future0923.debug.tools.common.exception.SocketCloseException;
import io.github.future0923.debug.tools.common.protocal.http.AllClassLoaderRes;
import io.github.future0923.debug.tools.common.protocal.packet.request.RunTargetMethodRequestPacket;
import io.github.future0923.debug.tools.common.utils.DebugToolsJsonUtils;
import io.github.future0923.debug.tools.idea.bundle.DebugToolsBundle;
import io.github.future0923.debug.tools.idea.client.ApplicationProjectHolder;
import io.github.future0923.debug.tools.idea.client.socket.utils.SocketSendUtils;
import io.github.future0923.debug.tools.idea.constant.IdeaPluginProjectConstants;
import io.github.future0923.debug.tools.idea.model.InvokeMethodRecordDTO;
import io.github.future0923.debug.tools.idea.model.ParamCache;
Expand Down Expand Up @@ -91,6 +89,10 @@ protected void doOKAction() {
Map<String, String> itemHeaderMap = mainPanel.getItemHeaderMap();
AllClassLoaderRes.Item classLoaderRes = (AllClassLoaderRes.Item) mainPanel.getClassLoaderComboBox().getSelectedItem();
MainJsonEditor editor = mainPanel.getEditor();
if (editor.isGenerating()) {
DebugToolsNotifierUtil.notifyError(project, "参数正在生成,请稍后再试");
return;
}
String text = DebugToolsJsonUtils.compress(editor.getText());
String xxlJobParam = mainPanel.getXxlJobParamField().getText();
TraceMethodPanel traceMethodPanel = mainPanel.getTraceMethodPanel();
Expand Down Expand Up @@ -137,48 +139,35 @@ protected void doOKAction() {
}
}
RunTargetMethodRequestPacket packet = new RunTargetMethodRequestPacket(runDTO);
ApplicationProjectHolder.Info info = ApplicationProjectHolder.getInfo(project);
if (info == null) {
Messages.showErrorDialog(DebugToolsBundle.message("dialog.error.run.attach.first"), DebugToolsBundle.message("dialog.title.execution.failed"));
DebugToolsToolWindowFactory.showWindow(project, null);
return;
}
try {
info.getClient().getHolder().send(packet);
} catch (SocketCloseException e) {
Messages.showErrorDialog(DebugToolsBundle.message("dialog.error.socket.close"), DebugToolsBundle.message("dialog.title.execution.failed"));
return;
} catch (Exception e) {
Messages.showErrorDialog(DebugToolsBundle.message("dialog.error.socket.send") + e.getMessage(), DebugToolsBundle.message("dialog.title.execution.failed"));
return;
}
String runJsonStr = DebugToolsJsonUtils.toJsonStr(runDTO);
try {
String pathname = project.getBasePath() + IdeaPluginProjectConstants.PARAM_FILE;
File file = new File(pathname);
if (!file.exists()) {
FileUtils.touch(file);
SocketSendUtils.sendAsync(project, packet, () -> {
try {
String pathname = project.getBasePath() + IdeaPluginProjectConstants.PARAM_FILE;
File file = new File(pathname);
if (!file.exists()) {
FileUtils.touch(file);
}
FileUtil.writeUtf8String(runJsonStr, file);
} catch (IOException ex) {
log.error("参数写入json文件失败", ex);
DebugToolsNotifierUtil.notifyError(project, "参数写入json文件失败");
return;
}
FileUtil.writeUtf8String(runJsonStr, file);
} catch (IOException ex) {
log.error("参数写入json文件失败", ex);
DebugToolsNotifierUtil.notifyError(project, "参数写入json文件失败");
return;
}
if (settingState.getInvokeMethodRecord()) {
InvokeMethodRecordDTO invokeMethodRecordDTO = new InvokeMethodRecordDTO();
invokeMethodRecordDTO.setIdentity(recordRunDTO.getIdentity());
invokeMethodRecordDTO.formatRunTime();
invokeMethodRecordDTO.setClassName(runDTO.getTargetClassName());
invokeMethodRecordDTO.setClassSimpleName(recordRunDTO.getClassSimpleName());
invokeMethodRecordDTO.setMethodName(runDTO.getTargetMethodName());
invokeMethodRecordDTO.setMethodSignature(recordRunDTO.getMethodSignature());
invokeMethodRecordDTO.setMethodAroundName(methodAroundName);
invokeMethodRecordDTO.setMethodParamJson(text);
invokeMethodRecordDTO.setCacheKey(recordRunDTO.getCacheKey());
invokeMethodRecordDTO.formatRunDTO(runDTO);
DebugToolsToolWindowFactory.consumerInvokeMethodRecordPanel(project, panel -> panel.addItem(invokeMethodRecordDTO));
}
if (settingState.getInvokeMethodRecord()) {
InvokeMethodRecordDTO invokeMethodRecordDTO = new InvokeMethodRecordDTO();
invokeMethodRecordDTO.setIdentity(recordRunDTO.getIdentity());
invokeMethodRecordDTO.formatRunTime();
invokeMethodRecordDTO.setClassName(runDTO.getTargetClassName());
invokeMethodRecordDTO.setClassSimpleName(recordRunDTO.getClassSimpleName());
invokeMethodRecordDTO.setMethodName(runDTO.getTargetMethodName());
invokeMethodRecordDTO.setMethodSignature(recordRunDTO.getMethodSignature());
invokeMethodRecordDTO.setMethodAroundName(methodAroundName);
invokeMethodRecordDTO.setMethodParamJson(text);
invokeMethodRecordDTO.setCacheKey(recordRunDTO.getCacheKey());
invokeMethodRecordDTO.formatRunDTO(runDTO);
DebugToolsToolWindowFactory.consumerInvokeMethodRecordPanel(project, panel -> panel.addItem(invokeMethodRecordDTO));
}
});
super.doOKAction();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,7 @@ private void initLayout(RunDTO formatRunDTO) {
JPanel classLoaderJPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
getAllClassLoader();
refreshButton.addActionListener(e -> {
classLoaderComboBox.removeAllItems();
getAllClassLoader();
classLoaderComboBox.setSelectedClassLoader(StateUtils.getProjectDefaultClassLoader(project));
});
classLoaderJPanel.add(classLoaderComboBox);
classLoaderJPanel.add(refreshButton);
Expand Down Expand Up @@ -195,8 +193,7 @@ private void initLayout(RunDTO formatRunDTO) {
}

private void getAllClassLoader() {
classLoaderComboBox.refreshClassLoader(false);
classLoaderComboBox.setSelectedClassLoader(StateUtils.getProjectDefaultClassLoader(project));
classLoaderComboBox.refreshClassLoader(false, () -> classLoaderComboBox.setSelectedClassLoader(StateUtils.getProjectDefaultClassLoader(project)));
}

public Map<String, String> getItemHeaderMap() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ protected void doOKAction() {
Map<String, String> itemHeaderMap = mainPanel.getItemHeaderMap();
AllClassLoaderRes.Item classLoaderRes = (AllClassLoaderRes.Item) mainPanel.getClassLoaderComboBox().getSelectedItem();
MainJsonEditor editor = mainPanel.getEditor();
if (editor.isGenerating()) {
DebugToolsNotifierUtil.notifyError(project, "参数正在生成,请稍后再试");
return;
}
String text = DebugToolsJsonUtils.compress(editor.getText());
String xxlJobParam = mainPanel.getXxlJobParamField().getText();
TraceMethodPanel traceMethodPanel = mainPanel.getTraceMethodPanel();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,38 +16,51 @@
*/
package io.github.future0923.debug.tools.idea.ui.main;

import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiParameterList;
import com.intellij.util.concurrency.AppExecutorUtil;
import io.github.future0923.debug.tools.common.utils.DebugToolsJsonUtils;
import io.github.future0923.debug.tools.idea.setting.DebugToolsSettingState;
import io.github.future0923.debug.tools.idea.setting.GenParamType;
import io.github.future0923.debug.tools.idea.ui.editor.JsonEditor;
import io.github.future0923.debug.tools.idea.utils.DebugToolsNotifierUtil;
import io.github.future0923.debug.tools.idea.utils.DebugToolsJsonElementUtil;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.incremental.GlobalContextKey;

import java.util.concurrent.atomic.AtomicInteger;

/**
* @author future0923
*/
@Getter
public class MainJsonEditor extends JsonEditor {

private static final String STATUS_FIELD_NAME = "_status";

private final PsiParameterList psiParameterList;

public static final String FILE_NAME = "DebugToolsContentEditFile.json";

public static final GlobalContextKey<PsiParameterList> DEBUG_POWER_EDIT_CONTENT = GlobalContextKey.create("DebugToolsEditContent");

private final AtomicInteger generationVersion = new AtomicInteger();

@Getter
private volatile boolean generating;

public MainJsonEditor(String cacheText, PsiParameterList psiParameterList, Project project) {
super(project, "");
this.psiParameterList = psiParameterList;
if (StringUtils.isBlank(cacheText)) {
DebugToolsSettingState settingState = DebugToolsSettingState.getInstance(project);
setText(getJsonText(psiParameterList, settingState.getDefaultGenParamType()));
regenerateJsonText(settingState.getDefaultGenParamType(), true);
} else {
setText(cacheText);
}
Expand All @@ -58,17 +71,67 @@ public String getJsonText(@Nullable PsiParameterList psiParameterList, GenParamT
}

public void regenerateJsonText(GenParamType type) {
if (GenParamType.SIMPLE.equals(type)) {
setText(DebugToolsJsonElementUtil.getSimpleText(psiParameterList));
} else {
setText(getJsonText(psiParameterList, type));
}
regenerateJsonText(type, false);
}

public void prettyJsonText() {
setText(DebugToolsJsonUtils.pretty(getText()));
}

private void regenerateJsonText(GenParamType type, boolean preserveManualText) {
int currentGenerationVersion = generationVersion.incrementAndGet();
String previousText = getText();
String loadingText = statusText("Generating parameters...");
generating = true;
setText(loadingText);
ReadAction.nonBlocking(() -> buildJsonResult(type))
.withDocumentsCommitted(getProject())
.finishOnUiThread(ModalityState.any(), result -> {
if (generationVersion.get() != currentGenerationVersion) {
return;
}
generating = false;
if (preserveManualText && !StringUtils.equals(getText(), loadingText)) {
return;
}
if (result.success()) {
setText(result.text());
} else {
if (preserveManualText) {
setText("{}");
} else {
setText(previousText);
}
DebugToolsNotifierUtil.notifyError(getProject(), result.errorMessage());
}
})
.submit(AppExecutorUtil.getAppExecutorService());
}

private GenerateResult buildJsonResult(GenParamType type) {
if (psiParameterList == null) {
return new GenerateResult(null, "当前记录缺少方法参数信息,无法重新生成参数", false);
}
try {
String text;
if (GenParamType.SIMPLE.equals(type)) {
text = DebugToolsJsonElementUtil.getSimpleText(psiParameterList);
} else {
text = getJsonText(psiParameterList, type);
}
return new GenerateResult(text, null, true);
} catch (Exception ex) {
return new GenerateResult(null, "参数生成失败: " + ex.getMessage(), false);
}
}

private String statusText(String status) {
return DebugToolsJsonUtils.createJsonObject().set(STATUS_FIELD_NAME, status).toJSONString(4);
}

private record GenerateResult(String text, String errorMessage, boolean success) {
}

@Override
protected String fileName() {
return FILE_NAME;
Expand Down
Loading