commit
94ebe1cff0
21 changed files with 1612 additions and 0 deletions
@ -0,0 +1,50 @@ |
|||
.gradle |
|||
build/ |
|||
!gradle/wrapper/gradle-wrapper.jar |
|||
!**/src/main/**/build/ |
|||
!**/src/test/**/build/ |
|||
|
|||
### IntelliJ IDEA ### |
|||
.idea/ |
|||
.idea/modules.xml |
|||
.idea/jarRepositories.xml |
|||
.idea/compiler.xml |
|||
.idea/libraries/ |
|||
*.iws |
|||
*.iml |
|||
*.ipr |
|||
out/ |
|||
!**/src/main/**/out/ |
|||
!**/src/test/**/out/ |
|||
|
|||
### Eclipse ### |
|||
.apt_generated |
|||
.classpath |
|||
.factorypath |
|||
.project |
|||
.settings |
|||
.springBeans |
|||
.sts4-cache |
|||
bin/ |
|||
!**/src/main/**/bin/ |
|||
!**/src/test/**/bin/ |
|||
|
|||
### NetBeans ### |
|||
/nbproject/private/ |
|||
/nbbuild/ |
|||
/dist/ |
|||
/nbdist/ |
|||
/.nb-gradle/ |
|||
|
|||
### VS Code ### |
|||
.vscode/ |
|||
|
|||
### Mac OS ### |
|||
.DS_Store |
|||
|
|||
# Maven specific |
|||
target/ |
|||
pom.xml.tag |
|||
pom.xml.releaseBackup |
|||
pom.xml.versionsBackup |
|||
pom.xml.next |
|||
@ -0,0 +1,24 @@ |
|||
<component name="ProjectRunConfigurationManager"> |
|||
<configuration default="false" name="Run Plugin" type="GradleRunConfiguration" factoryName="Gradle"> |
|||
<log_file alias="idea.log" path="$PROJECT_DIR$/build/idea-sandbox/system/log/idea.log"/> |
|||
<ExternalSystemSettings> |
|||
<option name="executionName"/> |
|||
<option name="externalProjectPath" value="$PROJECT_DIR$"/> |
|||
<option name="externalSystemIdString" value="GRADLE"/> |
|||
<option name="scriptParameters" value=""/> |
|||
<option name="taskDescriptions"> |
|||
<list/> |
|||
</option> |
|||
<option name="taskNames"> |
|||
<list> |
|||
<option value="runIde"/> |
|||
</list> |
|||
</option> |
|||
<option name="vmOptions" value=""/> |
|||
</ExternalSystemSettings> |
|||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess> |
|||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess> |
|||
<DebugAllEnabled>false</DebugAllEnabled> |
|||
<method v="2"/> |
|||
</configuration> |
|||
</component> |
|||
@ -0,0 +1,46 @@ |
|||
plugins { |
|||
id("java") |
|||
id("org.jetbrains.kotlin.jvm") version "1.9.25" |
|||
id("org.jetbrains.intellij") version "1.17.4" |
|||
} |
|||
|
|||
group = "com.wd" |
|||
version = "1.0-SNAPSHOT" |
|||
|
|||
repositories { |
|||
mavenCentral() |
|||
} |
|||
|
|||
// Configure Gradle IntelliJ Plugin |
|||
// Read more: https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html |
|||
intellij { |
|||
version.set("2024.3") |
|||
type.set("IC") // Target IDE Platform |
|||
plugins.set(listOf(/* Plugin Dependencies */)) |
|||
} |
|||
|
|||
tasks { |
|||
// Set the JVM compatibility versions |
|||
withType<JavaCompile> { |
|||
sourceCompatibility = "17" |
|||
targetCompatibility = "17" |
|||
} |
|||
withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> { |
|||
kotlinOptions.jvmTarget = "17" |
|||
} |
|||
|
|||
patchPluginXml { |
|||
sinceBuild.set("231.*") |
|||
untilBuild.set("243.*") |
|||
} |
|||
|
|||
signPlugin { |
|||
certificateChain.set(System.getenv("CERTIFICATE_CHAIN")) |
|||
privateKey.set(System.getenv("PRIVATE_KEY")) |
|||
password.set(System.getenv("PRIVATE_KEY_PASSWORD")) |
|||
} |
|||
|
|||
publishPlugin { |
|||
token.set(System.getenv("PUBLISH_TOKEN")) |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
# Opt-out flag for bundling Kotlin standard library -> https://jb.gg/intellij-platform-kotlin-stdlib |
|||
kotlin.stdlib.default.dependency=false |
|||
# Enable Gradle Configuration Cache -> https://docs.gradle.org/current/userguide/configuration_cache.html |
|||
org.gradle.configuration-cache=true |
|||
# Enable Gradle Build Cache -> https://docs.gradle.org/current/userguide/build_cache.html |
|||
org.gradle.caching=true |
|||
Binary file not shown.
@ -0,0 +1,5 @@ |
|||
distributionBase=GRADLE_USER_HOME |
|||
distributionPath=wrapper/dists |
|||
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.11.1-bin.zip |
|||
zipStoreBase=GRADLE_USER_HOME |
|||
zipStorePath=wrapper/dists |
|||
@ -0,0 +1,234 @@ |
|||
#!/bin/sh |
|||
|
|||
# |
|||
# Copyright © 2015-2021 the original authors. |
|||
# |
|||
# Licensed under the Apache License, Version 2.0 (the "License"); |
|||
# you may not use this file except in compliance with the License. |
|||
# You may obtain a copy of the License at |
|||
# |
|||
# https://www.apache.org/licenses/LICENSE-2.0 |
|||
# |
|||
# Unless required by applicable law or agreed to in writing, software |
|||
# distributed under the License is distributed on an "AS IS" BASIS, |
|||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
# See the License for the specific language governing permissions and |
|||
# limitations under the License. |
|||
# |
|||
|
|||
############################################################################## |
|||
# |
|||
# Gradle start up script for POSIX generated by Gradle. |
|||
# |
|||
# Important for running: |
|||
# |
|||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is |
|||
# noncompliant, but you have some other compliant shell such as ksh or |
|||
# bash, then to run this script, type that shell name before the whole |
|||
# command line, like: |
|||
# |
|||
# ksh Gradle |
|||
# |
|||
# Busybox and similar reduced shells will NOT work, because this script |
|||
# requires all of these POSIX shell features: |
|||
# * functions; |
|||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», |
|||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»; |
|||
# * compound commands having a testable exit status, especially «case»; |
|||
# * various built-in commands including «command», «set», and «ulimit». |
|||
# |
|||
# Important for patching: |
|||
# |
|||
# (2) This script targets any POSIX shell, so it avoids extensions provided |
|||
# by Bash, Ksh, etc; in particular arrays are avoided. |
|||
# |
|||
# The "traditional" practice of packing multiple parameters into a |
|||
# space-separated string is a well documented source of bugs and security |
|||
# problems, so this is (mostly) avoided, by progressively accumulating |
|||
# options in "$@", and eventually passing that to Java. |
|||
# |
|||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, |
|||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; |
|||
# see the in-line comments for details. |
|||
# |
|||
# There are tweaks for specific operating systems such as AIX, CygWin, |
|||
# Darwin, MinGW, and NonStop. |
|||
# |
|||
# (3) This script is generated from the Groovy template |
|||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt |
|||
# within the Gradle project. |
|||
# |
|||
# You can find Gradle at https://github.com/gradle/gradle/. |
|||
# |
|||
############################################################################## |
|||
|
|||
# Attempt to set APP_HOME |
|||
|
|||
# Resolve links: $0 may be a link |
|||
app_path=$0 |
|||
|
|||
# Need this for daisy-chained symlinks. |
|||
while |
|||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path |
|||
[ -h "$app_path" ] |
|||
do |
|||
ls=$( ls -ld "$app_path" ) |
|||
link=${ls#*' -> '} |
|||
case $link in #( |
|||
/*) app_path=$link ;; #( |
|||
*) app_path=$APP_HOME$link ;; |
|||
esac |
|||
done |
|||
|
|||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit |
|||
|
|||
APP_NAME="Gradle" |
|||
APP_BASE_NAME=${0##*/} |
|||
|
|||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. |
|||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' |
|||
|
|||
# Use the maximum available, or set MAX_FD != -1 to use that value. |
|||
MAX_FD=maximum |
|||
|
|||
warn () { |
|||
echo "$*" |
|||
} >&2 |
|||
|
|||
die () { |
|||
echo |
|||
echo "$*" |
|||
echo |
|||
exit 1 |
|||
} >&2 |
|||
|
|||
# OS specific support (must be 'true' or 'false'). |
|||
cygwin=false |
|||
msys=false |
|||
darwin=false |
|||
nonstop=false |
|||
case "$( uname )" in #( |
|||
CYGWIN* ) cygwin=true ;; #( |
|||
Darwin* ) darwin=true ;; #( |
|||
MSYS* | MINGW* ) msys=true ;; #( |
|||
NONSTOP* ) nonstop=true ;; |
|||
esac |
|||
|
|||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar |
|||
|
|||
|
|||
# Determine the Java command to use to start the JVM. |
|||
if [ -n "$JAVA_HOME" ] ; then |
|||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then |
|||
# IBM's JDK on AIX uses strange locations for the executables |
|||
JAVACMD=$JAVA_HOME/jre/sh/java |
|||
else |
|||
JAVACMD=$JAVA_HOME/bin/java |
|||
fi |
|||
if [ ! -x "$JAVACMD" ] ; then |
|||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME |
|||
|
|||
Please set the JAVA_HOME variable in your environment to match the |
|||
location of your Java installation." |
|||
fi |
|||
else |
|||
JAVACMD=java |
|||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. |
|||
|
|||
Please set the JAVA_HOME variable in your environment to match the |
|||
location of your Java installation." |
|||
fi |
|||
|
|||
# Increase the maximum file descriptors if we can. |
|||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then |
|||
case $MAX_FD in #( |
|||
max*) |
|||
MAX_FD=$( ulimit -H -n ) || |
|||
warn "Could not query maximum file descriptor limit" |
|||
esac |
|||
case $MAX_FD in #( |
|||
'' | soft) :;; #( |
|||
*) |
|||
ulimit -n "$MAX_FD" || |
|||
warn "Could not set maximum file descriptor limit to $MAX_FD" |
|||
esac |
|||
fi |
|||
|
|||
# Collect all arguments for the java command, stacking in reverse order: |
|||
# * args from the command line |
|||
# * the main class name |
|||
# * -classpath |
|||
# * -D...appname settings |
|||
# * --module-path (only if needed) |
|||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. |
|||
|
|||
# For Cygwin or MSYS, switch paths to Windows format before running java |
|||
if "$cygwin" || "$msys" ; then |
|||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) |
|||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) |
|||
|
|||
JAVACMD=$( cygpath --unix "$JAVACMD" ) |
|||
|
|||
# Now convert the arguments - kludge to limit ourselves to /bin/sh |
|||
for arg do |
|||
if |
|||
case $arg in #( |
|||
-*) false ;; # don't mess with options #( |
|||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath |
|||
[ -e "$t" ] ;; #( |
|||
*) false ;; |
|||
esac |
|||
then |
|||
arg=$( cygpath --path --ignore --mixed "$arg" ) |
|||
fi |
|||
# Roll the args list around exactly as many times as the number of |
|||
# args, so each arg winds up back in the position where it started, but |
|||
# possibly modified. |
|||
# |
|||
# NB: a `for` loop captures its iteration list before it begins, so |
|||
# changing the positional parameters here affects neither the number of |
|||
# iterations, nor the values presented in `arg`. |
|||
shift # remove old arg |
|||
set -- "$@" "$arg" # push replacement arg |
|||
done |
|||
fi |
|||
|
|||
# Collect all arguments for the java command; |
|||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of |
|||
# shell script including quotes and variable substitutions, so put them in |
|||
# double quotes to make sure that they get re-expanded; and |
|||
# * put everything else in single quotes, so that it's not re-expanded. |
|||
|
|||
set -- \ |
|||
"-Dorg.gradle.appname=$APP_BASE_NAME" \ |
|||
-classpath "$CLASSPATH" \ |
|||
org.gradle.wrapper.GradleWrapperMain \ |
|||
"$@" |
|||
|
|||
# Use "xargs" to parse quoted args. |
|||
# |
|||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed. |
|||
# |
|||
# In Bash we could simply go: |
|||
# |
|||
# readarray ARGS < <( xargs -n1 <<<"$var" ) && |
|||
# set -- "${ARGS[@]}" "$@" |
|||
# |
|||
# but POSIX shell has neither arrays nor command substitution, so instead we |
|||
# post-process each arg (as a line of input to sed) to backslash-escape any |
|||
# character that might be a shell metacharacter, then use eval to reverse |
|||
# that process (while maintaining the separation between arguments), and wrap |
|||
# the whole thing up as a single "set" statement. |
|||
# |
|||
# This will of course break if any of these variables contains a newline or |
|||
# an unmatched quote. |
|||
# |
|||
|
|||
eval "set -- $( |
|||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | |
|||
xargs -n1 | |
|||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | |
|||
tr '\n' ' ' |
|||
)" '"$@"' |
|||
|
|||
exec "$JAVACMD" "$@" |
|||
@ -0,0 +1,89 @@ |
|||
@rem |
|||
@rem Copyright 2015 the original author or authors. |
|||
@rem |
|||
@rem Licensed under the Apache License, Version 2.0 (the "License"); |
|||
@rem you may not use this file except in compliance with the License. |
|||
@rem You may obtain a copy of the License at |
|||
@rem |
|||
@rem https://www.apache.org/licenses/LICENSE-2.0 |
|||
@rem |
|||
@rem Unless required by applicable law or agreed to in writing, software |
|||
@rem distributed under the License is distributed on an "AS IS" BASIS, |
|||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
@rem See the License for the specific language governing permissions and |
|||
@rem limitations under the License. |
|||
@rem |
|||
|
|||
@if "%DEBUG%" == "" @echo off |
|||
@rem ########################################################################## |
|||
@rem |
|||
@rem Gradle startup script for Windows |
|||
@rem |
|||
@rem ########################################################################## |
|||
|
|||
@rem Set local scope for the variables with windows NT shell |
|||
if "%OS%"=="Windows_NT" setlocal |
|||
|
|||
set DIRNAME=%~dp0 |
|||
if "%DIRNAME%" == "" set DIRNAME=. |
|||
set APP_BASE_NAME=%~n0 |
|||
set APP_HOME=%DIRNAME% |
|||
|
|||
@rem Resolve any "." and ".." in APP_HOME to make it shorter. |
|||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi |
|||
|
|||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. |
|||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" |
|||
|
|||
@rem Find java.exe |
|||
if defined JAVA_HOME goto findJavaFromJavaHome |
|||
|
|||
set JAVA_EXE=java.exe |
|||
%JAVA_EXE% -version >NUL 2>&1 |
|||
if "%ERRORLEVEL%" == "0" goto execute |
|||
|
|||
echo. |
|||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. |
|||
echo. |
|||
echo Please set the JAVA_HOME variable in your environment to match the |
|||
echo location of your Java installation. |
|||
|
|||
goto fail |
|||
|
|||
:findJavaFromJavaHome |
|||
set JAVA_HOME=%JAVA_HOME:"=% |
|||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe |
|||
|
|||
if exist "%JAVA_EXE%" goto execute |
|||
|
|||
echo. |
|||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% |
|||
echo. |
|||
echo Please set the JAVA_HOME variable in your environment to match the |
|||
echo location of your Java installation. |
|||
|
|||
goto fail |
|||
|
|||
:execute |
|||
@rem Setup the command line |
|||
|
|||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar |
|||
|
|||
|
|||
@rem Execute Gradle |
|||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* |
|||
|
|||
:end |
|||
@rem End local scope for the variables with windows NT shell |
|||
if "%ERRORLEVEL%"=="0" goto mainEnd |
|||
|
|||
:fail |
|||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of |
|||
rem the _cmd.exe /c_ return code! |
|||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 |
|||
exit /b 1 |
|||
|
|||
:mainEnd |
|||
if "%OS%"=="Windows_NT" endlocal |
|||
|
|||
:omega |
|||
@ -0,0 +1,6 @@ |
|||
val location: String? = connection.getHeaderField("Location") |
|||
if (location == null) { |
|||
// 处理 Location 为 null 的情况,例如抛出异常或返回默认值 |
|||
throw IOException("Location header is missing in the response") |
|||
} |
|||
// 原有逻辑 |
|||
@ -0,0 +1,133 @@ |
|||
# Maven-aggregation Quickstart |
|||
|
|||
Maven-aggregation Quickstart 是一个 IntelliJ IDEA 插件,用于快速生成标准的多模块 Maven 项目结构。通过该插件,你可以一键创建模块化项目,并自动配置模块间的依赖关系,同时支持自定义模块名称和 Java 版本,非常适合用于 Java 项目的快速启动。 |
|||
|
|||
--- |
|||
|
|||
## 📌 主要功能 |
|||
|
|||
- **一键创建 Maven 多模块项目结构** |
|||
- **自动生成模块间的依赖关系** |
|||
- **支持自定义模块名称** |
|||
- **支持选择 Java 版本** |
|||
- **自动生成 README.md 和 .gitignore 文件** |
|||
|
|||
--- |
|||
|
|||
## 🚀 使用方法 |
|||
|
|||
### 1. 安装插件 |
|||
|
|||
1. 打开 IntelliJ IDEA。 |
|||
2. 进入 `Settings (Preferences)` > `Plugins`。 |
|||
3. 点击 `Marketplace` 标签。 |
|||
4. 搜索 `Maven-aggregation Quickstart`。 |
|||
5. 点击 `Install` 安装插件。 |
|||
6. 重启 IntelliJ IDEA。 |
|||
|
|||
### 2. 创建项目 |
|||
|
|||
1. 打开 IntelliJ IDEA。 |
|||
2. 点击菜单 `File > New > Create Maven Aggregation Project`。 |
|||
3. 填写以下信息: |
|||
- GroupId: Maven 项目的组织标识(例如:`com.example`) |
|||
- ArtifactId: 项目名称 |
|||
- Version: 项目版本(默认 `1.0.0`) |
|||
- 模块名称:输入多个模块名称(例如:`api`, `service`, `pojo`) |
|||
- Java 版本:选择项目使用的 Java 版本 |
|||
4. 点击 `Finish`,插件会自动生成项目结构。 |
|||
|
|||
--- |
|||
|
|||
## 📁 项目结构示例 |
|||
|
|||
生成的项目目录结构如下: |
|||
your-project-name/ |
|||
├── api/ |
|||
├── service/ |
|||
├── pojo/ |
|||
├── common/ |
|||
├── mapper |
|||
|
|||
每个模块都包含以下标准目录结构: |
|||
module-name/ |
|||
├── src/ │ |
|||
├── main/ │ │ |
|||
├── java/ Java 源代码 |
|||
│ │ └── resources/ 静态资源文件 |
|||
│ └── test/ │ ├── java/ 测试代码 |
|||
|
|||
|
|||
--- |
|||
|
|||
## 🧩 模块说明 |
|||
|
|||
| 模块名称 | 说明 | |
|||
|---------|------| |
|||
| `api` | 对外暴露的 API 接口模块 | |
|||
| `common` | 公共工具类和通用组件模块 | |
|||
| `mapper` | 数据访问层模块(通常用于数据库操作) | |
|||
| `pojo` | 实体类模块 | |
|||
| `service` | 业务逻辑模块 | |
|||
|
|||
> 注意:你可以自定义模块名称,插件会自动识别并生成对应描述。 |
|||
|
|||
--- |
|||
|
|||
## 🧪 构建项目 |
|||
|
|||
为了确保项目的顺利构建,请按照以下步骤操作: |
|||
|
|||
1. **打开终端**:在你的项目根目录下打开一个新的终端窗口。 |
|||
2. **执行 Maven 命令**:运行以下命令来清理并安装项目依赖。 |
|||
|
|||
``` |
|||
mvn clean install |
|||
|
|||
|
|||
``` |
|||
|
|||
|
|||
--- |
|||
|
|||
## 🛠️ 开发与构建插件 |
|||
|
|||
如果你希望修改插件或构建插件源码,请参考以下步骤: |
|||
|
|||
### 1. 克隆仓库 |
|||
``` |
|||
git clone https://github.com/yourname/maven-aggregation.git |
|||
cd maven-aggregation |
|||
|
|||
``` |
|||
|
|||
### 2. 构建插件 |
|||
|
|||
使用 Maven 构建插件: |
|||
|
|||
``` |
|||
mvn clean package |
|||
|
|||
``` |
|||
|
|||
构建完成后,插件的 `.jar` 文件会生成在 `target/` 目录下。 |
|||
|
|||
### 3. 安装插件到 IntelliJ IDEA |
|||
|
|||
1. 打开 IntelliJ IDEA。 |
|||
2. 进入 `Settings (Preferences)` > `Plugins`。 |
|||
3. 点击 `Install Plugin from Disk...`。 |
|||
4. 选择 `target/maven-aggregation.jar`。 |
|||
5. 安装并重启 IntelliJ IDEA. |
|||
|
|||
--- |
|||
|
|||
## 📞 联系我们 |
|||
|
|||
如果你有任何问题或建议,请联系: |
|||
|
|||
📧 Email: 1938023944@qq.com |
|||
🌐 Website: [https://www.wandong.com](https://www.wandong.com) |
|||
|
|||
--- |
|||
|
|||
@ -0,0 +1,8 @@ |
|||
pluginManagement { |
|||
repositories { |
|||
mavenCentral() |
|||
gradlePluginPortal() |
|||
} |
|||
} |
|||
|
|||
rootProject.name = "maven-aggregation" |
|||
@ -0,0 +1,173 @@ |
|||
package com.wd.maven.aggregation; |
|||
|
|||
import com.intellij.openapi.project.Project; |
|||
import com.intellij.openapi.ui.DialogWrapper; |
|||
import com.intellij.openapi.ui.ValidationInfo; |
|||
import com.intellij.ui.components.JBCheckBox; |
|||
import com.intellij.ui.components.JBLabel; |
|||
import com.intellij.ui.components.JBTextField; |
|||
|
|||
import javax.swing.*; |
|||
import java.awt.*; |
|||
import java.util.ArrayList; |
|||
import java.util.Arrays; |
|||
import java.util.List; |
|||
|
|||
public class AggregationProjectDialog extends DialogWrapper { |
|||
|
|||
private JBTextField groupIdField; |
|||
private JBTextField artifactIdField; |
|||
private JBTextField versionField; |
|||
private JBTextField modulesField; |
|||
private JComboBox<String> javaVersionComboBox; |
|||
|
|||
// 预定义模块复选框
|
|||
private JBCheckBox apiCheckBox; |
|||
private JBCheckBox commonCheckBox; |
|||
private JBCheckBox mapperCheckBox; |
|||
private JBCheckBox pojoCheckBox; |
|||
private JBCheckBox serviceCheckBox; |
|||
|
|||
public AggregationProjectDialog(Project project) { |
|||
super(project); |
|||
setTitle("创建Maven聚合项目"); |
|||
init(); |
|||
} |
|||
|
|||
@Override |
|||
protected JComponent createCenterPanel() { |
|||
JPanel panel = new JPanel(new GridBagLayout()); |
|||
GridBagConstraints c = new GridBagConstraints(); |
|||
c.fill = GridBagConstraints.HORIZONTAL; |
|||
c.insets = new Insets(5, 5, 5, 5); |
|||
|
|||
// Group ID
|
|||
c.gridx = 0; |
|||
c.gridy = 0; |
|||
panel.add(new JBLabel("Group ID:"), c); |
|||
|
|||
c.gridx = 1; |
|||
c.weightx = 1.0; |
|||
groupIdField = new JBTextField("com.example"); |
|||
panel.add(groupIdField, c); |
|||
|
|||
// Artifact ID
|
|||
c.gridx = 0; |
|||
c.gridy = 1; |
|||
c.weightx = 0.0; |
|||
panel.add(new JBLabel("Artifact ID:"), c); |
|||
|
|||
c.gridx = 1; |
|||
c.weightx = 1.0; |
|||
artifactIdField = new JBTextField("demo"); |
|||
panel.add(artifactIdField, c); |
|||
|
|||
// Version
|
|||
c.gridx = 0; |
|||
c.gridy = 2; |
|||
c.weightx = 0.0; |
|||
panel.add(new JBLabel("Version:"), c); |
|||
|
|||
c.gridx = 1; |
|||
c.weightx = 1.0; |
|||
versionField = new JBTextField("1.0-SNAPSHOT"); |
|||
panel.add(versionField, c); |
|||
|
|||
// Java Version
|
|||
c.gridx = 0; |
|||
c.gridy = 3; |
|||
c.weightx = 0.0; |
|||
panel.add(new JBLabel("Java Version:"), c); |
|||
|
|||
c.gridx = 1; |
|||
c.weightx = 1.0; |
|||
javaVersionComboBox = new JComboBox<>(new String[]{"8", "11", "17", "21"}); |
|||
panel.add(javaVersionComboBox, c); |
|||
|
|||
// 预定义模块
|
|||
c.gridx = 0; |
|||
c.gridy = 4; |
|||
c.weightx = 0.0; |
|||
panel.add(new JBLabel("预定义模块:"), c); |
|||
|
|||
// 模块复选框面板
|
|||
JPanel modulesPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); |
|||
apiCheckBox = new JBCheckBox("api", true); |
|||
commonCheckBox = new JBCheckBox("common", true); |
|||
mapperCheckBox = new JBCheckBox("mapper", true); |
|||
pojoCheckBox = new JBCheckBox("pojo", true); |
|||
serviceCheckBox = new JBCheckBox("service", true); |
|||
|
|||
modulesPanel.add(apiCheckBox); |
|||
modulesPanel.add(commonCheckBox); |
|||
modulesPanel.add(mapperCheckBox); |
|||
modulesPanel.add(pojoCheckBox); |
|||
modulesPanel.add(serviceCheckBox); |
|||
|
|||
c.gridx = 1; |
|||
c.weightx = 1.0; |
|||
panel.add(modulesPanel, c); |
|||
|
|||
// 自定义模块
|
|||
c.gridx = 0; |
|||
c.gridy = 5; |
|||
c.weightx = 0.0; |
|||
panel.add(new JBLabel("自定义模块 (逗号分隔):"), c); |
|||
|
|||
c.gridx = 1; |
|||
c.weightx = 1.0; |
|||
modulesField = new JBTextField(); |
|||
panel.add(modulesField, c); |
|||
|
|||
return panel; |
|||
} |
|||
|
|||
@Override |
|||
protected ValidationInfo doValidate() { |
|||
if (groupIdField.getText().trim().isEmpty()) { |
|||
return new ValidationInfo("Group ID不能为空", groupIdField); |
|||
} |
|||
if (artifactIdField.getText().trim().isEmpty()) { |
|||
return new ValidationInfo("Artifact ID不能为空", artifactIdField); |
|||
} |
|||
if (versionField.getText().trim().isEmpty()) { |
|||
return new ValidationInfo("Version不能为空", versionField); |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
public String getGroupId() { |
|||
return groupIdField.getText().trim(); |
|||
} |
|||
|
|||
public String getArtifactId() { |
|||
return artifactIdField.getText().trim(); |
|||
} |
|||
|
|||
public String getVersion() { |
|||
return versionField.getText().trim(); |
|||
} |
|||
|
|||
public String getJavaVersion() { |
|||
return (String) javaVersionComboBox.getSelectedItem(); |
|||
} |
|||
|
|||
public String[] getModules() { |
|||
List<String> modulesList = new ArrayList<>(); |
|||
|
|||
// 添加选中的预定义模块
|
|||
if (apiCheckBox.isSelected()) modulesList.add("api"); |
|||
if (commonCheckBox.isSelected()) modulesList.add("common"); |
|||
if (mapperCheckBox.isSelected()) modulesList.add("mapper"); |
|||
if (pojoCheckBox.isSelected()) modulesList.add("pojo"); |
|||
if (serviceCheckBox.isSelected()) modulesList.add("service"); |
|||
|
|||
// 添加自定义模块
|
|||
String customModules = modulesField.getText().trim(); |
|||
if (!customModules.isEmpty()) { |
|||
modulesList.addAll(Arrays.asList(customModules.split("\\s*,\\s*"))); |
|||
} |
|||
|
|||
return modulesList.toArray(new String[0]); |
|||
} |
|||
} |
|||
@ -0,0 +1,327 @@ |
|||
package com.wd.maven.aggregation; |
|||
|
|||
import com.intellij.openapi.diagnostic.Logger; |
|||
import com.intellij.openapi.project.Project; |
|||
import com.intellij.openapi.vfs.VirtualFile; |
|||
|
|||
import java.io.BufferedWriter; |
|||
import java.io.IOException; |
|||
import java.nio.file.Files; |
|||
import java.nio.file.Path; |
|||
import java.nio.file.Paths; |
|||
import java.util.Arrays; |
|||
|
|||
|
|||
public class AggregationProjectGenerator { |
|||
|
|||
private static final Logger LOG = Logger.getInstance(AggregationProjectGenerator.class); |
|||
|
|||
public void generateProject(Project project, String groupId, String artifactId, String version, String[] modules, String javaVersion) { |
|||
VirtualFile baseDir = project.getBaseDir(); |
|||
if (baseDir == null) { |
|||
LOG.warn("Project base directory not found."); |
|||
return; |
|||
} |
|||
|
|||
Path projectPath = Paths.get(baseDir.getPath()); |
|||
|
|||
// 写入父 POM
|
|||
writeParentPom(projectPath, groupId, artifactId, version, modules, javaVersion); |
|||
|
|||
// 写入子模块
|
|||
for (String module : modules) { |
|||
// 使用父项目名-子模块名的格式创建目录
|
|||
String moduleName = artifactId + "-" + module; |
|||
Path modulePath = projectPath.resolve(moduleName); |
|||
writeModulePom(modulePath, groupId, artifactId, version, moduleName); |
|||
createDirectoryStructure(modulePath.resolve("src/main/java")); |
|||
createDirectoryStructure(modulePath.resolve("src/test/java")); |
|||
createDirectoryStructure(modulePath.resolve("src/main/resources")); |
|||
} |
|||
|
|||
// 添加模块间依赖
|
|||
addModuleDependencies(projectPath, groupId, version, artifactId, modules); |
|||
|
|||
// README.md
|
|||
writeReadme(projectPath, artifactId, modules); |
|||
|
|||
// .gitignore
|
|||
writeGitignore(projectPath); |
|||
} |
|||
|
|||
|
|||
private void writeParentPom(Path projectPath, String groupId, String artifactId, String version, String[] modules, String javaVersion) { |
|||
StringBuilder moduleXml = new StringBuilder(); |
|||
for (String module : modules) { |
|||
// 使用父项目名-子模块名的格式
|
|||
String moduleName = artifactId + "-" + module; |
|||
moduleXml.append(" <module>").append(moduleName).append("</module>\n"); |
|||
} |
|||
|
|||
StringBuilder dependencyManagementXml = new StringBuilder(); |
|||
for (String module : modules) { |
|||
dependencyManagementXml.append(" <dependency>\n") |
|||
.append(" <groupId>").append(groupId).append("</groupId>\n") |
|||
.append(" <artifactId>").append(artifactId).append("-").append(module).append("</artifactId>\n") // 使用正确的 artifactId
|
|||
.append(" <version>${project.version}</version>\n") |
|||
.append(" </dependency>\n"); |
|||
} |
|||
|
|||
String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + |
|||
"<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n" + |
|||
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" + |
|||
" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n" + |
|||
" <modelVersion>4.0.0</modelVersion>\n" + |
|||
"\n" + |
|||
" <groupId>" + groupId + "</groupId>\n" + |
|||
" <artifactId>" + artifactId + "</artifactId>\n" + |
|||
" <version>" + version + "</version>\n" + |
|||
" <packaging>pom</packaging>\n" + |
|||
"\n" + |
|||
" <modules>\n" + |
|||
moduleXml.toString() + |
|||
" </modules>\n" + |
|||
"\n" + |
|||
" <properties>\n" + |
|||
" <maven.compiler.source>" + javaVersion + "</maven.compiler.source>\n" + |
|||
" <maven.compiler.target>" + javaVersion + "</maven.compiler.target>\n" + |
|||
" <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n" + |
|||
" </properties>\n" + |
|||
"\n" + |
|||
" <dependencyManagement>\n" + |
|||
" <dependencies>\n" + |
|||
" <!-- 项目内部模块依赖 -->\n" + |
|||
dependencyManagementXml.toString() + |
|||
" </dependencies>\n" + |
|||
" </dependencyManagement>\n" + |
|||
"</project>"; |
|||
|
|||
writeToFile(projectPath.resolve("pom.xml"), content); |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
private void writeReadme(Path projectPath, String projectName, String[] modules) { |
|||
StringBuilder modulesDescription = new StringBuilder(); |
|||
for (String module : modules) { |
|||
modulesDescription.append("- `").append(module).append("`: "); |
|||
|
|||
// 根据模块名称添加描述
|
|||
if (module.equals("api")) { |
|||
modulesDescription.append("对外暴露的API接口模块\n"); |
|||
} else if (module.equals("common")) { |
|||
modulesDescription.append("公共工具类和通用组件模块\n"); |
|||
} else if (module.equals("mapper")) { |
|||
modulesDescription.append("数据访问层模块\n"); |
|||
} else if (module.equals("pojo")) { |
|||
modulesDescription.append("实体类模块\n"); |
|||
} else if (module.equals("service")) { |
|||
modulesDescription.append("业务逻辑模块\n"); |
|||
} else { |
|||
modulesDescription.append("自定义模块\n"); |
|||
} |
|||
} |
|||
|
|||
String content = "# " + projectName + " Maven聚合项目\n\n" + |
|||
"这是一个多模块Maven项目模板,通过模块化设计组织Java应用程序。\n\n" + |
|||
"## 项目结构\n\n" + |
|||
"```\n" + |
|||
projectName + "/\n"; |
|||
|
|||
// 添加模块目录结构
|
|||
for (String module : modules) { |
|||
content += "├── " + module + "/\n"; |
|||
} |
|||
|
|||
content += "```\n\n" + |
|||
"## 模块说明\n\n" + |
|||
modulesDescription.toString() + "\n" + |
|||
"## 开始使用\n\n" + |
|||
"1. 根据需要修改各模块的`pom.xml`文件\n" + |
|||
"2. 在相应模块中添加源代码\n" + |
|||
"3. 使用以下命令构建项目:\n\n" + |
|||
"```bash\n" + |
|||
"mvn clean install\n" + |
|||
"```\n"; |
|||
|
|||
writeToFile(projectPath.resolve("README.md"), content); |
|||
} |
|||
|
|||
private void writeGitignore(Path projectPath) { |
|||
String content = "# Maven\n" + |
|||
"target/\n" + |
|||
"pom.xml.tag\n" + |
|||
"pom.xml.releaseBackup\n" + |
|||
"pom.xml.versionsBackup\n" + |
|||
"pom.xml.next\n" + |
|||
"release.properties\n" + |
|||
"dependency-reduced-pom.xml\n" + |
|||
"buildNumber.properties\n" + |
|||
".mvn/timing.properties\n" + |
|||
".mvn/wrapper/maven-wrapper.jar\n\n" + |
|||
"# IntelliJ IDEA\n" + |
|||
".idea/\n" + |
|||
"*.iws\n" + |
|||
"*.iml\n" + |
|||
"*.ipr\n\n" + |
|||
"# Eclipse\n" + |
|||
".classpath\n" + |
|||
".project\n" + |
|||
".settings/\n\n" + |
|||
"# Mac\n" + |
|||
".DS_Store\n"; |
|||
|
|||
writeToFile(projectPath.resolve(".gitignore"), content); |
|||
} |
|||
private void writeModulePom(Path modulePath, String groupId, String parentArtifactId, String version, String projectName) { |
|||
// 获取模块名称
|
|||
String moduleName = modulePath.getFileName().toString(); |
|||
|
|||
// 新的 artifactId: 父项目名称-子模块名
|
|||
//String newArtifactId = parentArtifactId + "-" + moduleName;
|
|||
String newArtifactId = moduleName; |
|||
|
|||
// 构建 pom.xml 内容
|
|||
String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + |
|||
"<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n" + |
|||
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" + |
|||
" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n" + |
|||
" <modelVersion>4.0.0</modelVersion>\n" + |
|||
" <parent>\n" + |
|||
" <groupId>" + groupId + "</groupId>\n" + |
|||
" <artifactId>" + parentArtifactId + "</artifactId>\n" + |
|||
" <version>" + version + "</version>\n" + |
|||
" </parent>\n" + |
|||
" <artifactId>" + newArtifactId + "</artifactId>\n" + // 使用新的 artifactId
|
|||
" <packaging>jar</packaging>\n" + |
|||
"</project>"; |
|||
|
|||
// 写入文件
|
|||
writeToFile(modulePath.resolve("pom.xml"), content); |
|||
|
|||
// 可选:手动验证 pom.xml 内容
|
|||
LOG.info("Generated pom.xml content for module " + moduleName + ":\n" + content); |
|||
} |
|||
|
|||
private void addModuleDependencies(Path projectPath, String groupId, String version, String parentArtifactId, String[] modules) { |
|||
LOG.info("开始添加模块间依赖关系..."); |
|||
LOG.info("项目路径: " + projectPath); |
|||
LOG.info("父项目 artifactId: " + parentArtifactId); |
|||
LOG.info("模块列表: " + Arrays.toString(modules)); |
|||
|
|||
// 检查每个模块的 pom.xml 文件状态
|
|||
for (String module : modules) { |
|||
Path modulePath = projectPath.resolve(parentArtifactId + "-" + module); |
|||
Path pomPath = modulePath.resolve("pom.xml"); |
|||
LOG.info("Before adding dependencies, POM file existence for module " + module + ": " + Files.exists(pomPath)); |
|||
} |
|||
|
|||
// 默认依赖关系:api -> service -> mapper -> pojo -> common
|
|||
for (String module : modules) { |
|||
// 使用父项目名-子模块名的格式创建目录,moduleName 也满足此格式
|
|||
String moduleName = parentArtifactId + "-" + module; |
|||
|
|||
LOG.info("处理模块: " + moduleName); |
|||
|
|||
if (module.equals("api") && containsModule(modules, "service")) { |
|||
LOG.info("为模块 [api] 添加依赖: service"); |
|||
addDependencyToModule(projectPath.resolve(parentArtifactId + "-" + "api"), groupId, parentArtifactId, "service", version); |
|||
} else if (module.equals("service") && containsModule(modules, "mapper")) { |
|||
LOG.info("为模块 [service] 添加依赖: mapper"); |
|||
addDependencyToModule(projectPath.resolve(parentArtifactId + "-" + "service"), groupId, parentArtifactId, "mapper", version); |
|||
} else if (module.equals("mapper") && containsModule(modules, "pojo")) { |
|||
LOG.info("为模块 [mapper] 添加依赖: pojo"); |
|||
addDependencyToModule(projectPath.resolve(parentArtifactId + "-" + "mapper"), groupId, parentArtifactId, "pojo", version); |
|||
} else if (module.equals("pojo") && containsModule(modules, "common")) { |
|||
LOG.info("为模块 [pojo] 添加依赖: common"); |
|||
addDependencyToModule(projectPath.resolve(parentArtifactId + "-" + "pojo"), groupId, parentArtifactId, "common", version); |
|||
} else { |
|||
LOG.info("模块 [" + moduleName + "] 无需添加依赖"); |
|||
} |
|||
} |
|||
|
|||
LOG.info("模块间依赖关系添加完成"); |
|||
} |
|||
|
|||
private void addDependencyToModule(Path modulePath, String groupId, String parentArtifactId, String moduleName, String version) { |
|||
try { |
|||
Path pomPath = modulePath.resolve("pom.xml"); |
|||
LOG.info("POM file path for module " + modulePath + ": " + pomPath); |
|||
if (!Files.exists(pomPath)) { |
|||
LOG.warn("POM file does not exist for module: " + modulePath); |
|||
return; |
|||
} |
|||
|
|||
String content = new String(Files.readAllBytes(pomPath)); |
|||
LOG.info("Original POM content for module " + modulePath + ":\n" + content); |
|||
|
|||
String dependencyXml = " <dependency>\n" + |
|||
" <groupId>" + groupId + "</groupId>\n" + |
|||
" <artifactId>" + parentArtifactId + "-" + moduleName + "</artifactId>\n" + |
|||
" <version>" + version + "</version>\n" + |
|||
" </dependency>\n"; |
|||
|
|||
if (content.contains("</dependencies>")) { |
|||
// 已有依赖,在</dependencies>前添加
|
|||
int index = content.indexOf("</dependencies>"); |
|||
content = content.substring(0, index) + dependencyXml + content.substring(index); |
|||
} else if (content.contains("</project>")) { |
|||
// 没有依赖部分,在</project>前添加
|
|||
int index = content.indexOf("</project>"); |
|||
content = content.substring(0, index) + " <dependencies>\n" + dependencyXml + " </dependencies>\n" + content.substring(index); |
|||
} else { |
|||
LOG.warn("No suitable place to insert dependency in POM file for module: " + modulePath); |
|||
return; |
|||
} |
|||
|
|||
LOG.info("Updated POM content for module " + modulePath + ":\n" + content); |
|||
Files.write(pomPath, content.getBytes()); |
|||
} catch (IOException e) { |
|||
LOG.warn("Failed to add dependency to module: " + modulePath, e); |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
private void writeToFile(Path path, String content) { |
|||
try { |
|||
// 创建父目录(如果不存在)
|
|||
Files.createDirectories(path.getParent()); |
|||
|
|||
// 写入文件内容
|
|||
try (BufferedWriter writer = Files.newBufferedWriter(path)) { |
|||
writer.write(content); |
|||
} |
|||
} catch (IOException e) { |
|||
LOG.warn("Failed to write file: " + path, e); |
|||
} |
|||
} |
|||
|
|||
private void createDirectoryStructure(Path path) { |
|||
try { |
|||
Files.createDirectories(path); |
|||
} catch (IOException e) { |
|||
LOG.warn("Failed to create directory: " + path, e); |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
private boolean containsModule(String[] modules, String moduleName) { |
|||
for (String module : modules) { |
|||
if (module.equals(moduleName)) { |
|||
return true; |
|||
} |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
|
|||
|
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
package com.wd.maven.aggregation; |
|||
|
|||
import javax.swing.*; |
|||
import javax.swing.event.DocumentEvent; |
|||
import javax.swing.event.DocumentListener; |
|||
import java.awt.*; |
|||
import java.awt.event.ActionEvent; |
|||
import java.awt.event.ActionListener; |
|||
|
|||
public class DebounceDocumentListener implements DocumentListener { |
|||
private final Timer timer; |
|||
private final Runnable action; |
|||
private final int delay; |
|||
|
|||
public DebounceDocumentListener(Runnable action, int delay) { |
|||
this.action = action; |
|||
this.delay = delay; |
|||
this.timer = new Timer(delay, new ActionListener() { |
|||
@Override |
|||
public void actionPerformed(ActionEvent e) { |
|||
DebounceDocumentListener.this.action.run(); |
|||
} |
|||
}); |
|||
this.timer.setRepeats(false); |
|||
} |
|||
|
|||
@Override |
|||
public void insertUpdate(DocumentEvent e) { |
|||
timer.restart(); |
|||
} |
|||
|
|||
@Override |
|||
public void removeUpdate(DocumentEvent e) { |
|||
timer.restart(); |
|||
} |
|||
|
|||
@Override |
|||
public void changedUpdate(DocumentEvent e) { |
|||
timer.restart(); |
|||
} |
|||
} |
|||
@ -0,0 +1,56 @@ |
|||
package com.wd.maven.aggregation; |
|||
|
|||
import com.intellij.ide.util.projectWizard.WebProjectTemplate; |
|||
import com.intellij.openapi.module.Module; |
|||
import com.intellij.openapi.project.Project; |
|||
import com.intellij.openapi.vfs.VirtualFile; |
|||
import com.wd.maven.aggregation.AggregationProjectGenerator; |
|||
import com.wd.maven.aggregation.MavenAggregationSettings; |
|||
import com.wd.maven.aggregation.MavenAggregationSettingsPanel; |
|||
import org.jetbrains.annotations.NotNull; |
|||
import org.jetbrains.annotations.Nullable; |
|||
|
|||
import javax.swing.*; |
|||
|
|||
public class MavenAggregationProjectGenerator extends WebProjectTemplate<MavenAggregationSettings> { |
|||
|
|||
@NotNull |
|||
@Override |
|||
public String getName() { |
|||
return "Maven Aggregation Project"; |
|||
} |
|||
|
|||
@Override |
|||
public String getDescription() { |
|||
return "创建标准的Maven多模块项目结构,包含父POM和子模块"; |
|||
} |
|||
|
|||
@Nullable |
|||
@Override |
|||
public Icon getIcon() { |
|||
return null; // 可以返回一个自定义图标
|
|||
} |
|||
|
|||
@NotNull |
|||
public MavenAggregationSettings createSettings() { |
|||
return new MavenAggregationSettings(); |
|||
} |
|||
|
|||
@Nullable |
|||
public JComponent getSettingsPanel(MavenAggregationSettings settings) { |
|||
return new MavenAggregationSettingsPanel(settings).getPanel(); |
|||
} |
|||
|
|||
@Override |
|||
public void generateProject(@NotNull Project project, @NotNull VirtualFile baseDir, @NotNull MavenAggregationSettings settings, @NotNull Module module) { |
|||
AggregationProjectGenerator generator = new AggregationProjectGenerator(); |
|||
generator.generateProject( |
|||
project, |
|||
settings.getGroupId(), |
|||
settings.getArtifactId(), |
|||
settings.getVersion(), |
|||
settings.getModules(), |
|||
settings.getJavaVersion() |
|||
); |
|||
} |
|||
} |
|||
@ -0,0 +1,54 @@ |
|||
package com.wd.maven.aggregation; |
|||
|
|||
public class MavenAggregationSettings { |
|||
private String groupId = "com.example"; |
|||
private String artifactId = "demo"; |
|||
private String version = "1.0-SNAPSHOT"; |
|||
private String javaVersion = "8"; |
|||
private String[] modules = {"api", "common", "mapper", "pojo", "service"}; |
|||
|
|||
public String getGroupId() { |
|||
return groupId; |
|||
} |
|||
|
|||
public void setGroupId(String groupId) { |
|||
this.groupId = groupId; |
|||
} |
|||
|
|||
public String getArtifactId() { |
|||
return artifactId; |
|||
} |
|||
|
|||
public void setArtifactId(String artifactId) { |
|||
this.artifactId = artifactId; |
|||
} |
|||
|
|||
public String getVersion() { |
|||
return version; |
|||
} |
|||
|
|||
public void setVersion(String version) { |
|||
this.version = version; |
|||
} |
|||
|
|||
public String getJavaVersion() { |
|||
return javaVersion; |
|||
} |
|||
|
|||
public void setJavaVersion(String javaVersion) { |
|||
this.javaVersion = javaVersion; |
|||
} |
|||
|
|||
public String[] getModules() { |
|||
return modules; |
|||
} |
|||
|
|||
public void setModules(String[] modules) { |
|||
this.modules = modules; |
|||
} |
|||
|
|||
|
|||
|
|||
public MavenAggregationSettings() { } |
|||
} |
|||
|
|||
@ -0,0 +1,227 @@ |
|||
package com.wd.maven.aggregation; |
|||
|
|||
import com.intellij.ui.components.JBCheckBox; |
|||
import com.intellij.ui.components.JBLabel; |
|||
import com.intellij.ui.components.JBTextField; |
|||
import com.intellij.util.ui.UIUtil; |
|||
|
|||
import javax.swing.*; |
|||
import java.awt.*; |
|||
import java.awt.event.ItemListener; |
|||
import java.util.ArrayList; |
|||
import java.util.Arrays; |
|||
import java.util.List; |
|||
|
|||
public class MavenAggregationSettingsPanel { |
|||
private JPanel mainPanel; |
|||
private JBTextField groupIdField; |
|||
private JBTextField artifactIdField; |
|||
private JBTextField versionField; |
|||
private JBTextField modulesField; |
|||
private JComboBox<String> javaVersionComboBox; |
|||
|
|||
// 预定义模块复选框
|
|||
private JBCheckBox apiCheckBox; |
|||
private JBCheckBox commonCheckBox; |
|||
private JBCheckBox mapperCheckBox; |
|||
private JBCheckBox pojoCheckBox; |
|||
private JBCheckBox serviceCheckBox; |
|||
|
|||
private final MavenAggregationSettings settings; |
|||
|
|||
public MavenAggregationSettingsPanel(MavenAggregationSettings settings) { |
|||
this.settings = settings; |
|||
createUI(); |
|||
initValues(); |
|||
} |
|||
|
|||
private void createUI() { |
|||
mainPanel = new JPanel(new GridBagLayout()); |
|||
GridBagConstraints c = new GridBagConstraints(); |
|||
c.fill = GridBagConstraints.HORIZONTAL; |
|||
c.insets = new Insets(5, 5, 5, 5); |
|||
|
|||
// Group ID
|
|||
c.gridx = 0; |
|||
c.gridy = 0; |
|||
mainPanel.add(new JBLabel("Group ID:"), c); |
|||
|
|||
c.gridx = 1; |
|||
c.weightx = 1.0; |
|||
groupIdField = new JBTextField(); |
|||
mainPanel.add(groupIdField, c); |
|||
|
|||
// Artifact ID
|
|||
c.gridx = 0; |
|||
c.gridy = 1; |
|||
c.weightx = 0.0; |
|||
mainPanel.add(new JBLabel("Artifact ID:"), c); |
|||
|
|||
c.gridx = 1; |
|||
c.weightx = 1.0; |
|||
artifactIdField = new JBTextField(); |
|||
mainPanel.add(artifactIdField, c); |
|||
|
|||
// Version
|
|||
c.gridx = 0; |
|||
c.gridy = 2; |
|||
c.weightx = 0.0; |
|||
mainPanel.add(new JBLabel("Version:"), c); |
|||
|
|||
c.gridx = 1; |
|||
c.weightx = 1.0; |
|||
versionField = new JBTextField(); |
|||
mainPanel.add(versionField, c); |
|||
|
|||
// Java Version
|
|||
c.gridx = 0; |
|||
c.gridy = 3; |
|||
c.weightx = 0.0; |
|||
mainPanel.add(new JBLabel("Java Version:"), c); |
|||
|
|||
c.gridx = 1; |
|||
c.weightx = 1.0; |
|||
javaVersionComboBox = new JComboBox<>(new String[]{"8", "11", "17", "21"}); |
|||
mainPanel.add(javaVersionComboBox, c); |
|||
|
|||
// 预定义模块
|
|||
c.gridx = 0; |
|||
c.gridy = 4; |
|||
c.weightx = 0.0; |
|||
mainPanel.add(new JBLabel("预定义模块:"), c); |
|||
|
|||
// 模块复选框面板
|
|||
JPanel modulesPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); |
|||
apiCheckBox = new JBCheckBox("api", true); |
|||
commonCheckBox = new JBCheckBox("common", true); |
|||
mapperCheckBox = new JBCheckBox("mapper", true); |
|||
pojoCheckBox = new JBCheckBox("pojo", true); |
|||
serviceCheckBox = new JBCheckBox("service", true); |
|||
|
|||
modulesPanel.add(apiCheckBox); |
|||
modulesPanel.add(commonCheckBox); |
|||
modulesPanel.add(mapperCheckBox); |
|||
modulesPanel.add(pojoCheckBox); |
|||
modulesPanel.add(serviceCheckBox); |
|||
|
|||
c.gridx = 1; |
|||
c.weightx = 1.0; |
|||
mainPanel.add(modulesPanel, c); |
|||
|
|||
// 自定义模块
|
|||
c.gridx = 0; |
|||
c.gridy = 5; |
|||
c.weightx = 0.0; |
|||
mainPanel.add(new JBLabel("自定义模块 (逗号分隔):"), c); |
|||
|
|||
c.gridx = 1; |
|||
c.weightx = 1.0; |
|||
modulesField = new JBTextField(); |
|||
mainPanel.add(modulesField, c); |
|||
|
|||
// 添加监听器
|
|||
groupIdField.getDocument().addDocumentListener(new DebounceDocumentListener(() -> { |
|||
settings.setGroupId(groupIdField.getText().trim()); |
|||
}, 300)); |
|||
|
|||
artifactIdField.getDocument().addDocumentListener(new DebounceDocumentListener(() -> { |
|||
settings.setArtifactId(artifactIdField.getText().trim()); |
|||
}, 300)); |
|||
|
|||
versionField.getDocument().addDocumentListener(new DebounceDocumentListener(() -> { |
|||
settings.setVersion(versionField.getText().trim()); |
|||
}, 300)); |
|||
|
|||
javaVersionComboBox.addActionListener(e -> { |
|||
String selectedVersion = (String) javaVersionComboBox.getSelectedItem(); |
|||
if (isValidJavaVersion(selectedVersion)) { |
|||
settings.setJavaVersion(selectedVersion); |
|||
} else { |
|||
// 默认回退到 17
|
|||
settings.setJavaVersion("17"); |
|||
// 确保在 EDT 中更新 UI
|
|||
UIUtil.invokeLaterIfNeeded(() -> { |
|||
javaVersionComboBox.setSelectedItem("17"); |
|||
JOptionPane.showMessageDialog(mainPanel, |
|||
"不支持的 Java 版本:" + selectedVersion + ",已自动切换为 Java 17。", |
|||
"警告", |
|||
JOptionPane.WARNING_MESSAGE); |
|||
}); |
|||
} |
|||
}); |
|||
|
|||
modulesField.getDocument().addDocumentListener(new DebounceDocumentListener(this::updateModules, 300)); |
|||
|
|||
// 模块变更监听器
|
|||
ItemListener moduleListener = e -> updateModules(); |
|||
apiCheckBox.addItemListener(moduleListener); |
|||
commonCheckBox.addItemListener(moduleListener); |
|||
mapperCheckBox.addItemListener(moduleListener); |
|||
pojoCheckBox.addItemListener(moduleListener); |
|||
serviceCheckBox.addItemListener(moduleListener); |
|||
} |
|||
|
|||
// 新增辅助方法
|
|||
private boolean isValidJavaVersion(String version) { |
|||
return Arrays.asList("8", "11", "17", "21").contains(version); |
|||
} |
|||
|
|||
private void initValues() { |
|||
groupIdField.setText(settings.getGroupId()); |
|||
artifactIdField.setText(settings.getArtifactId()); |
|||
versionField.setText(settings.getVersion()); |
|||
javaVersionComboBox.setSelectedItem(settings.getJavaVersion()); |
|||
|
|||
// 设置模块选择状态
|
|||
String[] modules = settings.getModules(); |
|||
for (String module : modules) { |
|||
switch (module) { |
|||
case "api": |
|||
apiCheckBox.setSelected(true); |
|||
break; |
|||
case "common": |
|||
commonCheckBox.setSelected(true); |
|||
break; |
|||
case "mapper": |
|||
mapperCheckBox.setSelected(true); |
|||
break; |
|||
case "pojo": |
|||
pojoCheckBox.setSelected(true); |
|||
break; |
|||
case "service": |
|||
serviceCheckBox.setSelected(true); |
|||
break; |
|||
default: |
|||
// 自定义模块,添加到文本框
|
|||
if (modulesField.getText().isEmpty()) { |
|||
modulesField.setText(module); |
|||
} else { |
|||
modulesField.setText(modulesField.getText() + ", " + module); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
private void updateModules() { |
|||
List<String> modulesList = new ArrayList<>(); |
|||
|
|||
// 添加选中的预定义模块
|
|||
if (apiCheckBox.isSelected()) modulesList.add("api"); |
|||
if (commonCheckBox.isSelected()) modulesList.add("common"); |
|||
if (mapperCheckBox.isSelected()) modulesList.add("mapper"); |
|||
if (pojoCheckBox.isSelected()) modulesList.add("pojo"); |
|||
if (serviceCheckBox.isSelected()) modulesList.add("service"); |
|||
|
|||
// 添加自定义模块
|
|||
String customModules = modulesField.getText().trim(); |
|||
if (!customModules.isEmpty()) { |
|||
modulesList.addAll(Arrays.asList(customModules.split("\\s*,\\s*"))); |
|||
} |
|||
|
|||
settings.setModules(modulesList.toArray(new String[0])); |
|||
} |
|||
|
|||
public JPanel getPanel() { |
|||
return mainPanel; |
|||
} |
|||
} |
|||
@ -0,0 +1,42 @@ |
|||
package com.wd.maven.aggregation; |
|||
|
|||
import com.intellij.openapi.actionSystem.AnAction; |
|||
import com.intellij.openapi.actionSystem.AnActionEvent; |
|||
import com.intellij.openapi.project.Project; |
|||
import com.intellij.openapi.project.ProjectUtil; |
|||
import com.intellij.openapi.ui.Messages; |
|||
import com.intellij.openapi.vfs.VirtualFile; |
|||
|
|||
public class QuickstartAggregationAction extends AnAction { |
|||
|
|||
@Override |
|||
public void actionPerformed(AnActionEvent e) { |
|||
Project project = e.getProject(); |
|||
if (project == null) return; |
|||
|
|||
// 创建对话框
|
|||
AggregationProjectDialog dialog = new AggregationProjectDialog(project); |
|||
if (dialog.showAndGet()) { |
|||
// 用户点击了确定
|
|||
String groupId = dialog.getGroupId(); |
|||
String artifactId = dialog.getArtifactId(); |
|||
String version = dialog.getVersion(); |
|||
String[] modules = dialog.getModules(); |
|||
String javaVersion = dialog.getJavaVersion(); |
|||
|
|||
// 生成项目
|
|||
AggregationProjectGenerator generator = new AggregationProjectGenerator(); |
|||
generator.generateProject(project, groupId, artifactId, version, modules, javaVersion); |
|||
|
|||
// 刷新项目视图
|
|||
refreshProjectView(project); |
|||
} |
|||
} |
|||
|
|||
private void refreshProjectView(Project project) { |
|||
VirtualFile baseDir = ProjectUtil.guessProjectDir(project); |
|||
if (baseDir != null) { |
|||
baseDir.refresh(false, true); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
package com.wd.maven.aggregation; |
|||
|
|||
import javax.swing.event.DocumentEvent; |
|||
import javax.swing.event.DocumentListener; |
|||
|
|||
public class SimpleDocumentListener implements DocumentListener { |
|||
private final Runnable action; |
|||
|
|||
public SimpleDocumentListener(Runnable action) { |
|||
this.action = action; |
|||
} |
|||
|
|||
@Override |
|||
public void insertUpdate(DocumentEvent e) { |
|||
action.run(); |
|||
} |
|||
|
|||
@Override |
|||
public void removeUpdate(DocumentEvent e) { |
|||
action.run(); |
|||
} |
|||
|
|||
@Override |
|||
public void changedUpdate(DocumentEvent e) { |
|||
action.run(); |
|||
} |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
<!-- Plugin Configuration File. Read more: https://plugins.jetbrains.com/docs/intellij/plugin-configuration-file.html --> |
|||
<idea-plugin> |
|||
<!-- Unique identifier of the plugin. It should be FQN. It cannot be changed between the plugin versions. --> |
|||
<id>com.wd.maven-aggregation</id> |
|||
|
|||
<!-- Public plugin name should be written in Title Case. |
|||
Guidelines: https://plugins.jetbrains.com/docs/marketplace/plugin-overview-page.html#plugin-name --> |
|||
<name>Maven-aggregation Quickstart</name> |
|||
|
|||
<!-- A displayed Vendor name or Organization ID displayed on the Plugins Page. --> |
|||
<vendor email="1938023944@qq.com" url="https://www.wandong.com">wandong</vendor> |
|||
|
|||
<!-- Description of the plugin displayed on the Plugin Page and IDE Plugin Manager. |
|||
Simple HTML elements (text formatting, paragraphs, and lists) can be added inside of <![CDATA[ ]]> tag. |
|||
Guidelines: https://plugins.jetbrains.com/docs/marketplace/plugin-overview-page.html#plugin-description --> |
|||
<description><![CDATA[ |
|||
<p>Maven聚合项目快速生成插件,帮助您快速创建标准的多模块Maven项目结构。</p> |
|||
|
|||
<p><b>主要功能:</b></p> |
|||
<ul> |
|||
<li>一键创建Maven多模块项目结构</li> |
|||
<li>自动配置模块间的依赖关系</li> |
|||
<li>支持自定义模块名称</li> |
|||
<li>支持选择Java版本</li> |
|||
<li>自动生成项目README和.gitignore文件</li> |
|||
</ul> |
|||
|
|||
<p><b>使用方法:</b></p> |
|||
<p>在IDEA中,选择"File > New > Create Maven Aggregation Project",然后按照向导完成配置。</p> |
|||
]]></description> |
|||
|
|||
<!-- Product and plugin compatibility requirements. |
|||
Read more: https://plugins.jetbrains.com/docs/intellij/plugin-compatibility.html --> |
|||
<depends>com.intellij.modules.platform</depends> |
|||
|
|||
|
|||
<!-- Extension points defined by the plugin. |
|||
Read more: https://plugins.jetbrains.com/docs/intellij/plugin-extension-points.html --> |
|||
<extensions defaultExtensionNs="com.intellij"> |
|||
</extensions> |
|||
|
|||
<actions> |
|||
<action id="QuickstartAggregationAction" class="com.wd.maven.aggregation.QuickstartAggregationAction" |
|||
text="Create Maven Aggregation Project" description="Creates a new Maven multi-module project template"> |
|||
<!-- <add-to-group group-id="NewGroup" anchor="first"/>--> |
|||
<!-- <add-to-group group-id="NewProjectOrModuleGroup" anchor="first"/>--> |
|||
<add-to-group group-id="NewGroup" anchor="first"/> |
|||
</action> |
|||
</actions> |
|||
|
|||
|
|||
</idea-plugin> |
|||
|
After Width: | Height: | Size: 818 B |
Loading…
Reference in new issue