diff --git a/src/main/java/com/star/easydoc/action/GenerateAllJavadocAction.java b/src/main/java/com/star/easydoc/action/GenerateAllJavadocAction.java index 56943e6cb5a421c7c29c36d9fc5404046c4acc44..2776f62d74634d54f7ebed9cb13c69d02bbd6718 100644 --- a/src/main/java/com/star/easydoc/action/GenerateAllJavadocAction.java +++ b/src/main/java/com/star/easydoc/action/GenerateAllJavadocAction.java @@ -1,27 +1,29 @@ package com.star.easydoc.action; -import java.util.Arrays; -import java.util.Optional; - +import com.intellij.ide.util.PackageChooserDialog; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiElementFactory; -import com.intellij.psi.PsiField; -import com.intellij.psi.PsiMethod; +import com.intellij.psi.*; import com.intellij.psi.javadoc.PsiDocComment; import com.star.easydoc.config.EasyJavadocConfigComponent; import com.star.easydoc.model.EasyJavadocConfiguration; import com.star.easydoc.service.DocGeneratorService; +import com.star.easydoc.service.TranslatorService; import com.star.easydoc.service.WriterService; import com.star.easydoc.view.inner.GenerateAllView; +import com.star.easydoc.view.inner.PackageDescribeView; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + /** * 生成所有文档注释 * @@ -38,17 +40,50 @@ public class GenerateAllJavadocAction extends AnAction { private WriterService writerService = ServiceManager.getService(WriterService.class); private EasyJavadocConfiguration config = ServiceManager.getService(EasyJavadocConfigComponent.class).getState(); + private TranslatorService translatorService = ServiceManager.getService(TranslatorService.class); @Override public void actionPerformed(@NotNull AnActionEvent e) { + Project project = e.getData(LangDataKeys.PROJECT); // 前置规则校验 PsiElement psiElement = e.getData(LangDataKeys.PSI_ELEMENT); if (psiElement == null) { return; } + //对文件夹选择的额外处理下 + if (psiElement instanceof PsiDirectory) { + PackageChooserDialog selector = new PackageChooserDialog("选择多个Packages创建package-info", project); + PsiPackage psiPackage = JavaDirectoryService.getInstance().getPackage((PsiDirectory) psiElement); + if (psiPackage!=null) { + selector.selectPackage(psiPackage.getQualifiedName()); + } + selector.show(); + + List packages = selector.getSelectedPackages(); + if (packages==null||packages.size()==0){ + return; + } + //执行 + Map packMap = packages.stream().collect(Collectors.toMap(s -> s, s -> { + String result = translatorService.autoTranslate(s.getName()); + return result; + })); + //显示列表,一个个的修改后再提交写入更好 + + PackageDescribeView packageDescribeView = new PackageDescribeView(packMap); + if (packageDescribeView.showAndGet()) { + //重新获取一次 + Map finalMap = packageDescribeView.getFinalMap(); + //下面是执行,可以考虑并发 + for (Map.Entry entry : finalMap.entrySet()) { + PackageInfoHandle.handle(entry.getKey(),entry.getValue()); + } + } + return; + } + if (!(psiElement instanceof PsiClass)) { return; } - Project project = e.getData(LangDataKeys.PROJECT); // 弹出选择框 GenerateAllView generateAllView = new GenerateAllView(); generateAllView.getClassCheckBox().setSelected(Optional.ofNullable(config.getGenAllClass()).orElse(false)); diff --git a/src/main/java/com/star/easydoc/action/GenerateJavadocAction.java b/src/main/java/com/star/easydoc/action/GenerateJavadocAction.java index f191c7ed9725d26d5c645dcbb691da672399c560..e594d037f655730602117aa68bf001f21e157f3b 100644 --- a/src/main/java/com/star/easydoc/action/GenerateJavadocAction.java +++ b/src/main/java/com/star/easydoc/action/GenerateJavadocAction.java @@ -11,8 +11,7 @@ import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiElementFactory; +import com.intellij.psi.*; import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.util.messages.MessageBusConnection; import com.star.easydoc.listener.AppActivationListener; @@ -46,6 +45,7 @@ public class GenerateJavadocAction extends AnAction { connection.subscribe(ApplicationActivationListener.TOPIC, new AppActivationListener()); } + @Override public void actionPerformed(@NotNull AnActionEvent anActionEvent) { Project project = anActionEvent.getData(LangDataKeys.PROJECT); @@ -72,10 +72,26 @@ public class GenerateJavadocAction extends AnAction { } PsiElement psiElement = anActionEvent.getData(LangDataKeys.PSI_ELEMENT); - if (psiElement == null || psiElement.getNode() == null) { + //选中文件夹则判断包里面是否需要创建package-info.java,创建package-info 并携带注释 + if (psiElement instanceof PsiDirectory) { + PsiPackage psiPackage = JavaDirectoryService.getInstance().getPackage((PsiDirectory) psiElement); + String comment = translatorService.autoTranslate(psiPackage.getName()); + PackageInfoHandle.handle(psiPackage,comment); + return; + } + PsiFile psiFile = anActionEvent.getData(LangDataKeys.PSI_FILE); + //判断是否是package-info.java若是则进行package-info注释 + if (psiFile != null && PackageInfoHandle.INFO_FILE_NAME.equals(psiFile.getName())) { + PsiDirectory psiDirectory = psiFile.getParent(); + PsiPackage psiPackage = JavaDirectoryService.getInstance().getPackage(psiDirectory); + String comment = translatorService.autoTranslate(psiPackage.getName()); + PackageInfoHandle.handle(psiPackage,comment); return; } + if (psiElement == null || psiElement.getNode() == null) { + return; + } String comment = docGeneratorService.generate(psiElement); if (StringUtils.isEmpty(comment)) { return; diff --git a/src/main/java/com/star/easydoc/action/PackageInfoHandle.java b/src/main/java/com/star/easydoc/action/PackageInfoHandle.java new file mode 100644 index 0000000000000000000000000000000000000000..d6105d950d20983b09ac58aacbf19139368af056 --- /dev/null +++ b/src/main/java/com/star/easydoc/action/PackageInfoHandle.java @@ -0,0 +1,90 @@ +package com.star.easydoc.action; + +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiInvalidElementAccessException; +import com.intellij.psi.PsiPackage; +import com.intellij.util.IncorrectOperationException; +import com.star.easydoc.service.DocGeneratorService; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; + +/** + * 创建类, 可能有更便捷的方式创建实体类. 有待优化 + */ +public class PackageInfoHandle { + public static final String INFO_FILE_NAME = "package-info.java"; + public static final String PACKAGE_INFO_DESCRIBE = "PACKAGE_INFO_DESCRIBE"; + private static DocGeneratorService docGeneratorService = ServiceManager.getService(DocGeneratorService.class); + public static void handle(PsiPackage psiPackage,String comment) { + try { + Project project = psiPackage.getProject(); + PsiDirectory psiDirectory = psiPackage.getDirectories()[0]; + //是文件夹,文件夹处理 + VirtualFile virtualFile = psiDirectory.getVirtualFile().findChild(PackageInfoHandle.INFO_FILE_NAME); + if (virtualFile == null) { + //文件不存在则创建文件 + String result = docGeneratorService.generate(psiPackage).replace("${"+PACKAGE_INFO_DESCRIBE+"}",comment) + + "package " + psiPackage.getQualifiedName() + ";\n"; + WriteCommandAction.writeCommandAction(project).run(() -> { + try { + PsiFile file = psiDirectory.createFile(PackageInfoHandle.INFO_FILE_NAME); + VirtualFile fileVirtualFile = file.getVirtualFile(); + fileVirtualFile.setBinaryContent(result.getBytes(StandardCharsets.UTF_8)); + } catch (PsiInvalidElementAccessException | IOException | IncorrectOperationException ignored) { + ignored.printStackTrace(); + } + }); + //处理完就结束了 + return; + } else { +// virtualFile.getCharset() + try(InputStream inputStream = virtualFile.getInputStream()) { + int available = inputStream.available(); + byte[] bytes = new byte[available]; + inputStream.read(bytes); + String val = new String(bytes, virtualFile.getCharset()); + int index = val.indexOf("/**"); + StringBuffer buffer = new StringBuffer(); + if (index>=0){ + if (index>0){ + buffer.append(val, 0, index); + } + buffer.append("/**\n"); + buffer.append(" * ").append(comment); + buffer.append("\n"); + buffer.append(" * "); + buffer.append(val,index+3,val.length()); + }else { + //没有注释生成就行了 + buffer.append(docGeneratorService.generate(psiPackage).replace("${"+PACKAGE_INFO_DESCRIBE+"}",comment)); + buffer.append(val); + } + String finalVal = buffer.toString(); + WriteCommandAction.writeCommandAction(project).run(() -> { + try { + virtualFile.setBinaryContent(finalVal.getBytes(StandardCharsets.UTF_8)); + } catch (PsiInvalidElementAccessException | IOException | IncorrectOperationException ignored) { + ignored.printStackTrace(); + } + }); + } + //存在package-info,逻辑需要处理,先干脆不动算了,即然存在,应该会写注释的~~ +// System.out.println("6666"); + } + } catch (Exception e) { + //由于外面stream执行,错误处理直接吞掉,保证后续也可以执行 + e.printStackTrace(); + } + VirtualFileManager.getInstance().refreshWithoutFileWatcher(true); + + } + +} diff --git a/src/main/java/com/star/easydoc/listener/AppActivationListener.java b/src/main/java/com/star/easydoc/listener/AppActivationListener.java index 03b705288f9eb8afd91823963e755a5948779c60..4392824ff4c6931e76b9b7fb778d1b6225af5318 100644 --- a/src/main/java/com/star/easydoc/listener/AppActivationListener.java +++ b/src/main/java/com/star/easydoc/listener/AppActivationListener.java @@ -35,38 +35,38 @@ public class AppActivationListener implements ApplicationActivationListener { @Override public synchronized void applicationActivated(@NotNull IdeFrame ideFrame) { if (System.currentTimeMillis() - lastNoticeTime.get() < INTERVAL) { - return; + return; } NotificationGroup group = new NotificationGroup("Easy Javadoc", NotificationDisplayType.BALLOON, true, null, - General.AddJdk); + General.AddJdk); Notification notification = group.createNotification( - "支持EasyJavadoc", "如果这款小而精的插件为您节约了不少时间,请支持一下开发者!", - NotificationType.INFORMATION, NotificationListener.URL_OPENING_LISTENER); - + "支持EasyJavadoc", "如果这款小而精的插件为您节约了不少时间,请支持一下开发者!", + NotificationType.INFORMATION, NotificationListener.URL_OPENING_LISTENER); + // 去点star notification.addAction(new NotificationAction("✨ 去点star") { - @Override - public void actionPerformed(@NotNull AnActionEvent e, @NotNull Notification notification) { - try { - Desktop dp = Desktop.getDesktop(); - if (dp.isSupported(Desktop.Action.BROWSE)) { - dp.browse(URI.create("https://github.com/starcwang/easy_javadoc")); - } - } catch (Exception ex) { - LOGGER.error("打开链接失败:https://github.com/starcwang/easy_javadoc", ex); - } - } + @Override + public void actionPerformed(@NotNull AnActionEvent e, @NotNull Notification notification) { + try { + Desktop dp = Desktop.getDesktop(); + if (dp.isSupported(Desktop.Action.BROWSE)) { + dp.browse(URI.create("https://github.com/starcwang/easy_javadoc")); + } + } catch (Exception ex) { + LOGGER.error("打开链接失败:https://github.com/starcwang/easy_javadoc", ex); + } + } }); - + // 支付 notification.addAction(new NotificationAction("☕ 请喝咖啡") { - @Override - public void actionPerformed(@NotNull AnActionEvent e, @NotNull Notification notification) { - SupportView supportView = new SupportView(); - supportView.show(); - } + @Override + public void actionPerformed(@NotNull AnActionEvent e, @NotNull Notification notification) { + SupportView supportView = new SupportView(); + supportView.show(); + } }); - + notification.notify(null); lastNoticeTime.set(System.currentTimeMillis()); } diff --git a/src/main/java/com/star/easydoc/service/DocGeneratorService.java b/src/main/java/com/star/easydoc/service/DocGeneratorService.java index 83d436c861984ce2cd550b24cdb0ff11b1a40c62..909908e5286b1855db91afab3373056e97b9c75e 100644 --- a/src/main/java/com/star/easydoc/service/DocGeneratorService.java +++ b/src/main/java/com/star/easydoc/service/DocGeneratorService.java @@ -1,20 +1,18 @@ package com.star.easydoc.service; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; - import com.google.common.collect.ImmutableMap; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiField; -import com.intellij.psi.PsiMethod; +import com.intellij.psi.*; import com.star.easydoc.service.generator.DocGenerator; import com.star.easydoc.service.generator.impl.ClassDocGenerator; import com.star.easydoc.service.generator.impl.FieldDocGenerator; import com.star.easydoc.service.generator.impl.MethodDocGenerator; +import com.star.easydoc.service.generator.impl.PackageInfoDocGenerator; import org.apache.commons.lang3.StringUtils; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; + /** * @author wangchao * @date 2019/08/25 @@ -26,6 +24,7 @@ public class DocGeneratorService { .put(PsiClass.class, new ClassDocGenerator()) .put(PsiMethod.class, new MethodDocGenerator()) .put(PsiField.class, new FieldDocGenerator()) + .put(PsiPackage.class, new PackageInfoDocGenerator()) .build(); public String generate(PsiElement psiElement) { diff --git a/src/main/java/com/star/easydoc/service/generator/impl/PackageInfoDocGenerator.java b/src/main/java/com/star/easydoc/service/generator/impl/PackageInfoDocGenerator.java new file mode 100644 index 0000000000000000000000000000000000000000..54e9c81ce8ba3211dd691b7f0e869c0a41338f1f --- /dev/null +++ b/src/main/java/com/star/easydoc/service/generator/impl/PackageInfoDocGenerator.java @@ -0,0 +1,30 @@ +package com.star.easydoc.service.generator.impl; + +import com.intellij.openapi.components.ServiceManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiPackage; +import com.star.easydoc.action.PackageInfoHandle; +import com.star.easydoc.service.TranslatorService; +import com.star.easydoc.service.generator.DocGenerator; +import org.apache.commons.lang3.StringUtils; + + +public class PackageInfoDocGenerator implements DocGenerator { + + private TranslatorService translatorService = ServiceManager.getService(TranslatorService.class); + @Override + public String generate(PsiElement psiElement) { + if (!(psiElement instanceof PsiPackage)) { + return StringUtils.EMPTY; + } + PsiPackage psiPackage = (PsiPackage)psiElement; + + return defaultGenerate(psiPackage); + } + + private String defaultGenerate(PsiPackage psiPackage) { + return "/**\n" + + " * ${"+ PackageInfoHandle.PACKAGE_INFO_DESCRIBE+"} \n" + + "**/\n"; + } +} diff --git a/src/main/java/com/star/easydoc/service/translator/impl/TencentTranslator.java b/src/main/java/com/star/easydoc/service/translator/impl/TencentTranslator.java index 3e1007a55ceca09c707d5543d796bf357608d3c6..ab39186d3da43e755f256fd0a682bd5741a8b202 100644 --- a/src/main/java/com/star/easydoc/service/translator/impl/TencentTranslator.java +++ b/src/main/java/com/star/easydoc/service/translator/impl/TencentTranslator.java @@ -1,15 +1,5 @@ package com.star.easydoc.service.translator.impl; -import java.nio.charset.StandardCharsets; -import java.util.Map.Entry; -import java.util.Random; -import java.util.SortedMap; -import java.util.TreeMap; - -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; -import javax.xml.bind.DatatypeConverter; - import com.fasterxml.jackson.annotation.JsonProperty; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; @@ -18,6 +8,15 @@ import com.star.easydoc.model.EasyJavadocConfiguration; import com.star.easydoc.util.HttpUtil; import com.star.easydoc.util.JsonUtil; +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.StandardCharsets; +import java.security.SecureRandom; +import java.util.Base64; +import java.util.Map.Entry; +import java.util.SortedMap; +import java.util.TreeMap; + /** * 腾讯翻译 * @@ -54,7 +53,7 @@ public class TencentTranslator extends AbstractTranslator { TencentResponse response = null; for (int i = 0; i < 10; i++) { SortedMap params = new TreeMap<>(); - params.put("Nonce", new Random().nextInt(java.lang.Integer.MAX_VALUE)); + params.put("Nonce", new SecureRandom().nextInt(java.lang.Integer.MAX_VALUE)); params.put("Timestamp", System.currentTimeMillis() / 1000); params.put("Region", "ap-beijing"); params.put("SecretId", config.getSecretId()); @@ -85,7 +84,7 @@ public class TencentTranslator extends AbstractTranslator { SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), mac.getAlgorithm()); mac.init(secretKeySpec); byte[] hash = mac.doFinal(s.getBytes(StandardCharsets.UTF_8)); - return DatatypeConverter.printBase64Binary(hash); + return Base64.getEncoder().encodeToString(hash); } public static String getStringToSign(String method, String endpoint, SortedMap params) { diff --git a/src/main/java/com/star/easydoc/view/inner/PackageDescribeView.form b/src/main/java/com/star/easydoc/view/inner/PackageDescribeView.form new file mode 100644 index 0000000000000000000000000000000000000000..2e6f32a65025ee05aa00cf9c826bb950d27cc4af --- /dev/null +++ b/src/main/java/com/star/easydoc/view/inner/PackageDescribeView.form @@ -0,0 +1,26 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/main/java/com/star/easydoc/view/inner/PackageDescribeView.java b/src/main/java/com/star/easydoc/view/inner/PackageDescribeView.java new file mode 100644 index 0000000000000000000000000000000000000000..cac413e3d41d1eb53089cd42b3050b8e1615da31 --- /dev/null +++ b/src/main/java/com/star/easydoc/view/inner/PackageDescribeView.java @@ -0,0 +1,71 @@ +package com.star.easydoc.view.inner; + +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.PsiPackage; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableCellEditor; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class PackageDescribeView extends DialogWrapper { + private JPanel panel1; + private JTable packageInfoTable; + public PackageDescribeView(Map packMap) { + super(false); + + this.packMap = packMap; + createMap(packMap); + + init(); + setTitle("包信息生成"); + } + private Map packMap; + private Map packIndexMap; + public Map getFinalMap(){ +// packageInfoTable.get + TableCellEditor editor = packageInfoTable.getCellEditor(); + if (editor!=null){ + editor.stopCellEditing(); + } + Map finalPackMap = new HashMap<>(); + for (Integer index : packIndexMap.keySet()) { + PsiPackage psiPackage = packIndexMap.get(index); + String value = (String)packageInfoTable.getValueAt(index, 1); + finalPackMap.put(psiPackage,value); + } + return finalPackMap; + } + public void createMap(Map packMap){ + List> list = new ArrayList<>(packMap.entrySet()); + String[][] objs = new String[list.size()][2]; + packIndexMap = new HashMap<>(); + for (int i = 0; i < list.size(); i++) { + PsiPackage aPackage = list.get(i).getKey(); + objs[i][0]= aPackage.getQualifiedName(); + objs[i][1]=list.get(i).getValue(); + packIndexMap.put(i,aPackage); + } + DefaultTableModel innerModel = new DefaultTableModel(objs, new String[]{"包名称","注释"}){ + @Override + public boolean isCellEditable(int row, int column) { + if (column==1){ + return true; + }else { + return false; + } + } + }; + packageInfoTable.setModel(innerModel); +// packageInfoTable.colum(0) + } + + @Override + protected @Nullable JComponent createCenterPanel() { + return panel1; + } +}