Idea插件开发之G2M2G

1,947 阅读4分钟

Idea插件开发之G2M2G

众做周知,idea是一个很强大的工具。最强的地方就是它的成长性,可塑性。你可以根据自己的喜好来调教它。
从快捷键设置,到代码模板,再到插件开发。一步步它可以成长为最牛B的开发工具。

之前遇到过一个问题,这个问题对有些人可能不是问题。
闲话少叙,由于公司版本管理工具使用的是Gradle, 不过旧的项目还有使用Maven。有时候想拷贝一个依赖,在Maven里是这样的

<dependency> 
    <groupId>io.swagger</groupId> 
    <artifactId>swagger-models</artifactId> 
    <exclusions> 
        <exclusion> 
            <groupId>swagger-annotations</groupId> 
            <artifactId>swagger-models</artifactId> 
        </exclusion> 
    </exclusions> 
    <version>1.5.22</version> 
 </dependency> 

但是Gradle是这样的

compile(group: "io.swagger", name: "swagger-models", version: "1.5.22"){ 
        exclude group: 'swagger-annotations', module: 'swagger-models' 
}

有时候从Maven复制到Gradle时,要手动改成这个样子,好麻烦...
还有时候从Gradle复制到Maven,还要手动改,更麻烦...

一开始想用 Live Templates模板配置,但是试了很多方法,还是不行。
于是想自己写一个插件。g2m2g,意思就是Gradle to Maven and Maven to Gradle

idea插件开发

Plugin DevKit

  1. 首先安装并启用Plugin DevKit插件。
  2. 使用Gradle开发插件。使用Gradle可以很好地管理依赖。

项目结构

plugin.xml

这个是插件的配置信息。

创建一个Action

选择EditorPopupMenu,在编辑器里右键弹出。

创建之后,在plugin.xml里会自动生成配置信息。

然后就可以在Action里写业务代码了。

Gradle to Maven

package com.ler.action;

import com.alibaba.fastjson.JSONObject;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.ide.CopyPasteManager;
import com.ler.action.entity.MavenJsonBean;
import com.ler.action.util.GradleParser;
import com.ler.action.util.SelectUtil;
import java.awt.datatransfer.StringSelection;

/**
 * @author lww
 */
public class Gradle2MavenAction extends AnAction {

    @Override
    public void actionPerformed(AnActionEvent e) {
        //获取当前在操作的工程上下文
        //Project project = e.getData(PlatformDataKeys.PROJECT);
        String data = SelectUtil.getSelectString(e);
        if (data == null) {
            return;
        }
        MavenJsonBean bean = GradleParser.parseGradle(data);
        String xml = GradleParser.jsonToXml(JSONObject.toJSONString(bean));
        CopyPasteManager.getInstance().setContents(new StringSelection(xml));
        //Messages.showMessageDialog(project, "转换成功,已复制,去粘贴吧!", "Success", Messages.getInformationIcon());
    }

}

  • 首先获取选择的内容
package com.ler.action.util;

import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.editor.Editor;

/**
 * @author lww
 * @date 2020-05-27 19:59
 */
public class SelectUtil {

    public static String getSelectString(AnActionEvent e) {
        //获取选择的文本
        Editor editor = e.getData(CommonDataKeys.EDITOR);
        if (editor == null) {
            return null;
        }
        String data = editor.getSelectionModel().getSelectedText();
        if (data == null || data.isEmpty()) {
            return null;
        }
        return data;
    }
}
  • 我是创建了一个类用来存储依赖。先解析出Gradle里的依赖,存到对象里,然后转为Json,再转为xml。

  • Maven对象

package com.ler.action.entity;

import java.util.List;
import lombok.Data;

/**
 * @author lww
 * @date 2020-05-27 16:09
 */
@Data
public class MavenJsonBean {

    private DependencyBean dependency;

    @Data
    public static class DependencyBean {

        private String groupId;
        private String artifactId;
        private ExclusionsBean exclusions;
        private String version;

        @Data
        public static class ExclusionsBean {

            private List<ExclusionBean> exclusion;

            @Data
            public static class ExclusionBean {

                private String groupId;
                private String artifactId;
            }
        }
    }
}

解析Gradle依赖用的是正则表达式,用到了正向先行断言和正向后行断言。

    private final static Pattern GROUP_PB = Pattern.compile("(?<=group:)(.)+(?=, name)");
    private final static Pattern NAME_PB = Pattern.compile("(?<=name:)(.)+(?=, version)");
    private final static Pattern VERSION_PB = Pattern.compile("(?<=version:)(.)+");
    private final static Pattern EX_GROUP_PB = Pattern.compile("(?<=group:)(.)+(?=, module)");
    private final static Pattern MODEL_PB = Pattern.compile("(?<=module:)(.)+");

JSON2XML

  /**
     * Json to xml string.
     *
     * @param json the json
     * @return the string
     */
    public static String jsonToXml(String json) {
        try {
            StringBuffer buffer = new StringBuffer();
            JSONObject jObj = JSON.parseObject(json);
            String xmlstr = json2Xmlstr(jObj, buffer);
            return buffer.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * Json to xmlstr string.
     *
     * @param jObj   the j obj
     * @param buffer the buffer
     * @return the string
     */
    private static String json2Xmlstr(JSONObject jObj, StringBuffer buffer) {
        Set<Map.Entry<String, Object>> se = jObj.entrySet();
        for (Entry<String, Object> en : se) {
            if ("com.alibaba.fastjson.JSONObject".equals(en.getValue().getClass().getName())) {
                buffer.append("<").append(en.getKey()).append(">");
                JSONObject jo = jObj.getJSONObject(en.getKey());
                json2Xmlstr(jo, buffer);
                buffer.append("</").append(en.getKey()).append(">");
            } else if ("com.alibaba.fastjson.JSONArray".equals(en.getValue().getClass().getName())) {
                JSONArray jarray = jObj.getJSONArray(en.getKey());
                for (int i = 0; i < jarray.size(); i++) {
                    buffer.append("<").append(en.getKey()).append(">");
                    JSONObject jsonobject = jarray.getJSONObject(i);
                    json2Xmlstr(jsonobject, buffer);
                    buffer.append("</").append(en.getKey()).append(">");
                }
            } else if ("java.lang.String".equals(en.getValue().getClass().getName())) {
                buffer.append("<").append(en.getKey()).append(">").append(en.getValue());
                buffer.append("</").append(en.getKey()).append(">");
            }
        }
        return buffer.toString();
    }

Maven to Gradle

package com.ler.action;

import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.ler.action.util.SelectUtil;
import com.ler.action.util.XmlParser;
import java.awt.datatransfer.StringSelection;

/**
 * @author lww
 */
public class Maven2GradleAction extends AnAction {

    @Override
    public void actionPerformed(AnActionEvent e) {
        //获取当前在操作的工程上下文
        Project project = e.getData(PlatformDataKeys.PROJECT);
        String data = SelectUtil.getSelectString(e);
        if (data == null) {
            return;
        }
        try {
            String compile = XmlParser.parseXml(data);
            CopyPasteManager.getInstance().setContents(new StringSelection(compile));
            //Messages.showMessageDialog(project, "转换成功,已复制,去粘贴吧!", "Success", Messages.getInformationIcon());
        } catch (Exception ex) {
            ex.printStackTrace();
            Messages.showMessageDialog(project, "转换失败!", "Error", Messages.getInformationIcon());
        }
    }
}

XML2Json

 public static String parseXml(String xmlStr) throws Exception {
        //xml 2 json
        JSONObject jsonObject = XML.toJSONObject(xmlStr);
        MavenJsonBean mavenJsonBean = com.alibaba.fastjson.JSONObject.parseObject(jsonObject.toString(), MavenJsonBean.class);
        StringBuilder sb = new StringBuilder();
        DependencyBean dependency = mavenJsonBean.getDependency();
        sb.append("compile(group: \"")
                .append(dependency.getGroupId())
                .append("\", name: \"")
                .append(dependency.getArtifactId());
        if (dependency.getVersion() == null || dependency.getVersion().isEmpty()) {
            sb.append("\")");
        } else {
            sb.append("\", version: \"")
                    .append(dependency.getVersion())
                    .append("\")");
        }

        if (dependency.getExclusions() != null && dependency.getExclusions().getExclusion() != null && dependency.getExclusions().getExclusion().size() > 0) {
            List<ExclusionBean> exclusion = dependency.getExclusions().getExclusion();
            sb.append("{");
            for (ExclusionBean ex : exclusion) {
                sb.append("\n exclude group: '").append(ex.getGroupId()).append("', module: '").append(ex.getArtifactId()).append("'");
            }
            sb.append("\n }");
        }
        return sb.toString();
    }

打包及运行插件

打包成功,插件在

安装打包的插件

效果

  • Maven2Gradle
  • 转换后的效果
  • Gradle2Maven
  • 转换后的效果,没有格式化
  • 格式化一下
  • 有一个问题,如果没有exclusion,会有一个空的exclusions

代码粘的不全,源码地址: 码云

打包好的插件地址 链接: 百度云 密码:oatf

本文使用 mdnice 排版