diff --git a/athena-all/.gitignore b/athena-all/.gitignore new file mode 100644 index 000000000..7b64ac84d --- /dev/null +++ b/athena-all/.gitignore @@ -0,0 +1,45 @@ +.idea +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ +.idea +### 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 + +.run \ No newline at end of file diff --git a/athena-all/README.md b/athena-all/README.md new file mode 100644 index 000000000..8c6c2713e --- /dev/null +++ b/athena-all/README.md @@ -0,0 +1,21 @@ ++ jdk version:jdk17 ++ 2023年12月25日 + + 1.代码注释 comment_side_car + + 2.代码建议 code_suggest_sidecar + + 给方法添加注释 comment_2 + + 2.生成代码 biz_sidecar + + 分析代码范围 analysis_scope + + 3.屏蔽一些功能+部署到外网 + + 4.单元测试 + + 5.查找bug ++ 2023年12月26日 + + 搭一个外网版本 ++ 2023年12月27日 + + 简化ide中生成代码的流程 ++ 2024年01月01日 + + 尽量不再使用静态方法,而是使用ioc和aop + ++ 最后的版本这是效能组所有中间件+效能工具+平台的决策大脑(给用户测的) ++ 方法重命名 rename_method ++ translation 选中翻译 ++ suggest_sidecar 方法review(建议) \ No newline at end of file diff --git a/athena-all/build.gradle.kts b/athena-all/build.gradle.kts new file mode 100644 index 000000000..ceaf8e9ee --- /dev/null +++ b/athena-all/build.gradle.kts @@ -0,0 +1,78 @@ +plugins { + id("java") + id("org.jetbrains.kotlin.jvm") version "1.7.20" + id("org.jetbrains.intellij") version "1.14.0" +} + +group = "run.mone" +version = "2024.01.16.1" + + +repositories { + mavenLocal() + mavenCentral() +} + + +// Configure Gradle IntelliJ Plugin +// Read more: https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html +intellij { + version.set("2023.1.2") + type.set("IC") // Target IDE Platform + plugins.set(listOf("com.intellij.java"/* Plugin Dependencies */)) +} + +tasks { + // Set the JVM compatibility versions + withType { + sourceCompatibility = "17" + targetCompatibility = "17" + } + withType { + kotlinOptions.jvmTarget = "17" + } + + patchPluginXml { + sinceBuild.set("222") + untilBuild.set("300.*") + } + 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")) + } + + initializeIntelliJPlugin { + //不关闭,在有的网络下,会特别慢 + selfUpdateCheck.set(false) + } +} + +dependencies { + implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) + implementation("com.ibeetl:beetl:3.15.4.RELEASE") + implementation("org.antlr:antlr4-runtime:4.7.2") + implementation("io.netty:netty-all:4.1.36.Final") + implementation("com.google.code.gson:gson:2.8.9") + implementation("run.mone:openai:1.4-SNAPSHOT") + implementation("com.google.guava:guava:32.0.1-jre") + implementation("com.squareup.okhttp3:okhttp:4.11.0") + implementation("com.squareup.okhttp3:okhttp-sse:4.11.0") + implementation("org.apache.commons:commons-lang3:3.13.0") + implementation("com.github.javaparser:javaparser-core:3.25.6") + + implementation("org.nutz:nutz:1.r.69.20210929") + implementation("mysql:mysql-connector-java:8.0.28") + implementation("org.apache.commons:commons-lang3:3.14.0") + + compileOnly("org.projectlombok:lombok:1.18.26") + annotationProcessor("org.projectlombok:lombok:1.18.26") + + testCompileOnly("org.projectlombok:lombok:1.18.26") + testAnnotationProcessor("org.projectlombok:lombok:1.18.26") + +} \ No newline at end of file diff --git a/athena-all/gradle.properties b/athena-all/gradle.properties new file mode 100644 index 000000000..ecb06786e --- /dev/null +++ b/athena-all/gradle.properties @@ -0,0 +1 @@ +kotlin.stdlib.default.dependency = false \ No newline at end of file diff --git a/athena-all/gradle/wrapper/gradle-wrapper.jar b/athena-all/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..249e5832f Binary files /dev/null and b/athena-all/gradle/wrapper/gradle-wrapper.jar differ diff --git a/athena-all/gradle/wrapper/gradle-wrapper.properties b/athena-all/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..070cb702f --- /dev/null +++ b/athena-all/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/athena-all/gradlew b/athena-all/gradlew new file mode 100755 index 000000000..1b6c78733 --- /dev/null +++ b/athena-all/gradlew @@ -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" "$@" diff --git a/athena-all/gradlew.bat b/athena-all/gradlew.bat new file mode 100644 index 000000000..107acd32c --- /dev/null +++ b/athena-all/gradlew.bat @@ -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 diff --git a/athena-all/settings.gradle.kts b/athena-all/settings.gradle.kts new file mode 100644 index 000000000..18387ae48 --- /dev/null +++ b/athena-all/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "Athena" \ No newline at end of file diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/ActionChain.java b/athena-all/src/main/java/run/mone/m78/ip/action/ActionChain.java new file mode 100644 index 000000000..045dfff3b --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/action/ActionChain.java @@ -0,0 +1,57 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.action; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import run.mone.m78.ip.common.Context; +import run.mone.m78.ip.service.*; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/7 21:00 + */ +public class ActionChain { + + + private AbstractService testService; + + public void init() { + testService = new TestService(); + + ChatGptService chatGptService = new ChatGptService(); + testService.setNext(chatGptService); + + CodeService codeService = new CodeService(); + chatGptService.setNext(codeService); + + MusicService musicService = MusicService.ins(); + codeService.setNext(musicService); + + ImageService imageService = new ImageService(); + musicService.setNext(imageService); + + UserService userService = new UserService(); + imageService.setNext(userService); + + } + + + public void execute(Context context, AnActionEvent e) { + testService.execute(context, e); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/ActionEnum.java b/athena-all/src/main/java/run/mone/m78/ip/action/ActionEnum.java new file mode 100644 index 000000000..0d41861da --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/action/ActionEnum.java @@ -0,0 +1,16 @@ +package run.mone.m78.ip.action; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/2 11:25 + */ +public enum ActionEnum { + + zero,//image + diga,//music + diga_stop, + background, + code_upload, + code_download, + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/AthenaAction.java b/athena-all/src/main/java/run/mone/m78/ip/action/AthenaAction.java new file mode 100644 index 000000000..c49b35b7c --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/action/AthenaAction.java @@ -0,0 +1,65 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.action; + +import com.intellij.ide.util.PropertiesComponent; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.wm.impl.IdeBackgroundUtil; +import run.mone.m78.ip.common.ApiCall; +import run.mone.m78.ip.common.Context; +import run.mone.m78.ip.common.NotificationCenter; +import run.mone.m78.ip.util.EditorUtils; +import org.jetbrains.annotations.NotNull; + +/** + * @author goodjava@qq.com + */ +public class AthenaAction extends AnAction { + + private static final Logger log = Logger.getInstance(AthenaAction.class); + + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + String content = getText(e); + log.info("Ultraman req:" + content); + ActionChain chain = new ActionChain(); + chain.init(); + Context context = new Context(); + context.setContent(content); + chain.execute(context, e); + if (content.equals(ActionEnum.background.name())) { + NotificationCenter.notice("background"); + log.info("background"); + String image = new ApiCall().callOne(ApiCall.IMAGE_API); + PropertiesComponent prop = PropertiesComponent.getInstance(); + prop.setValue(IdeBackgroundUtil.FRAME_PROP, null); + prop.setValue(IdeBackgroundUtil.EDITOR_PROP, image); + IdeBackgroundUtil.repaintAllWindows(); + return; + } + } + + private String getText(AnActionEvent anActionEvent) { + Editor editor = anActionEvent.getData(PlatformDataKeys.EDITOR); + return EditorUtils.getSelectContent(editor); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/ChatAction.java b/athena-all/src/main/java/run/mone/m78/ip/action/ChatAction.java new file mode 100644 index 000000000..779ab8181 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/action/ChatAction.java @@ -0,0 +1,37 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.action; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; +import run.mone.m78.ip.component.ChatComponent; +import org.jetbrains.annotations.NotNull; + +/** + * @author goodjava@qq.com + */ +public class ChatAction extends AnAction { + + @Override + public void actionPerformed(@NotNull AnActionEvent anActionEvent) { + Application application = ApplicationManager.getApplication(); + ChatComponent component= application.getComponent(ChatComponent.class); + component.show(anActionEvent.getProject(),anActionEvent); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/CommonAction.java b/athena-all/src/main/java/run/mone/m78/ip/action/CommonAction.java new file mode 100644 index 000000000..c930fdbab --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/action/CommonAction.java @@ -0,0 +1,43 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.action; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; + +/** + * @author goodjava@qq.com + */ +public class CommonAction extends AnAction { + + + + @Override + public void actionPerformed(@NotNull AnActionEvent anActionEvent) { + Project project = anActionEvent.getData(PlatformDataKeys.PROJECT); + String projectName = project.getName(); + String basePath = project.getBasePath(); +// Messages.showMessageDialog(project, projectName + ":" + basePath, "", Messages.getInformationIcon()); + String title = "title"; + String content = "content"; + + + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/CreateFilterAction.java b/athena-all/src/main/java/run/mone/m78/ip/action/CreateFilterAction.java new file mode 100644 index 000000000..b25d89ec5 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/action/CreateFilterAction.java @@ -0,0 +1,34 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.action; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; +import run.mone.m78.ip.component.FilterComponent; +import org.jetbrains.annotations.NotNull; + +public class CreateFilterAction extends AnAction { + + @Override + public void actionPerformed(@NotNull AnActionEvent anActionEvent) { + Application application = ApplicationManager.getApplication(); + FilterComponent myComponent = application.getComponent(FilterComponent.class); + myComponent.show(anActionEvent.getProject()); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/CreateProjectAction.java b/athena-all/src/main/java/run/mone/m78/ip/action/CreateProjectAction.java new file mode 100644 index 000000000..3dbf2518f --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/action/CreateProjectAction.java @@ -0,0 +1,37 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.action; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; +import run.mone.m78.ip.component.CreateProjectComponent; +import org.jetbrains.annotations.NotNull; + +/** + * @author goodjava@qq.com + */ +public class CreateProjectAction extends AnAction { + + @Override + public void actionPerformed(@NotNull AnActionEvent anActionEvent) { + Application application = ApplicationManager.getApplication(); + CreateProjectComponent myComponent = application.getComponent(CreateProjectComponent.class); + myComponent.show(anActionEvent.getProject()); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/CreateSprintBootProjectAction.java b/athena-all/src/main/java/run/mone/m78/ip/action/CreateSprintBootProjectAction.java new file mode 100644 index 000000000..bdaae8bac --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/action/CreateSprintBootProjectAction.java @@ -0,0 +1,37 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.action; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; +import run.mone.m78.ip.component.CreateSpringBootProjectComponent; +import org.jetbrains.annotations.NotNull; + +/** + * @author goodjava@qq.com + */ +public class CreateSprintBootProjectAction extends AnAction { + + @Override + public void actionPerformed(@NotNull AnActionEvent anActionEvent) { + Application application = ApplicationManager.getApplication(); + CreateSpringBootProjectComponent myComponent = application.getComponent(CreateSpringBootProjectComponent.class); + myComponent.show(anActionEvent.getProject()); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/DynamicAction.java b/athena-all/src/main/java/run/mone/m78/ip/action/DynamicAction.java new file mode 100644 index 000000000..283b13576 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/action/DynamicAction.java @@ -0,0 +1,45 @@ +package run.mone.m78.ip.action; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; +import run.mone.m78.ip.bo.GenerateCodeReq; +import run.mone.m78.ip.common.PromptType; +import run.mone.m78.ip.service.PromptService; +import run.mone.m78.ip.bo.PromptInfo; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author goodjava@qq.com + * @date 2023/5/27 09:24 + */ +public class DynamicAction extends AnAction implements DumbAware { + + + private final String myText; + + private PromptType type; + + private PromptInfo promptInfo; + + + public DynamicAction(String text, PromptType type, PromptInfo promptInfo) { + super(text); + myText = text; + this.type = type; + this.promptInfo = promptInfo; + } + + @Override + public void actionPerformed(@NotNull AnActionEvent event) { + @Nullable Project project = event.getProject(); + @Nullable Module module = LangDataKeys.MODULE.getData(event.getDataContext()); + PromptService.dynamicInvoke(GenerateCodeReq.builder().project(project).module(module).promptInfo(this.promptInfo).promptName(this.promptInfo.getPromptName()).promptType(type).build()); + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/DynamicActionGroup.java b/athena-all/src/main/java/run/mone/m78/ip/action/DynamicActionGroup.java new file mode 100644 index 000000000..a3fdb2ca7 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/action/DynamicActionGroup.java @@ -0,0 +1,27 @@ +package run.mone.m78.ip.action; + +import com.intellij.openapi.actionSystem.ActionGroup; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import run.mone.m78.ip.common.Prompt; +import run.mone.m78.ip.bo.PromptInfo; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/5/27 09:23 + */ +public class DynamicActionGroup extends ActionGroup { + + @Override + public AnAction @NotNull [] getChildren(@Nullable AnActionEvent event) { + List actions = new ArrayList<>(); + List list = Prompt.promptList("plugin"); + list.stream().forEach(it -> actions.add(new DynamicAction(it.getDesc(), Prompt.getPromptType(it), it))); + return actions.toArray(new AnAction[0]); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/GenerateAction.java b/athena-all/src/main/java/run/mone/m78/ip/action/GenerateAction.java new file mode 100644 index 000000000..519255ab6 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/action/GenerateAction.java @@ -0,0 +1,81 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.action; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +//import com.intellij.openapi.actionSystem.DataKeys; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +/** + * @author goodjava@qq.com + * 生成代码 + */ +public class GenerateAction extends AnAction { + + /** + * 刷新项目 + */ + private void refreshProject(AnActionEvent event) { + event.getProject().getBaseDir().refresh(false, true); + } + + + private void build(String filePath, String fileName) { + File floder = new File(filePath); + if (!floder.exists()) { + floder.mkdirs(); + } + + File file = new File(filePath + "/" + fileName); + if (file.exists()) { + return; + } + + try { + Files.write(Paths.get(filePath + File.separator + fileName), "".getBytes()); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + @Override + public void actionPerformed(@NotNull AnActionEvent event) { + + String projectBasePath = event.getProject().getBasePath(); + + build(projectBasePath+File.separator+"a","init.data"); + build(projectBasePath+File.separator+"b","init.data"); + + +// VirtualFile file = DataKeys.VIRTUAL_FILE.getData(event.getDataContext()); + VirtualFile file = null; + String filePath = file.getPath(); + + + build(filePath, "zzy.java"); + + refreshProject(event); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/MenuAction.java b/athena-all/src/main/java/run/mone/m78/ip/action/MenuAction.java new file mode 100644 index 000000000..f078b8f15 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/action/MenuAction.java @@ -0,0 +1,32 @@ +package run.mone.m78.ip.action; + +import com.intellij.openapi.actionSystem.ActionGroup; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import run.mone.m78.ip.common.Prompt; +import run.mone.m78.ip.bo.PromptInfo; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author caobaoyu + * @description: + * @date 2023-06-14 14:50 + */ +public class MenuAction extends ActionGroup { + + private List promptInfoList; + + public MenuAction(String text, List promptInfos) { + super(text, true); + this.promptInfoList = promptInfos; + } + + @Override + public AnAction @NotNull [] getChildren(@Nullable AnActionEvent e) { + return new AnAction[]{}; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/MenuActionGroup.java b/athena-all/src/main/java/run/mone/m78/ip/action/MenuActionGroup.java new file mode 100644 index 000000000..0f1fa9db9 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/action/MenuActionGroup.java @@ -0,0 +1,37 @@ +package run.mone.m78.ip.action; + +import com.intellij.openapi.actionSystem.ActionGroup; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import run.mone.m78.ip.common.Prompt; +import run.mone.m78.ip.bo.PromptInfo; +import run.mone.m78.ip.common.Const; +import run.mone.m78.ip.util.LabelUtils; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +/** + * @author caobaoyu + * @author goodjava@qq.com + * @description: + * @date 2023-06-14 14:15 + */ +public class MenuActionGroup extends ActionGroup { + + public MenuActionGroup() { + super("Prompt", true); + } + + @Override + public AnAction @NotNull [] getChildren(AnActionEvent e) { + if (LabelUtils.getLabelValue(e.getProject(), Const.DISABLE_ACTION_GROUP, "false").equals("true")) { + return new AnAction[]{}; + } + List list = Prompt.getPromptInfoByTag(""); + list.addAll(Prompt.getCollected()); + return list.stream().map(it -> new DynamicAction(it.getDesc(), Prompt.getPromptType(it), it)).toArray(AnAction[]::new); + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/NaviAction.java b/athena-all/src/main/java/run/mone/m78/ip/action/NaviAction.java new file mode 100644 index 000000000..654325c43 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/action/NaviAction.java @@ -0,0 +1,37 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.action; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; +import run.mone.m78.ip.component.NaviComponent; +import org.jetbrains.annotations.NotNull; + +/** + * @author goodjava@qq.com + */ +public class NaviAction extends AnAction { + + @Override + public void actionPerformed(@NotNull AnActionEvent anActionEvent) { + Application application = ApplicationManager.getApplication(); + NaviComponent component= application.getComponent(NaviComponent.class); + component.show(anActionEvent.getProject()); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/PluginAction.java b/athena-all/src/main/java/run/mone/m78/ip/action/PluginAction.java new file mode 100644 index 000000000..d3487a43c --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/action/PluginAction.java @@ -0,0 +1,37 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.action; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; +import run.mone.m78.ip.component.PluginComponent; +import org.jetbrains.annotations.NotNull; + +/** + * @author goodjava@qq.com + */ +public class PluginAction extends AnAction { + + @Override + public void actionPerformed(@NotNull AnActionEvent anActionEvent) { + Application application = ApplicationManager.getApplication(); + PluginComponent component = application.getComponent(PluginComponent.class); + component.show(anActionEvent.getProject()); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/TestAction.java b/athena-all/src/main/java/run/mone/m78/ip/action/TestAction.java new file mode 100644 index 000000000..5048bfa2d --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/action/TestAction.java @@ -0,0 +1,52 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.action; + +import com.google.common.collect.Maps; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; +import run.mone.m78.ip.service.ScriptService; + +/** + * @author goodjava@qq.com + */ +public class TestAction extends AnAction { + + @Override + public void actionPerformed(AnActionEvent e) { + //获取当前在操作的工程上下文 + Project project = e.getData(PlatformDataKeys.PROJECT); + + //获取当前操作的类文件 + PsiFile psiFile = e.getData(CommonDataKeys.PSI_FILE); + //获取当前类文件的路径 + String classPath = ""; + if (null != psiFile) { + classPath = psiFile.getVirtualFile().getPath(); + } + String title = "Hello World!"; + //显示对话框 + //Messages.showMessageDialog(project, classPath, title, Messages.getInformationIcon()); + + ScriptService.ins().invoke("def sum() {return 1+2}","sum", Maps.newHashMap(), Maps.newHashMap()); + + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/UltramanAction.java b/athena-all/src/main/java/run/mone/m78/ip/action/UltramanAction.java new file mode 100644 index 000000000..483aab16b --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/action/UltramanAction.java @@ -0,0 +1,59 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.action; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.psi.PsiFile; + +/** + * @author goodjava@qq.com + */ +public class UltramanAction extends AnAction { + + + @Override + public void actionPerformed(AnActionEvent e) { + //获取当前操作的类文件 + PsiFile psiFile = e.getData(CommonDataKeys.PSI_FILE); + //获取当前类文件的路径 + String classPath = ""; + if (null != psiFile) { + classPath = psiFile.getVirtualFile().getPath(); + } + String title = ""; + + Editor editor = e.getData(PlatformDataKeys.EDITOR); + if (null != editor) { + Document document = editor.getDocument(); + if (null != document) { + Application applicationManager = ApplicationManager.getApplication(); + applicationManager.runWriteAction(() -> { + document.setText(title); + }); + + } + } + + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/AddMethodConfig.java b/athena-all/src/main/java/run/mone/m78/ip/bo/AddMethodConfig.java new file mode 100644 index 000000000..61bdbc5d0 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/AddMethodConfig.java @@ -0,0 +1,23 @@ +package run.mone.m78.ip.bo; + +import com.intellij.psi.PsiType; +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/6/14 15:08 + */ +@Data +@Builder +public class AddMethodConfig implements Serializable { + + private String name; + + private PsiType returnType; + + private boolean isInterface; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/AiCodePromptRes.java b/athena-all/src/main/java/run/mone/m78/ip/bo/AiCodePromptRes.java new file mode 100644 index 000000000..c3e1de3d7 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/AiCodePromptRes.java @@ -0,0 +1,26 @@ +package run.mone.m78.ip.bo; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author caobaoyu + * @description: + * @date 2023-06-06 11:15 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class AiCodePromptRes { + private String promptName; + private String desc; + private String meta; + private String type; + private String showDialog; + private String prefix = ""; + private String suffix = ""; + private String src; +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/AiCodeRes.java b/athena-all/src/main/java/run/mone/m78/ip/bo/AiCodeRes.java new file mode 100644 index 000000000..7c64059c0 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/AiCodeRes.java @@ -0,0 +1,27 @@ +package run.mone.m78.ip.bo; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +/** + * @author caobaoyu + * @description: + * @date 2023-05-30 14:25 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class AiCodeRes implements Serializable { + private String msg; + private Long tagId; + private String tagName; + private Boolean selected; + private List promptInfoList; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/AiMessage.java b/athena-all/src/main/java/run/mone/m78/ip/bo/AiMessage.java new file mode 100644 index 000000000..050435e5c --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/AiMessage.java @@ -0,0 +1,28 @@ +package run.mone.m78.ip.bo; + +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/6/9 14:32 + */ +@Data +@Builder +public class AiMessage implements Serializable { + + private AiMessageType type; + + private String id; + + private String text; + + private String projectName; + + //代表是否是编码(```code```) + @Builder.Default + private boolean code = true; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/AiMessageType.java b/athena-all/src/main/java/run/mone/m78/ip/bo/AiMessageType.java new file mode 100644 index 000000000..5ff0bcc3c --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/AiMessageType.java @@ -0,0 +1,14 @@ +package run.mone.m78.ip.bo; + +/** + * @author goodjava@qq.com + * @date 2023/6/9 14:33 + */ +public enum AiMessageType { + + begin, + process, + success, + failure, + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/AnnoInfo.java b/athena-all/src/main/java/run/mone/m78/ip/bo/AnnoInfo.java new file mode 100644 index 000000000..9cf904924 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/AnnoInfo.java @@ -0,0 +1,18 @@ +package run.mone.m78.ip.bo; + +import lombok.Data; + +import java.util.Map; + +/** + * @author goodjava@qq.com + * @date 2023/6/21 17:03 + */ +@Data +public class AnnoInfo { + + private String name; + + private Map members; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/AnnoMember.java b/athena-all/src/main/java/run/mone/m78/ip/bo/AnnoMember.java new file mode 100644 index 000000000..e1a02d7a5 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/AnnoMember.java @@ -0,0 +1,18 @@ +package run.mone.m78.ip.bo; + +import lombok.Builder; +import lombok.Data; + +/** + * @author goodjava@qq.com + * @date 2023/6/21 17:03 + */ +@Data +@Builder +public class AnnoMember { + + private String key; + + private String value; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/AthenaReq.java b/athena-all/src/main/java/run/mone/m78/ip/bo/AthenaReq.java new file mode 100644 index 000000000..be765e312 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/AthenaReq.java @@ -0,0 +1,34 @@ +package run.mone.m78.ip.bo; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author caobaoyu + * @description: + * @date 2023-06-07 14:18 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class AthenaReq { + + private String aiProxy; + + private String userName; + + private String zzToken; + + private String version; + + private String os; + + private String ideaVersion; + + private String time; + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/AudioRes.java b/athena-all/src/main/java/run/mone/m78/ip/bo/AudioRes.java new file mode 100644 index 000000000..abc345e40 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/AudioRes.java @@ -0,0 +1,14 @@ +package run.mone.m78.ip.bo; + +import lombok.Data; + +/** + * @author goodjava@qq.com + * @date 2023/11/23 11:54 + */ +@Data +public class AudioRes { + + private String text; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ClassInfo.java b/athena-all/src/main/java/run/mone/m78/ip/bo/ClassInfo.java new file mode 100644 index 000000000..1c16cee3b --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/ClassInfo.java @@ -0,0 +1,50 @@ +package run.mone.m78.ip.bo; + +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/6/19 14:11 + */ +@Data +@Builder +public class ClassInfo implements Serializable, PsiInfo { + + private String className; + + private String moduleName; + + private boolean hidden; + + + @Override + public String toString() { + if (null == moduleName) { + return className; + } + return className + " (" + moduleName + ")"; + } + + @Override + public String getName() { + return className; + } + + @Override + public void setName(String name) { + this.className = name; + } + + @Override + public boolean isHidden() { + return hidden; + } + + @Override + public void hidden(boolean hidden) { + this.hidden = hidden; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/CreateClassMeta.java b/athena-all/src/main/java/run/mone/m78/ip/bo/CreateClassMeta.java new file mode 100644 index 000000000..de39c8395 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/CreateClassMeta.java @@ -0,0 +1,16 @@ +package run.mone.m78.ip.bo; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/5/29 14:37 + */ +@Data +public class CreateClassMeta implements Serializable { + + private boolean useSelect; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/CreateClassRes.java b/athena-all/src/main/java/run/mone/m78/ip/bo/CreateClassRes.java new file mode 100644 index 000000000..0bd217344 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/CreateClassRes.java @@ -0,0 +1,22 @@ +package run.mone.m78.ip.bo; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/6/18 09:49 + */ +@Data +public class CreateClassRes implements Serializable { + + private String moduleName; + + private String packageStr; + + private String className; + + private int code; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/Dependency.java b/athena-all/src/main/java/run/mone/m78/ip/bo/Dependency.java new file mode 100644 index 000000000..2f1434d62 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/Dependency.java @@ -0,0 +1,19 @@ +package run.mone.m78.ip.bo; + +import lombok.Data; + +/** + * @author caobaoyu + * @description: + * @date 2023-06-09 09:52 + */ +@Data +public class Dependency { + + private String groupId; + + private String artifactId; + + private String version; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ElementInfo.java b/athena-all/src/main/java/run/mone/m78/ip/bo/ElementInfo.java new file mode 100644 index 000000000..7eeb9418b --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/ElementInfo.java @@ -0,0 +1,18 @@ +package run.mone.m78.ip.bo; + +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/5/29 13:05 + */ +@Data +@Builder +public class ElementInfo implements Serializable { + + private String name; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/FieldInfo.java b/athena-all/src/main/java/run/mone/m78/ip/bo/FieldInfo.java new file mode 100644 index 000000000..76d9c10b4 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/FieldInfo.java @@ -0,0 +1,24 @@ +package run.mone.m78.ip.bo; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * @author goodjava@qq.com + * @date 2023/6/21 16:26 + */ +@Data +public class FieldInfo implements Serializable { + + private String name; + + private String classType; + + private Map meta; + + private List annoList; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/GenerateCodeReq.java b/athena-all/src/main/java/run/mone/m78/ip/bo/GenerateCodeReq.java new file mode 100644 index 000000000..7111cfaad --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/GenerateCodeReq.java @@ -0,0 +1,111 @@ +package run.mone.m78.ip.bo; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import run.mone.m78.ip.common.PromptType; +import lombok.Builder; +import lombok.Data; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.CountDownLatch; + +/** + * @author caobaoyu + * @author zhangzhiyong + * @description: + * @date 2023-05-17 16:53 + * + * 主要用来生成代码 + */ +@Data +@Builder +public class GenerateCodeReq { + + private String projectName; + + private String model; + + private String promptName; + + private String fileName; + + private String meta; + + private Project project; + + private Editor editor; + + private Module module; + + private String moduleName; + + //所有module的列表 + private List moduleNameList; + + private String type; + + private PromptType promptType; + + private PromptInfo promptInfo; + + private String showDialog; + + private Map param; + + /** + * 格式化代码 + */ + @Builder.Default + private boolean format = true; + + private String comment; + + private String chatComment; + + /** + * method + * class + * module + * project + */ + private String scope; + + private String context; + + private CountDownLatch latch; + + //这个文件的内容 + private String virtualFileText; + + //class相关代码 + private String classCode; + + private String qualifiedName; + + private String className; + + private String classPackage; + + + private String classCode2; + + //选中的方法code(鼠标停留的位置) + private String methodCode; + + //选中的内容 + private String selectText; + + //操作系统名称 + private String systemName; + + private String ideaVersion; + + private String pluginVersion; + + @Builder.Default + private String taskType = "edit"; + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/IdeaPluginInfoBo.java b/athena-all/src/main/java/run/mone/m78/ip/bo/IdeaPluginInfoBo.java new file mode 100644 index 000000000..99061caa0 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/IdeaPluginInfoBo.java @@ -0,0 +1,116 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.bo; + +/** + * @author goodjava@qq.com + * users + */ +public class IdeaPluginInfoBo { + + private int id; + + private String name; + + + private int dataId; + + private long ctime; + + private long utime; + + private int status; + + private String creator; + + private String desc; + + private String url; + + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getDataId() { + return dataId; + } + + public void setDataId(int dataId) { + this.dataId = dataId; + } + + public long getCtime() { + return ctime; + } + + public void setCtime(long ctime) { + this.ctime = ctime; + } + + public long getUtime() { + return utime; + } + + public void setUtime(long utime) { + this.utime = utime; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public String getCreator() { + return creator; + } + + public void setCreator(String creator) { + this.creator = creator; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/LombokTest.java b/athena-all/src/main/java/run/mone/m78/ip/bo/LombokTest.java new file mode 100644 index 000000000..c6591f5c5 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/LombokTest.java @@ -0,0 +1,10 @@ +package run.mone.m78.ip.bo; + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class LombokTest implements Serializable { + private String data; +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/Message.java b/athena-all/src/main/java/run/mone/m78/ip/bo/Message.java new file mode 100644 index 000000000..52d2ce9ef --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/Message.java @@ -0,0 +1,29 @@ +package run.mone.m78.ip.bo; + +/** + * @author goodjava@qq.com + * @date 2023/6/5 15:07 + */ +public interface Message { + + String selectMethodMsg = "Please select a method first"; + + String selectClassMsg = "Please select a class first"; + + String finishMsg = "Execution finished"; + + String cannotFindTestDirectory = "Cannot find the test directory"; + + String unsupportedCommand = "Unsupported command"; + + String initFinishMsg = "prompt init finished"; + + String selectPackage = "Please select the package path in the project tree on the left"; + + String selectTextMsg = "Please select a block of text in the Editor first"; + + String selectTextFile = "Please select a text file"; + + String suggestion = "Athena(方法修改建议)"; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/MessageConsumer.java b/athena-all/src/main/java/run/mone/m78/ip/bo/MessageConsumer.java new file mode 100644 index 000000000..1797467fa --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/MessageConsumer.java @@ -0,0 +1,26 @@ +package run.mone.m78.ip.bo; + +/** + * @author goodjava@qq.com + * @date 2023/6/11 12:20 + */ +public class MessageConsumer { + + public void begin(AiMessage message) { + + } + + public void onEvent(AiMessage message) { + + } + + + public void end(AiMessage message) { + + } + + public void failure(AiMessage message) { + + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/MethodInfo.java b/athena-all/src/main/java/run/mone/m78/ip/bo/MethodInfo.java new file mode 100644 index 000000000..19068e47d --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/MethodInfo.java @@ -0,0 +1,43 @@ +package run.mone.m78.ip.bo; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/6/19 14:19 + */ +public class MethodInfo implements PsiInfo, Serializable { + + private boolean hidden; + + private String name; + + public MethodInfo(String name) { + this.name = name; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public void setName(String name) { + this.name = name; + } + + @Override + public boolean isHidden() { + return this.hidden; + } + + @Override + public void hidden(boolean hidden) { + this.hidden = hidden; + } + + @Override + public String toString() { + return this.name; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ModelRes.java b/athena-all/src/main/java/run/mone/m78/ip/bo/ModelRes.java new file mode 100644 index 000000000..78d05d655 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/ModelRes.java @@ -0,0 +1,30 @@ +package run.mone.m78.ip.bo; + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class ModelRes implements Serializable { + + String name; + String value; + Boolean vip; // Nullable + Long points; // Nullable, User points in z platform + + + int maxToken; + int moduleClassNum; + boolean supportJsonResponse; + boolean optimizeTokens; + + + + public ModelRes(String name, String value) { + this.name = name; + this.value = value; + } + + public ModelRes() { + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ModuleInfo.java b/athena-all/src/main/java/run/mone/m78/ip/bo/ModuleInfo.java new file mode 100644 index 000000000..dd9b80fd0 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/ModuleInfo.java @@ -0,0 +1,40 @@ +package run.mone.m78.ip.bo; + +import lombok.Builder; + +/** + * @author goodjava@qq.com + * @date 2023/6/19 21:50 + */ +@Builder +public class ModuleInfo implements PsiInfo{ + + private String name; + + private boolean hidden;; + + @Override + public String getName() { + return name; + } + + @Override + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return this.name; + } + + @Override + public boolean isHidden() { + return this.hidden; + } + + @Override + public void hidden(boolean hidden) { + this.hidden = hidden; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/Msg.java b/athena-all/src/main/java/run/mone/m78/ip/bo/Msg.java new file mode 100644 index 000000000..8c3f5e735 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/Msg.java @@ -0,0 +1,18 @@ +package run.mone.m78.ip.bo; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/5/31 10:29 + */ +@Data +public class Msg implements Serializable { + + private String role; + + private String content; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ParamDialogReq.java b/athena-all/src/main/java/run/mone/m78/ip/bo/ParamDialogReq.java new file mode 100644 index 000000000..eae8cb370 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/ParamDialogReq.java @@ -0,0 +1,19 @@ +package run.mone.m78.ip.bo; + +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/6/29 14:51 + */ +@Data +@Builder +public class ParamDialogReq implements Serializable { + + private String title; + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ParamInfo.java b/athena-all/src/main/java/run/mone/m78/ip/bo/ParamInfo.java new file mode 100644 index 000000000..92430e8c1 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/ParamInfo.java @@ -0,0 +1,23 @@ +package run.mone.m78.ip.bo; + +import com.intellij.psi.PsiType; +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/6/14 09:24 + */ +@Data +@Builder +public class ParamInfo implements Serializable { + + private String name; + + private String type; + + private PsiType psiType; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/PluginDeleteParam.java b/athena-all/src/main/java/run/mone/m78/ip/bo/PluginDeleteParam.java new file mode 100644 index 000000000..a08d374ee --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/PluginDeleteParam.java @@ -0,0 +1,95 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.bo; + +import java.util.List; + +/** + * @author goodjava@qq.com + */ +public class PluginDeleteParam { + private Integer id; + private String name; + private String version; + private String token; + private String userName; + + + private List groupList; + + /** + * 服务器列表 + */ + private List addressList; + + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public List getGroupList() { + return groupList; + } + + public void setGroupList(List groupList) { + this.groupList = groupList; + } + + public List getAddressList() { + return addressList; + } + + public void setAddressList(List addressList) { + this.addressList = addressList; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ProjectModuleInfo.java b/athena-all/src/main/java/run/mone/m78/ip/bo/ProjectModuleInfo.java new file mode 100644 index 000000000..0d6118d84 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/ProjectModuleInfo.java @@ -0,0 +1,18 @@ +package run.mone.m78.ip.bo; + +import lombok.Builder; +import lombok.Data; + +/** + * @author caobaoyu + * @description: + * @date 2023-05-30 16:22 + */ +@Data +public class ProjectModuleInfo { + + private String projectName; + + private String moduleName; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/PromptContext.java b/athena-all/src/main/java/run/mone/m78/ip/bo/PromptContext.java new file mode 100644 index 000000000..5e2b7c875 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/PromptContext.java @@ -0,0 +1,43 @@ +package run.mone.m78.ip.bo; + +import com.intellij.openapi.editor.Editor; +import lombok.Data; +import run.mone.ultraman.bo.AthenaFieldInfo; +import run.mone.ultraman.bo.AthenaMethodInfo; + +import java.io.Serializable; +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/5/13 09:36 + */ +@Data +public class PromptContext implements Serializable { + + private String project; + + private String module; + + private String className; + + private String methodName; + + private String scope; + + private String comment; + + private List resourceCode; + + private List methodCodeList; + + private List fieldCodeList; + + private String clazzName; + + private List resourceBeanList; + + private Editor editor; + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/PromptInfo.java b/athena-all/src/main/java/run/mone/m78/ip/bo/PromptInfo.java new file mode 100644 index 000000000..d99b9137b --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/PromptInfo.java @@ -0,0 +1,63 @@ +package run.mone.m78.ip.bo; + +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * @author caobaoyu + * @description: + * @date 2023-05-17 18:33 + */ +@Data +@Builder +public class PromptInfo implements Serializable { + + private Long id; + + private String promptName; + + private String meta; + + private String desc; + + private boolean collected; + + private int usedTimes; + + private List tags; + + private Map labels; + + private Map userLabels; + + private String data; + + private Integer collectedSort; + + private List addon; + + private List addon_metas; + + public boolean open(String key) { + return this.labels.getOrDefault(key, "false").equals("true"); + } + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof PromptInfo that)) return false; + + return Objects.equals(promptName, that.promptName); + } + + @Override + public int hashCode() { + return promptName != null ? promptName.hashCode() : 0; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ProxyAsk.java b/athena-all/src/main/java/run/mone/m78/ip/bo/ProxyAsk.java new file mode 100644 index 000000000..462581438 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/ProxyAsk.java @@ -0,0 +1,52 @@ +package run.mone.m78.ip.bo; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * @author goodjava@qq.com + * @date 2023/5/25 16:27 + */ +@Data +public class ProxyAsk implements Serializable { + + private String id; + + private String token; + + private String zzToken; + + private String promptName; + + private String[] params; + + private Map paramMap; + + private boolean skipSystemSetting; + + private String model; + + private int maxToken; + + /** + * 是否开启测试模式 + */ + private boolean debug; + + private List msgList; + + /** + * 0 是单条的,并且传过来是promptName + * 1 多条,就是正常的多轮问答 + */ + private int type; + + /** + * 来源 + */ + private String from; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/PsiInfo.java b/athena-all/src/main/java/run/mone/m78/ip/bo/PsiInfo.java new file mode 100644 index 000000000..fb1d621e9 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/PsiInfo.java @@ -0,0 +1,17 @@ +package run.mone.m78.ip.bo; + +/** + * @author goodjava@qq.com + * @date 2023/6/19 14:19 + */ +public interface PsiInfo { + + String getName(); + + void setName(String name); + + boolean isHidden(); + + void hidden(boolean hidden); + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/Req.java b/athena-all/src/main/java/run/mone/m78/ip/bo/Req.java new file mode 100644 index 000000000..2fbcd8824 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/Req.java @@ -0,0 +1,22 @@ +package run.mone.m78.ip.bo; + +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/6/17 09:40 + */ +@Data +@Builder +public class Req implements Serializable { + + private int code; + + private String message; + + private String sound; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/Response.java b/athena-all/src/main/java/run/mone/m78/ip/bo/Response.java new file mode 100644 index 000000000..950bd559e --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/Response.java @@ -0,0 +1,162 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.bo; + +import java.io.Serializable; +import java.util.Map; + +/** + * @author goodjava@qq.com + */ +public class Response implements Serializable { + + private int code; + private String msg; + private D data; + private String traceId; + private String spanId; + private String cmd; + private int id; + + private String senderId; + private String receiverId; + private String message; + private String group; + + private Map attachments; + + + public Response(int code, String msg, D data) { + this.code = code; + this.msg = msg; + this.data = data; + } + + public Response(int code, String msg, D data, String cmd) { + this.code = code; + this.msg = msg; + this.data = data; + this.cmd = cmd; + } + + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public D getData() { + return data; + } + + public void setData(D data) { + this.data = data; + } + + public String getTraceId() { + return traceId; + } + + public void setTraceId(String traceId) { + this.traceId = traceId; + } + + public String getSpanId() { + return spanId; + } + + public void setSpanId(String spanId) { + this.spanId = spanId; + } + + public String getCmd() { + return cmd; + } + + public void setCmd(String cmd) { + this.cmd = cmd; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getSenderId() { + return senderId; + } + + public void setSenderId(String senderId) { + this.senderId = senderId; + } + + public String getReceiverId() { + return receiverId; + } + + public void setReceiverId(String receiverId) { + this.receiverId = receiverId; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getGroup() { + return group; + } + + public void setGroup(String group) { + this.group = group; + } + + public Map getAttachments() { + return attachments; + } + + public void setAttachments(Map attachments) { + this.attachments = attachments; + } + + public static Response success(D data) { + return new Response<>(0, "succ", data); + } + + public static Response success(String cmd, D data) { + return new Response<>(0, "succ", data, cmd); + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/Result.java b/athena-all/src/main/java/run/mone/m78/ip/bo/Result.java new file mode 100644 index 000000000..1d631876d --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/Result.java @@ -0,0 +1,54 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.bo; + + +import lombok.Data; + +/** + * @author goodjava@qq.com + */ +@Data +public class Result { + + private int code; + private String message; + private T data; + + + public static Result success(String message) { + return new Result<>(0, message); + } + + public static Result fail(int code, String message) { + return new Result<>(code, message); + } + + public Result() { + } + + public Result(int code, String message) { + this.code = code; + this.message = message; + } + + public Result(int code, String message, T data) { + this.code = code; + this.message = message; + this.data = data; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/RobotContext.java b/athena-all/src/main/java/run/mone/m78/ip/bo/RobotContext.java new file mode 100644 index 000000000..58dc6a661 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/RobotContext.java @@ -0,0 +1,20 @@ +package run.mone.m78.ip.bo; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/4/28 14:24 + */ +@Data +public class RobotContext implements Serializable { + + private Project project; + + private Module module; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/RobotReq.java b/athena-all/src/main/java/run/mone/m78/ip/bo/RobotReq.java new file mode 100644 index 000000000..14dec27cc --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/RobotReq.java @@ -0,0 +1,21 @@ +package run.mone.m78.ip.bo; + +import com.intellij.openapi.project.Project; +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/4/28 14:23 + */ +@Data +@Builder +public class RobotReq implements Serializable { + + private String param; + + private Project project; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ServerInfo.java b/athena-all/src/main/java/run/mone/m78/ip/bo/ServerInfo.java new file mode 100644 index 000000000..c3e977c70 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/ServerInfo.java @@ -0,0 +1,48 @@ +package run.mone.m78.ip.bo; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/4/27 09:26 + * + * 插件的一些服务器信息 + */ +@Data +public class ServerInfo implements Serializable { + + private String host; + + private int port; + + private List projectList; + + private List moduleList; + + private List promptList; + + private String gptModel; + + /** + * ai proxy debug 模式 + */ + private boolean aiProxyDebug; + + + /** + * 是否使用local模式(所有问答直走本地) + */ + private boolean local; + + //是否开启多模态 + private boolean vision; + + /** + * 是否香后端发送append_msg + */ + private boolean send; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/SpiderUrl.java b/athena-all/src/main/java/run/mone/m78/ip/bo/SpiderUrl.java new file mode 100644 index 000000000..5a4e9ec77 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/SpiderUrl.java @@ -0,0 +1,51 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.bo; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/10 10:47 + */ +public class SpiderUrl { + + private String url; + + private String title; + + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + + @Override + public String toString() { + return this.title; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/Tag.java b/athena-all/src/main/java/run/mone/m78/ip/bo/Tag.java new file mode 100644 index 000000000..112fa75c5 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/Tag.java @@ -0,0 +1,22 @@ +package run.mone.m78.ip.bo; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/5/27 14:45 + */ +@Data +public class Tag implements Serializable { + + + private int id; + + private String name; + + private String description; + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/TbTask.java b/athena-all/src/main/java/run/mone/m78/ip/bo/TbTask.java new file mode 100644 index 000000000..00fd02585 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/TbTask.java @@ -0,0 +1,49 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.bo; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/9 14:53 + */ +public class TbTask { + + private String taskId; + + private String content; + + @Override + public String toString() { + return this.content; + } + + public String getTaskId() { + return taskId; + } + + public void setTaskId(String taskId) { + this.taskId = taskId; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/TeslaPluginConfig.java b/athena-all/src/main/java/run/mone/m78/ip/bo/TeslaPluginConfig.java new file mode 100644 index 000000000..a3f8f12b6 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/TeslaPluginConfig.java @@ -0,0 +1,157 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.bo; + + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @author goodjava@qq.com + */ +@Data +public class TeslaPluginConfig implements Serializable { + + private String mvnPath = ""; + private String javaPath = ""; + + //现在用来存取http server port + private String chatServer = ""; + + private String token = ""; + + //现在用来连接ultraman server + private String dashServer = ""; + + private String nickName = ""; + + private String opsLocal = ""; + private String opsStaging = ""; + + private String groupList = ""; + + private String chatgptKey = ""; + + private String chatgptProxy = "false"; + + private String aiProxy = ""; + + private String zToken = ""; + + private String model = ""; + + private List modelList; + + + public String getMvnPath() { + return mvnPath; + } + + public void setMvnPath(String mvnPath) { + this.mvnPath = mvnPath; + } + + public String getJavaPath() { + return javaPath; + } + + public void setJavaPath(String javaPath) { + this.javaPath = javaPath; + } + + public String getChatServer() { + return chatServer; + } + + public void setChatServer(String chatServer) { + this.chatServer = chatServer; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public String getDashServer() { + return dashServer; + } + + public void setDashServer(String dashServer) { + this.dashServer = dashServer; + } + + public String getNickName() { + return nickName; + } + + public void setNickName(String nickName) { + this.nickName = nickName; + } + + public String getOpsLocal() { + return opsLocal; + } + + public void setOpsLocal(String opsLocal) { + this.opsLocal = opsLocal; + } + + public String getOpsStaging() { + return opsStaging; + } + + public void setOpsStaging(String opsStaging) { + this.opsStaging = opsStaging; + } + + public String getGroupList() { + return groupList; + } + + public void setGroupList(String groupList) { + this.groupList = groupList; + } + + public String getChatgptKey() { + return chatgptKey; + } + + public void setChatgptKey(String chatgptKey) { + this.chatgptKey = chatgptKey; + } + + public String getChatgptProxy() { + return chatgptProxy; + } + + public void setChatgptProxy(String chatgptProxy) { + this.chatgptProxy = chatgptProxy; + } + + public String getzToken() { + return zToken; + } + + public void setzToken(String zToken) { + this.zToken = zToken; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/UserBo.java b/athena-all/src/main/java/run/mone/m78/ip/bo/UserBo.java new file mode 100644 index 000000000..fe74ac60c --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/UserBo.java @@ -0,0 +1,52 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.bo; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/11 16:30 + */ +public class UserBo { + + + private String name; + + private String email; + + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + + @Override + public String toString() { + return this.name; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/UserVo.java b/athena-all/src/main/java/run/mone/m78/ip/bo/UserVo.java new file mode 100644 index 000000000..8d6f4c315 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/UserVo.java @@ -0,0 +1,55 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.bo; + + +/** + * @author goodjava@qq.com + */ +public class UserVo { + + private String id; + private String name; + + public UserVo(String id, String name) { + this.id = id; + this.name = name; + } + + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + + @Override + public String toString() { + return this.name; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ValueInfo.java b/athena-all/src/main/java/run/mone/m78/ip/bo/ValueInfo.java new file mode 100644 index 000000000..ef6103387 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/ValueInfo.java @@ -0,0 +1,16 @@ +package run.mone.m78.ip.bo; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/7/14 14:27 + */ +@Data +public class ValueInfo implements Serializable { + + private String value; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ZAddrRes.java b/athena-all/src/main/java/run/mone/m78/ip/bo/ZAddrRes.java new file mode 100644 index 000000000..989c4e107 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/ZAddrRes.java @@ -0,0 +1,34 @@ +package run.mone.m78.ip.bo; + +import lombok.Data; + +import java.util.List; + +/** + * @author caobaoyu + * @description: + * @date 2023-06-07 14:40 + */ +@Data +public class ZAddrRes { + + private String addr; + + private String version; + + private String athenaConfig; + + /** + * athena dashboard的server地址(前端那个服务) + */ + private String athenaDashServer; + + /** + * 支持哪些模型 + */ + private List models; + + private List modelsV2; + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ZAskParam.java b/athena-all/src/main/java/run/mone/m78/ip/bo/ZAskParam.java new file mode 100644 index 000000000..e57c98bad --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/ZAskParam.java @@ -0,0 +1,28 @@ +package run.mone.m78.ip.bo; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @author caobaoyu + * @description: 请求Z平台的请求参数 + * @date 2023-04-21 15:43 + */ +@Data +public class ZAskParam implements Serializable { + private String token; + private String prompt; + private String type; + + private String name; + + private int num; + +// private boolean glm; + + private boolean chatGPT; + + private List types; +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ZPromptAddonItem.java b/athena-all/src/main/java/run/mone/m78/ip/bo/ZPromptAddonItem.java new file mode 100644 index 000000000..30ee19001 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/ZPromptAddonItem.java @@ -0,0 +1,12 @@ +package run.mone.m78.ip.bo; + +import lombok.Data; + +import java.io.Serializable; +import java.util.Map; + +@Data +public class ZPromptAddonItem implements Serializable { + String value; + Map meta; +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ZPromptRes.java b/athena-all/src/main/java/run/mone/m78/ip/bo/ZPromptRes.java new file mode 100644 index 000000000..6cea10b4d --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/ZPromptRes.java @@ -0,0 +1,47 @@ +package run.mone.m78.ip.bo; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * @author caobaoyu + * @description: Z平台http返回 + * @date 2023-04-21 15:51 + */ +@Data +public class ZPromptRes implements Serializable { + + private Long id; + + private String name; + + private String data; + + private int type; + + private String info; + + private String meta; + + private Integer mode; + + private String description; + + private List tags; + + private Boolean collected; + + private int usedTimes; + + private Map labels; + + private Map userLabels; + + private Integer collectedSort; + + private List addon; + private List addon_metas; +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ZRequestPram.java b/athena-all/src/main/java/run/mone/m78/ip/bo/ZRequestPram.java new file mode 100644 index 000000000..355b54c0c --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/ZRequestPram.java @@ -0,0 +1,42 @@ +package run.mone.m78.ip.bo; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author caobaoyu + * @description: 请求Z平台的请求参数 + * @date 2023-04-21 15:43 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ZRequestPram implements Serializable { + + private Integer pageSize; + + private Integer pageNum; + + private Integer type; + + private String info; + + private String name; + + private Integer structure; + + private Boolean collectionOnly; + + private String token; + + private Long tags; + + private Boolean sortByUsedTimes; + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/Choice.java b/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/Choice.java new file mode 100644 index 000000000..65bd71770 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/Choice.java @@ -0,0 +1,16 @@ +package run.mone.m78.ip.bo.chatgpt; + +import lombok.Data; + +/** + * @author goodjava@qq.com + * @date 2023/11/24 13:47 + */ +@Data +public class Choice { + + private Message message; + + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/Completions.java b/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/Completions.java new file mode 100644 index 000000000..1768aa682 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/Completions.java @@ -0,0 +1,42 @@ +package run.mone.m78.ip.bo.chatgpt; + +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/11/26 19:38 + */ +@Data +@Builder +public class Completions implements Serializable { + + + @Builder.Default + private String model = "gpt-4-1106-preview"; + + + private List messages; + + + @Builder.Default + private boolean stream = true; + + @Builder.Default + private double temperature = 0.2; + + @Builder.Default + private Integer n = 1; + + //可以控制是否是json返回结果 + private Format response_format; + + + //参数 + private String params; + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/Format.java b/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/Format.java new file mode 100644 index 000000000..b6a216f6c --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/Format.java @@ -0,0 +1,16 @@ +package run.mone.m78.ip.bo.chatgpt; + +import lombok.Builder; +import lombok.Data; + +/** + * @author goodjava@qq.com + * @date 2023/12/3 21:32 + */ +@Data +@Builder +public class Format { + + @Builder.Default + private String type = "json_object"; +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/ImageUrl.java b/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/ImageUrl.java new file mode 100644 index 000000000..ddcff8ea7 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/ImageUrl.java @@ -0,0 +1,16 @@ +package run.mone.m78.ip.bo.chatgpt; + +import lombok.Builder; +import lombok.Data; + +/** + * @author goodjava@qq.com + * @date 2023/11/24 13:56 + */ +@Data +@Builder +public class ImageUrl { + + private String url; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/LocalReq.java b/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/LocalReq.java new file mode 100644 index 000000000..04565ea2f --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/LocalReq.java @@ -0,0 +1,19 @@ +package run.mone.m78.ip.bo.chatgpt; + +import lombok.Data; + +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/11/28 11:16 + */ +@Data +public class LocalReq { + + private List msgList; + + //需要带的上下文数量 + private int num; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/Message.java b/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/Message.java new file mode 100644 index 000000000..ffcd848ba --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/Message.java @@ -0,0 +1,26 @@ +package run.mone.m78.ip.bo.chatgpt; + +import lombok.Builder; +import lombok.Data; + +import java.util.Map; + +/** + * @author goodjava@qq.com + * @date 2023/11/24 13:48 + */ +@Data +@Builder +public class Message { + + private String id; + + private String content; + + private String role; + + private Map params; + + //先放这里吧...很粗糙... + private String promptName; +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/ReqContent.java b/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/ReqContent.java new file mode 100644 index 000000000..9c6e3e9ca --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/ReqContent.java @@ -0,0 +1,20 @@ +package run.mone.m78.ip.bo.chatgpt; + +import lombok.Builder; +import lombok.Data; + +/** + * @author goodjava@qq.com + * @date 2023/11/24 13:53 + */ +@Data +@Builder +public class ReqContent { + + @Builder.Default + private String type = "text"; + + private String text; + + private ImageUrl image_url; +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/ReqMessage.java b/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/ReqMessage.java new file mode 100644 index 000000000..05d5720a8 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/ReqMessage.java @@ -0,0 +1,20 @@ +package run.mone.m78.ip.bo.chatgpt; + +import lombok.Builder; +import lombok.Data; + +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/11/24 13:52 + */ +@Data +@Builder +public class ReqMessage { + + @Builder.Default + private String role = "user"; + + private List content; +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/SpeechReq.java b/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/SpeechReq.java new file mode 100644 index 000000000..d3ce03d8d --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/SpeechReq.java @@ -0,0 +1,24 @@ +package run.mone.m78.ip.bo.chatgpt; + +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/11/24 11:45 + */ +@Builder +@Data +public class SpeechReq implements Serializable { + + @Builder.Default + private String model = "tts-1"; + + private String input; + + @Builder.Default + private String voice = "alloy"; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/VisionReq.java b/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/VisionReq.java new file mode 100644 index 000000000..f4418b7b1 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/VisionReq.java @@ -0,0 +1,27 @@ +package run.mone.m78.ip.bo.chatgpt; + +import lombok.Builder; +import lombok.Data; + +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/11/24 13:51 + */ +@Data +@Builder +public class VisionReq { + + @Builder.Default + private String model = "gpt-4-vision-preview"; + + + private List messages; + + + @Builder.Default + private int max_tokens = 300; + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/VisionRes.java b/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/VisionRes.java new file mode 100644 index 000000000..92533e03e --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/VisionRes.java @@ -0,0 +1,16 @@ +package run.mone.m78.ip.bo.chatgpt; + +import lombok.Data; + +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/11/24 13:45 + */ +@Data +public class VisionRes { + + private List choices; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/prompt/PromptParam.java b/athena-all/src/main/java/run/mone/m78/ip/bo/prompt/PromptParam.java new file mode 100644 index 000000000..ccd82c65f --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/prompt/PromptParam.java @@ -0,0 +1,58 @@ +package run.mone.m78.ip.bo.prompt; + +import com.google.common.collect.Lists; +import com.intellij.openapi.project.Project; +import run.mone.m78.ip.util.ProjectUtils; +import run.mone.m78.ip.bo.PromptInfo; +import run.mone.m78.ip.common.Const; +import run.mone.m78.ip.util.LabelUtils; +import run.mone.m78.ip.util.PackageUtils; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/7/16 00:22 + */ +@Data +public class PromptParam implements Serializable { + + private String type; + + private String subType; + + private String name; + + private String value; + + private List list; + + public void init(String key, Project project, PromptInfo promptInfo) { + if (key.equals("reqClass")) { + String reqPackage = LabelUtils.getLabelValue(project, promptInfo, Const.REQ_PACKAGE, Const.DEFAULT_REQ_PACKAGE); + List list = PackageUtils.getClassList(project, reqPackage); + list.add("Select"); + setList(list); + setType("comboBox"); + setSubType("class"); + } + if (key.equals("module")) { + List moduleList = ProjectUtils.listAllModules(project); + setList(moduleList); + setType("comboBox"); + } + if (key.equals("package")) { + String selectType = LabelUtils.open(Const.TREE_SELECT) ? "Select" : "Select2"; + List list = Lists.newArrayList(selectType); + setList(list); + setType("comboBox"); + } + } + + @Override + public String toString() { + return this.value; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/prompt/PromptParamType.java b/athena-all/src/main/java/run/mone/m78/ip/bo/prompt/PromptParamType.java new file mode 100644 index 000000000..36b0737dc --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/prompt/PromptParamType.java @@ -0,0 +1,17 @@ +package run.mone.m78.ip.bo.prompt; + +/** + * @author goodjava@qq.com + * @date 2023/7/19 13:35 + */ +public enum PromptParamType { + + code, + editor, + button, + comboBox, + label, + textField, + //参数 + params, +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/AiChatMessage.java b/athena-all/src/main/java/run/mone/m78/ip/bo/robot/AiChatMessage.java new file mode 100644 index 000000000..bc012147c --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/robot/AiChatMessage.java @@ -0,0 +1,68 @@ +package run.mone.m78.ip.bo.robot; + +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2023/12/1 13:55 + */ +@Data +@Builder +public class AiChatMessage implements Serializable { + + //这条消息的id + private String id; + + private int code; + + private int state; + + private long utime; + + private long ctime; + + //角色 + private Role role; + + private String message; + + //数据 + private T data; + + @Builder.Default + private MessageType type = MessageType.string; + + //返回的音频 + private String sound; + + @Builder.Default + private Map meta = new HashMap<>(); + + //这里就是向chatgpt提问的字符串 + public String toString() { + //有问题的把问题也append上 + String question = meta.getOrDefault("question", "").toString() + "\n"; + return question + getAnswer(); + } + + private String getAnswer() { + //单纯的String + if (type.equals(MessageType.string)) { + return data.toString(); + } + //一个列表 + if (type.equals(MessageType.list)) { + List list = (List) data; + return list.stream().map(data -> data.getIndex() + ":" + data.getTitle()).collect(Collectors.joining("\n")); + } + return data.toString(); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/AiMessageManager.java b/athena-all/src/main/java/run/mone/m78/ip/bo/robot/AiMessageManager.java new file mode 100644 index 000000000..c4f3f0d61 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/robot/AiMessageManager.java @@ -0,0 +1,148 @@ +package run.mone.m78.ip.bo.robot; + +import com.google.common.collect.Maps; +import org.apache.commons.lang3.StringUtils; +import run.mone.ultraman.state.AnswerType; +import run.mone.ultraman.state.ProjectFsmManager; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2023/12/1 14:20 + */ +public class AiMessageManager { + + + private List> messages = new LinkedList<>(); + + + private Map memory = new HashMap<>(); + + + public void addMessage(AiChatMessage message) { + this.messages.add(message); + } + + public void removeMessage(String id) { + messages = messages.stream().filter(it -> { + if (null == it.getId()) { + return false; + } + return !it.getId().equals(id); + }).collect(Collectors.toList()); + } + + public List> getMessages() { + return messages; + } + + public Map getMemory() { + return memory; + } + + + public void clearMsg() { + this.messages.clear(); + this.memory.clear(); + } + + /** + * 如果是submit 类型的event,返回的就是给前端的选择结果 + * 这里处理的其实是返回结果 + * + * @param req + * @return + */ + public EventRes event(MessageReq req) { + String id = req.getId(); + String data = ""; + //是否显示出来 + boolean show = false; + String messageId = ""; + Optional> optional = this.messages.stream().filter(it -> null != it.getId() && it.getId().equals(id)).findAny(); + if (optional.isPresent()) { + if ("submit".equals(req.getEventType())) { + AiChatMessage message = optional.get(); + //逻辑就是选中一个 + if (message.getType().equals(MessageType.list)) { + int index = Integer.valueOf(req.getMeta().getOrDefault("index", "0")); + List list = (List) message.getData(); + data = list.get(index - 1).getTitle(); + messageId = UUID.randomUUID().toString(); + ProjectAiMessageManager.getInstance().addMessage(req.getProject(), + AiChatMessage.builder() + .message(data) + .type(MessageType.string) + .data(data) + .id(messageId) + .role(Role.user) + .build()); + //看看有没有需要放入记忆的 + String memary = message.getMeta().getOrDefault("memary", "").toString(); + Map memaryMap = new HashMap<>(); + if (StringUtils.isNotEmpty(memary)) { + memaryMap.put(memary, data); + } + ProjectFsmManager.processMsg(req.getProject(), data, AnswerType.empty, memaryMap); + show = true; + } + //map(逻辑就是数据填充) + else if (message.getType().equals(MessageType.map)) { + Map map = req.getMapData(); + MapData mapData = MapData.builder().map(map).build(); + message.setData(mapData); + + data = "数据确认完毕"; + ProjectAiMessageManager.getInstance().addMessage(req.getProject(), + AiChatMessage.builder() + .message(data) + .type(MessageType.string) + .data(data) + .id(messageId) + .role(Role.user) + .build()); + show = true; + ProjectFsmManager.processMsg(req.getProject(), mapData.toString(), AnswerType.empty, map); + } + + //bool(返回true或者false) + else if (message.getType().equals(MessageType.bool)) { + boolean anwser = Boolean.valueOf(req.getMeta().getOrDefault("anwser", "false")); + String question = req.getMeta().getOrDefault("question", ""); + BoolData boolData = BoolData.builder().anwser(anwser).question(question).build(); + message.setData(boolData); + data = anwser ? "是" : "否"; + messageId = UUID.randomUUID().toString(); + ProjectAiMessageManager.getInstance().addMessage(req.getProject(), + AiChatMessage.builder() + .message(data) + .type(MessageType.string) + .data(data) + .id(messageId) + .role(Role.user) + .build()); + ProjectFsmManager.processMsg(req.getProject(), data, AnswerType.empty, Maps.newHashMap()); + show = true; + } + } + } + return EventRes.builder().data(data).messageId(messageId).show(show).build(); + } + + + public String appendMsg(AiChatMessage message) { + String id = ""; + if (StringUtils.isEmpty(message.getId())) { + id = UUID.randomUUID().toString(); + message.setId(id); + } + this.messages.add(message); + return message.getId(); + } + + public List> list() { + return this.messages; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/BoolData.java b/athena-all/src/main/java/run/mone/m78/ip/bo/robot/BoolData.java new file mode 100644 index 000000000..8087d46a9 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/robot/BoolData.java @@ -0,0 +1,29 @@ +package run.mone.m78.ip.bo.robot; + +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/12/15 11:08 + */ +@Data +@Builder +public class BoolData implements Serializable { + + + //问题内容 + private String question; + + + //回答的内容(true 或者 false) + private boolean anwser; + + + @Override + public String toString() { + return question; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/EventRes.java b/athena-all/src/main/java/run/mone/m78/ip/bo/robot/EventRes.java new file mode 100644 index 000000000..6e5ae359b --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/robot/EventRes.java @@ -0,0 +1,27 @@ +package run.mone.m78.ip.bo.robot; + +import lombok.Builder; +import lombok.Data; + +import java.util.Map; + +/** + * @author goodjava@qq.com + * @date 2023/12/11 16:54 + */ +@Builder +@Data +public class EventRes { + + private String messageId; + + private String type; + + private String data; + + private boolean show; + + private Map meta; + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/ItemData.java b/athena-all/src/main/java/run/mone/m78/ip/bo/robot/ItemData.java new file mode 100644 index 000000000..c056e7483 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/robot/ItemData.java @@ -0,0 +1,25 @@ +package run.mone.m78.ip.bo.robot; + +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; +import java.util.Map; + +/** + * @author goodjava@qq.com + * @date 2023/12/1 13:59 + */ +@Data +@Builder +public class ItemData implements Serializable, MessageData { + + private int index; + + private String title; + + private String value; + + private Map metaMap; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MapData.java b/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MapData.java new file mode 100644 index 000000000..035e004bf --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MapData.java @@ -0,0 +1,27 @@ +package run.mone.m78.ip.bo.robot; + +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +/** + * @author goodjava@qq.com + * @date 2023/12/11 17:20 + */ +@Data +@Builder +public class MapData implements Serializable, MessageData { + + private Map map; + + @Builder.Default + private Map memaryMap = new HashMap<>(); + + @Override + public String toString() { + return this.map.toString(); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MapDataValue.java b/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MapDataValue.java new file mode 100644 index 000000000..67fa89c32 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MapDataValue.java @@ -0,0 +1,21 @@ +package run.mone.m78.ip.bo.robot; + + +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/12/18 13:17 + */ +@Data +@Builder +public class MapDataValue implements Serializable { + + + private String memaryName; + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MessageData.java b/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MessageData.java new file mode 100644 index 000000000..5ea160dca --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MessageData.java @@ -0,0 +1,8 @@ +package run.mone.m78.ip.bo.robot; + +/** + * @author goodjava@qq.com + * @date 2023/12/11 17:28 + */ +public interface MessageData { +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MessageReq.java b/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MessageReq.java new file mode 100644 index 000000000..bda2f4876 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MessageReq.java @@ -0,0 +1,31 @@ +package run.mone.m78.ip.bo.robot; + +import lombok.Data; + +import java.util.Map; + +/** + * @author goodjava@qq.com + * @date 2023/12/11 10:48 + */ +@Data +public class MessageReq { + + private String project; + + private String id; + + private String role; + + private String message; + + private long time; + + private String eventType; + + private Map meta; + + private Map mapData; + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MessageRes.java b/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MessageRes.java new file mode 100644 index 000000000..f90f2e108 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MessageRes.java @@ -0,0 +1,24 @@ +package run.mone.m78.ip.bo.robot; + +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/12/11 14:12 + */ +@Data +@Builder +public class MessageRes implements Serializable { + + private String id; + + private String role; + + private String type; + + private String message; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MessageType.java b/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MessageType.java new file mode 100644 index 000000000..551f51061 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MessageType.java @@ -0,0 +1,22 @@ +package run.mone.m78.ip.bo.robot; + +/** + * @author goodjava@qq.com + * @date 2023/12/1 13:56 + */ +public enum MessageType { + + //纯粹的String + string, + //里边是ItemData(就是一个选择列表) + list, + + //kev -value (key都是固定好的,value用户自己填写) + map, + + //只有是还是否 + bool, + + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/ProjectAiMessageManager.java b/athena-all/src/main/java/run/mone/m78/ip/bo/robot/ProjectAiMessageManager.java new file mode 100644 index 000000000..3f5165a7b --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/robot/ProjectAiMessageManager.java @@ -0,0 +1,95 @@ +package run.mone.m78.ip.bo.robot; + +import com.google.gson.Gson; +import com.intellij.openapi.project.Project; +import lombok.Getter; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2023/12/1 14:38 + */ +public class ProjectAiMessageManager { + + + @Getter + private Map map = new HashMap<>(); + + + public void putMessageManager(String project, AiMessageManager manager) { + this.map.put(project, manager); + } + + public void removeMessageManager(String project) { + this.map.remove(project); + } + + + public AiMessageManager getMessageManager(String project) { + return map.get(project); + } + + + public List> getMessageList(String project) { + return map.get(project).getMessages(); + } + + public List> addMessage(Project project, AiChatMessage message) { + getMessageList(project).add(message); + return getMessageList(project); + } + + public List> addMessage(String project, AiChatMessage message) { + getMessageList(project).add(message); + return getMessageList(project); + } + + public List> getMessageList(Project project) { + return getMessageList(project.getName()); + } + + public void clearMsg(Project project) { + this.getMessageManager(project.getName()).clearMsg(); + } + + //删除指定消息 + public void delMsg(Project project, String msgId) { + this.getMessageManager(project.getName()).removeMessage(msgId); + } + + //事件 + public EventRes event(Project project, MessageReq req) { + return this.getMessageManager(project.getName()).event(req); + } + + //同步信息过来 + public MessageRes appendMsg(Project project, AiChatMessage message) { + return MessageRes.builder().id(this.getMessageManager(project.getName()).appendMsg(message)).build(); + } + + //获取消息列表 + public List listMsg(Project project) { + return this.getMessageManager(project.getName()).list().stream().map(it -> { + String message = it.getData().toString(); + if (!(it.getData() instanceof String)) { + message = (new Gson()).toJson(it.getData()); + } + return MessageRes.builder().id(it.getId()).type(it.getType().name()).message(message).role(it.getRole().name()).build(); + }).collect(Collectors.toList()); + } + + + private static final class LazyHolder { + private static final ProjectAiMessageManager ins = new ProjectAiMessageManager(); + } + + public static final ProjectAiMessageManager getInstance() { + return LazyHolder.ins; + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/Role.java b/athena-all/src/main/java/run/mone/m78/ip/bo/robot/Role.java new file mode 100644 index 000000000..ff1a019af --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/robot/Role.java @@ -0,0 +1,14 @@ +package run.mone.m78.ip.bo.robot; + +/** + * @author goodjava@qq.com + * @date 2023/12/1 14:20 + */ +public enum Role { + + system, + user, + assistant + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/z/EmbeddingStatus.java b/athena-all/src/main/java/run/mone/m78/ip/bo/z/EmbeddingStatus.java new file mode 100644 index 000000000..975a3f9f2 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/z/EmbeddingStatus.java @@ -0,0 +1,18 @@ +package run.mone.m78.ip.bo.z; + +import lombok.Data; + +/** + * @author goodjava@qq.com + * @date 2023/11/10 10:39 + */ +@Data +public class EmbeddingStatus { + + private String success; + + private int successCnt; + + private int total; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/z/ZKnowledgeRes.java b/athena-all/src/main/java/run/mone/m78/ip/bo/z/ZKnowledgeRes.java new file mode 100644 index 000000000..052619481 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/z/ZKnowledgeRes.java @@ -0,0 +1,26 @@ +package run.mone.m78.ip.bo.z; + +import lombok.Data; + +/** + * @author goodjava@qq.com + * @date 2023/11/7 13:34 + */ +@Data +public class ZKnowledgeRes { + + private Long tenantId; + + private Long knowledgeBaseId; + + private Long docId; + + private Long blockId; + + private float distance; + + private String content; + + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/z/ZResult.java b/athena-all/src/main/java/run/mone/m78/ip/bo/z/ZResult.java new file mode 100644 index 000000000..3c7695802 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/bo/z/ZResult.java @@ -0,0 +1,18 @@ +package run.mone.m78.ip.bo.z; + +import lombok.Data; + +/** + * @author goodjava@qq.com + * @date 2023/11/7 13:33 + */ +@Data +public class ZResult { + + private int code; + + private String message; + + private T data; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/client/GrpcClient.java b/athena-all/src/main/java/run/mone/m78/ip/client/GrpcClient.java new file mode 100644 index 000000000..7b40a78d6 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/client/GrpcClient.java @@ -0,0 +1,225 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.client; + +import com.google.gson.Gson; +import com.intellij.ide.util.PropertiesComponent; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.ui.Messages; +import com.intellij.util.messages.MessageBus; +import com.intellij.util.messages.MessageBusConnection; +import run.mone.m78.ip.util.HintUtils; +import run.mone.m78.ip.util.ProjectUtils; +import run.mone.mone.ultraman.grpc.UltramanRequest; +import run.mone.mone.ultraman.grpc.UltramanResponse; +import run.mone.mone.ultraman.grpc.UltramanServiceGrpc; +import run.mone.m78.ip.action.ActionEnum; +import run.mone.m78.ip.bo.TeslaPluginConfig; +import run.mone.m78.ip.common.NotificationCenter; +import run.mone.m78.ip.common.PluginVersion; +import run.mone.m78.ip.common.UltramanNotifier; +import run.mone.m78.ip.service.DocumentService; +import run.mone.m78.ip.service.ImageService; +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import io.grpc.stub.StreamObserver; +import org.apache.commons.lang.mutable.MutableObject; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/5 10:42 + */ +public class GrpcClient { + + private ManagedChannel channel; + + private TeslaPluginConfig config; + + private String ip; + + private boolean close = true; + + public void init() { + if (close) { + return; + } + + String v = PropertiesComponent.getInstance().getValue("tesla_plugin_token"); + if (null != v) { + try { + config = new Gson().fromJson(v, TeslaPluginConfig.class); + if (!StringUtils.equals(config.getChatServer(), ip)) { + try { + channel.shutdownNow(); + } catch (Throwable ex) { + } + } + + ip = config.getChatServer(); + System.out.println("Ultraman grpc channel build"); + channel = ManagedChannelBuilder.forAddress(ip, 5555).usePlaintext().build(); + + new Thread(() -> { + int i = 0; + MessageBusConnection connection = null; + for (; ; ) { + System.out.println("connect grpc num:" + (i++)); + CountDownLatch latch = new CountDownLatch(1); + try { + UltramanResponse res = call(UltramanRequest.newBuilder().setCmd("version").build()); + if (null != res && (Integer.valueOf(res.getData()) > Integer.valueOf(new PluginVersion().toString()))) { + //需要升级 + ApplicationManager.getApplication().invokeLater(() -> { + NotificationCenter.notice("Ultraman Plugin Update"); + }); + } + StreamObserver streamObserver = this.listener(latch); + MessageBus messageBus = ApplicationManager.getApplication().getMessageBus(); + connection = messageBus.connect(); + connection.subscribe(UltramanNotifier.ULTRAMAN_ACTION_TOPIC, event -> { + System.out.println(event.getCmd()); + switch (event.getCmd()) { + case "save_config": { + break; + } + case "req": { + streamObserver.onNext((UltramanRequest) event.getData()); + break; + } + } + }); + } catch (Throwable ex) { + ex.printStackTrace(); + latch.countDown(); + } + try { + latch.await(); + TimeUnit.SECONDS.sleep(3); + } catch (Throwable ex) { + + } finally { + if (null != connection) { + connection.disconnect(); + } + } + } + }).start(); + } catch (Throwable ex) { + System.out.println("Ultraman error:" + ex.getMessage()); + } + } else { + ApplicationManager.getApplication().invokeLater(() -> { + Messages.showMessageDialog("请初始化Ultraman配置(user)", "message", Messages.getInformationIcon()); + }); + } + } + + public UltramanResponse call(UltramanRequest req) { + UltramanServiceGrpc.UltramanServiceBlockingStub stub2 = UltramanServiceGrpc.newBlockingStub(channel); + UltramanResponse res = stub2.hello(req); + return res; + } + + public StreamObserver listener(CountDownLatch latch) { + UltramanServiceGrpc.UltramanServiceStub stub = UltramanServiceGrpc.newStub(channel); + MutableObject mo = new MutableObject(); + final StreamObserver reqStream = stub.stream(new StreamObserver() { + @Override + public void onNext(UltramanResponse res) { + System.out.println(res.getData()); + //通知 + if (res.getCmd().equals("notify")) { + String data = res.getData(); + if (!res.getResMapOrDefault("user", "").equals("")) { + data = res.getResMapOrDefault("user", "") + ":" + data; + } + String type = res.getResMapOrDefault("type", "0"); + if (type.equals("0")) { + NotificationCenter.notice(data); + HintUtils.show(null, data); + } else { + HintUtils.show(null, data); + } + } + //查看图片 + if (res.getCmd().equals("image")) { + new ImageService().open(ActionEnum.zero.name()); + } + //显示代码 + if (res.getCmd().equals("show_code")) { + MutableObject moc = new MutableObject(); + ApplicationManager.getApplication().invokeAndWait(() -> { + int v = Messages.showOkCancelDialog(ProjectUtils.project(), "有人给你推送了代码,是否选择查看", "选择", Messages.getInformationIcon()); + moc.setValue(v); + }); + if ((int) moc.getValue() == 0) { + new DocumentService().open(res.getResMapMap().get("fileName"), res.getData()); + } + } + //查看代码(别人主动要看代码,返回我的代码) + if (res.getCmd().equals("begin_review")) { + String user = res.getResMapMap().get("review"); + + MutableObject moc = new MutableObject(); + ApplicationManager.getApplication().invokeAndWait(() -> { + int v = Messages.showOkCancelDialog(ProjectUtils.project(), user + "想要查看你当前的code", "选择", Messages.getInformationIcon()); + moc.setValue(v); + }); + + if ((int) moc.getValue() != 0) { + return; + } + + Pair data = new DocumentService().getContent(null); + if (null == data) { + data = Pair.of("对方没有打开源码", "tmp.java"); + } + StreamObserver reqStream = (StreamObserver) mo.getValue(); + UltramanRequest req = UltramanRequest.newBuilder().setCmd("begin_review_res") + .setParams(data.getKey()) + .putParamMap("fileName", data.getValue()) + .putParamMap("review", user) + .putParamMap("user", res.getResMapMap().get("user")) + .build(); + reqStream.onNext(req); + } + } + + @Override + public void onError(Throwable throwable) { + throwable.printStackTrace(); + latch.countDown(); + } + + @Override + public void onCompleted() { + latch.countDown(); + } + }); + mo.setValue(reqStream); + UltramanRequest loginReq = UltramanRequest.newBuilder().setCmd("login").putParamMap("user", config.getNickName()).build(); + reqStream.onNext(loginReq); + return reqStream; + + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/client/MyHttpClient.java b/athena-all/src/main/java/run/mone/m78/ip/client/MyHttpClient.java new file mode 100644 index 000000000..92798ca90 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/client/MyHttpClient.java @@ -0,0 +1,39 @@ +package run.mone.m78.ip.client; + +import okhttp3.OkHttpClient; + +import java.util.concurrent.TimeUnit; + +/** + * @author caobaoyu + * @description: + * @date 2023-04-21 17:15 + */ +public class MyHttpClient { + + private static OkHttpClient instance; + + private MyHttpClient() { + } + + public static OkHttpClient getInstance() { + if (instance == null) { + instance = new OkHttpClient.Builder() + .connectTimeout(1, TimeUnit.SECONDS) + .readTimeout(10, TimeUnit.SECONDS) + .writeTimeout(1, TimeUnit.SECONDS) + .build(); + } + return instance; + } + + public static void close() { + instance = getInstance(); + if (instance == null) { + return; + } + instance.dispatcher().executorService().shutdown(); + instance.connectionPool().evictAll(); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/ApiCall.java b/athena-all/src/main/java/run/mone/m78/ip/common/ApiCall.java new file mode 100644 index 000000000..a2c78c041 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/ApiCall.java @@ -0,0 +1,69 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.common; + +import com.google.gson.Gson; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/2 10:56 + */ +public class ApiCall { + + private static final String END_POINT = ""; + + public static final String MUSIC_API = END_POINT + "/music"; + public static final String TEXT_API = END_POINT + "/text"; + public static final String IMAGE_API = END_POINT + "/image"; + public static final String CODE_API = END_POINT + "/code"; + public static final String USER_API = END_POINT + "/user"; + public static final String TASK_API = END_POINT + "/task"; + public static final String SPIDER_API = END_POINT + "/spider"; + + public static final Map TagIndex = new HashMap<>(); + + public List call(String url) { + return null; + } + + public String postCall(String url, String params) { + return postCall(url, params, 1000); + } + + public String postCall(String url, String params, int timeout) { + return null; + } + + + public String callOne(String url) { + return null; + } + + public String callTag(String url, String tag) { + return ""; + } + + public String callIt(String url, String name) { + return ""; + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/ApiRes.java b/athena-all/src/main/java/run/mone/m78/ip/common/ApiRes.java new file mode 100644 index 000000000..85b794b3e --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/ApiRes.java @@ -0,0 +1,57 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.common; + +import java.io.Serializable; +import java.util.List; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/2 10:58 + */ +public class ApiRes implements Serializable { + + private int code; + + private String message; + + private List data; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/AthenaBiConsumer.java b/athena-all/src/main/java/run/mone/m78/ip/common/AthenaBiConsumer.java new file mode 100644 index 000000000..ddac9950d --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/AthenaBiConsumer.java @@ -0,0 +1,17 @@ +package run.mone.m78.ip.common; + +import com.intellij.openapi.project.Project; + +import java.util.function.BiConsumer; + +/** + * @author goodjava@qq.com + * @date 2023/7/5 09:49 + */ +public class AthenaBiConsumer implements BiConsumer { + + @Override + public void accept(Project project, String s) { + + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/AthenaMessageConsumer.java b/athena-all/src/main/java/run/mone/m78/ip/common/AthenaMessageConsumer.java new file mode 100644 index 000000000..fad04c126 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/AthenaMessageConsumer.java @@ -0,0 +1,44 @@ +package run.mone.m78.ip.common; + +import com.google.gson.Gson; +import run.mone.m78.ip.bo.AiMessage; +import run.mone.m78.ip.bo.MessageConsumer; +import lombok.extern.slf4j.Slf4j; + +/** + * @author goodjava@qq.com + * @date 2023/7/5 09:49 + */ +@Slf4j +public class AthenaMessageConsumer extends MessageConsumer { + + private Gson gson = new Gson(); + + private String projectName; + + public AthenaMessageConsumer(String projectName) { + this.projectName = projectName; + } + + @Override + public void begin(AiMessage message) { + String str = gson.toJson(message); + log.info(str); + ChromeUtils.call(projectName, "setResultCode", str); + } + + @Override + public void onEvent(AiMessage message) { + String str = gson.toJson(message); + log.info(str); + ChromeUtils.call(projectName, "setResultCode", str); + } + + @Override + public void end(AiMessage message) { + String str = gson.toJson(message); + log.info(str); + ChromeUtils.call(projectName, "setResultCode", str); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/ChromeUtils.java b/athena-all/src/main/java/run/mone/m78/ip/common/ChromeUtils.java new file mode 100644 index 000000000..6c2ddf175 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/ChromeUtils.java @@ -0,0 +1,39 @@ +package run.mone.m78.ip.common; + +import com.google.gson.Gson; +import run.mone.m78.ip.bo.robot.AiChatMessage; +import lombok.SneakyThrows; + +/** + * @author goodjava@qq.com + * @date 2023/6/2 16:44 + */ +public class ChromeUtils { + + private static final Gson gson = new Gson(); + + @SneakyThrows + public static void call(String projectName, String method, String param, boolean useReq) { + + } + + + public static void call(String projectName, String param, int code) { + call(projectName, param, "", code); + } + + public static void call(String projectName, String param, String sound, int code) { + + } + + public static void call(String projectName, AiChatMessage res) { + + } + + + public static void call(String projectName, String method, String param) { + call(projectName, method, param, false); + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/ColorEggUtils.java b/athena-all/src/main/java/run/mone/m78/ip/common/ColorEggUtils.java new file mode 100644 index 000000000..95ef501cc --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/ColorEggUtils.java @@ -0,0 +1,124 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.common; + +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.DESKeySpec; +import java.security.SecureRandom; + +public class ColorEggUtils { + + /** + * 加密 + * + * @param content + * 待加密内容 + * @param key + * 加密的密钥 + * @return + */ + public static byte[] encrypt(String content, String key) { + try { + SecureRandom random = new SecureRandom(); + DESKeySpec desKey = new DESKeySpec(key.getBytes()); + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); + SecretKey securekey = keyFactory.generateSecret(desKey); + Cipher cipher = Cipher.getInstance("DES"); + cipher.init(Cipher.ENCRYPT_MODE, securekey, random); + byte[] result = cipher.doFinal(content.getBytes()); + return result; + } catch (Throwable e) { + e.printStackTrace(); + } + return null; + } + + /** + * 解密 + * + * @param content + * 待解密内容 + * @param key + * 解密的密钥 + * @return + */ + public static String decrypt(byte[] content, String key) { + try { + SecureRandom random = new SecureRandom(); + DESKeySpec desKey = new DESKeySpec(key.getBytes()); + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); + SecretKey securekey = keyFactory.generateSecret(desKey); + Cipher cipher = Cipher.getInstance("DES"); + cipher.init(Cipher.DECRYPT_MODE, securekey, random); + byte[] result = cipher.doFinal(content); + return new String(result); + } catch (Throwable e) { + e.printStackTrace(); + } + return null; + } + + + /** + * 将二进制转换成16进制 + * + * @param buf + * @return + */ + public static String parseByte2HexStr(byte buf[]) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < buf.length; i++) { + String hex = Integer.toHexString(buf[i] & 0xFF); + if (hex.length() == 1) { + hex = '0' + hex; + } + sb.append(hex); + } + return sb.toString(); + } + + /** + * hex字符串转byte数组 + * @param inHex 待转换的Hex字符串 + * @return 转换后的byte数组结果 + */ + public static byte[] hexToByteArray(String inHex){ + int hexlen = inHex.length(); + byte[] result; + if (hexlen % 2 == 1){ + //奇数 + hexlen++; + result = new byte[(hexlen/2)]; + inHex="0"+inHex; + }else { + //偶数 + result = new byte[(hexlen/2)]; + } + int j=0; + for (int i = 0; i < hexlen; i+=2){ + result[j]=hexToByte(inHex.substring(i,i+2)); + j++; + } + return result; + } + + public static byte hexToByte(String inHex){ + return (byte)Integer.parseInt(inHex,16); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/ConfigCenter.java b/athena-all/src/main/java/run/mone/m78/ip/common/ConfigCenter.java new file mode 100644 index 000000000..330b88b98 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/ConfigCenter.java @@ -0,0 +1,51 @@ +package run.mone.m78.ip.common; + +import run.mone.m78.ip.bo.AiCodeRes; +import run.mone.m78.ip.bo.Tag; +import lombok.Data; +import lombok.Getter; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @author caobaoyu + * @description: 从Z获取一些基础配置 对应 -> 68 Athena の cfg center + * @date 2023-05-30 11:02 + */ +@Data +public class ConfigCenter { + + + private static Map copyrightingMap = new HashMap<>(); + + @Getter + private static List guide = new ArrayList<>(); + + private static List menuTag = new ArrayList<>(); + + public static Map getMenuTag() { + return menuTag.stream().collect(Collectors.toMap(Tag::getName, Function.identity())); + } + + public static void init(String zAddr) { + guide.clear(); + menuTag.clear(); + buildCopyrighting(zAddr); + } + + private static void buildCopyrighting(String zAddr) { + + + } + + public static AiCodeRes build(String type) { + return copyrightingMap.get(type); + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/ConfigUtils.java b/athena-all/src/main/java/run/mone/m78/ip/common/ConfigUtils.java new file mode 100644 index 000000000..dfc9454f4 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/ConfigUtils.java @@ -0,0 +1,68 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.common; + +import com.google.gson.Gson; +import com.intellij.ide.util.PropertiesComponent; +import run.mone.m78.ip.bo.TeslaPluginConfig; +import org.apache.commons.lang3.StringUtils; +import run.mone.ultraman.AthenaContext; + +/** + * @author goodjava@qq.com + */ +public abstract class ConfigUtils { + + public static TeslaPluginConfig getConfig() { + String v = PropertiesComponent.getInstance().getValue(""); + if (StringUtils.isNotEmpty(v)) { + TeslaPluginConfig config = new Gson().fromJson(v, TeslaPluginConfig.class); + + String model = config.getModel(); + if (StringUtils.isNotEmpty(model)) { + AthenaContext.ins().setGptModel(model); + AthenaContext.ins().setModelList(config.getModelList()); + } + + if (StringUtils.isEmpty(config.getDashServer())) { + config.setDashServer(System.getenv("DASH")); + } + if (StringUtils.isEmpty(config.getNickName())) { + config.setNickName(System.getenv("USER")); + } + if (StringUtils.isEmpty(config.getChatgptKey())) { + config.setChatgptKey(System.getenv("API")); + } + + AthenaContext.ins().setToken(config.getToken()); + return config; + } + return new TeslaPluginConfig(); + + } + + + public static String user() { + try { + TeslaPluginConfig config = getConfig(); + return config.getNickName(); + } catch (Throwable ex) { + return ""; + } + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/Const.java b/athena-all/src/main/java/run/mone/m78/ip/common/Const.java new file mode 100644 index 000000000..eeb5d3925 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/Const.java @@ -0,0 +1,64 @@ +package run.mone.m78.ip.common; + +import com.intellij.openapi.util.Key; +import com.intellij.util.messages.Topic; +import run.mone.ultraman.listener.AthenaMessageListener; + +/** + * @author goodjava@qq.com + * @date 2023/6/17 09:37 + */ +public interface Const { + + String MODULE_FILE_NAME = ""; + + String REQ_PACKAGE = "req_package"; + + String DEFAULT_REQ_PACKAGE = "run.mone.bo"; + + String DISABLE_SEARCH = "disable.search"; + + String AI_PROXY_CHAT = "ai.proxy.chat"; + + String ENABLE_ATHENA_STATUS_BAR = "enable.athena.status.bar"; + + String DISABLE_ACTION_GROUP = "disable.action.group"; + + String BIZ_WRITE = "biz_write"; + + String OPEN_AI_KEY = "open_ai_key"; + + String OPEN_AI_PROXY = "open_ai_proxy"; + + //直接本地调用chatgpt(local模式) + String OPEN_AI_LOCAL = "open_ai_local"; + + //本地测试 + String OPEN_AI_TEST = "open.ai.test"; + + //提问的时候是否开启选中的文本 + String OPEN_SELECT_TEXT = "open.select.text"; + + String OPEN_AI_MODEL = "open_ai_model"; + + String SEARCH = "search"; + + int UI_CANCEL_CODE = 555; + + String OPEN_GUIDE = "open.guide"; + + String DEBUG = "debug"; + + //多模态模式 + String VISION = "vision"; + + String CODE_SCRIPT = "code.script"; + + String TREE_SELECT = "tree.select"; + + Key T_KEY = new Key<>("t"); + + Topic ATHENA_TOPIC = new Topic(AthenaMessageListener.class); + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/Context.java b/athena-all/src/main/java/run/mone/m78/ip/common/Context.java new file mode 100644 index 000000000..c783f4641 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/Context.java @@ -0,0 +1,56 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.common; + +import com.intellij.openapi.project.Project; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/8 10:19 + */ +public class Context { + + private String content; + + private int status; + + private Project project; + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public Project getProject() { + return project; + } + + public void setProject(Project project) { + this.project = project; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/DownloadUtils.java b/athena-all/src/main/java/run/mone/m78/ip/common/DownloadUtils.java new file mode 100644 index 000000000..53d5c7d89 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/DownloadUtils.java @@ -0,0 +1,36 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.common; + + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Paths; + +/** + * @Author goodjava@qq.com + * @Date 2021/10/30 20:58 + */ +public class DownloadUtils { + + + public static void download(String url, String name) throws IOException { + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/Events.java b/athena-all/src/main/java/run/mone/m78/ip/common/Events.java new file mode 100644 index 000000000..58e8ce0ca --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/Events.java @@ -0,0 +1,34 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.common; + +import com.intellij.openapi.application.ApplicationManager; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/6 20:17 + */ +public class Events { + + + public static void publis(UltramanEvent event) { + ApplicationManager.getApplication().getMessageBus() + .syncPublisher(UltramanNotifier.ULTRAMAN_ACTION_TOPIC) + .onEvent(event); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/FileUtils.java b/athena-all/src/main/java/run/mone/m78/ip/common/FileUtils.java new file mode 100644 index 000000000..192d444fb --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/FileUtils.java @@ -0,0 +1,88 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.common; + +import org.apache.commons.io.IOUtils; +import org.beetl.core.Configuration; +import org.beetl.core.GroupTemplate; +import org.beetl.core.Template; +import org.beetl.core.resource.StringTemplateResourceLoader; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Map; + +/** + * @author goodjava@qq.com + */ +public class FileUtils { + + public static String home() { + return System.getProperty("user.home"); + } + + public static void createDirectories(String path) { + try { + Files.createDirectories(Paths.get(path)); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static String getTemplate(String name) { + InputStream is = FileUtils.class.getClassLoader().getResourceAsStream("template/" + name); + try { + return IOUtils.toString(is, StandardCharsets.UTF_8); + } catch (IOException e) { + e.printStackTrace(); + } + return ""; + } + + + public static String renderTemplate(String template, Map m) { + try { + StringTemplateResourceLoader resourceLoader = new StringTemplateResourceLoader(); + Configuration cfg = Configuration.defaultConfiguration(); + GroupTemplate gt = new GroupTemplate(resourceLoader, cfg); + Template t = gt.getTemplate(template); + m.forEach((k, v) -> t.binding(k, v)); + String str = t.render(); + return str; + } catch (Throwable ex) { + ex.printStackTrace(); + } + return ""; + } + + + /** + * 写文件 + * @param path + * @param content + */ + public static void writeFile(String path, String content) { + try { + Files.write(Paths.get(path), content.getBytes()); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/GlobalConfig.java b/athena-all/src/main/java/run/mone/m78/ip/common/GlobalConfig.java new file mode 100644 index 000000000..2117c579b --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/GlobalConfig.java @@ -0,0 +1,21 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.common; + +public class GlobalConfig { + public static final String PLUGIN_NAME = "youpin_plugin"; +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/IdeaPluginVersion.java b/athena-all/src/main/java/run/mone/m78/ip/common/IdeaPluginVersion.java new file mode 100644 index 000000000..5e68a42c8 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/IdeaPluginVersion.java @@ -0,0 +1,29 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.common; + +/** + * @author goodjava@qq.com + */ +public class IdeaPluginVersion { + + @Override + public String toString() { + return "IdeaPluginVersion:2019-05-08:0.0.1"; + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/JavaClassUtils.java b/athena-all/src/main/java/run/mone/m78/ip/common/JavaClassUtils.java new file mode 100644 index 000000000..8b0e0c2da --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/JavaClassUtils.java @@ -0,0 +1,51 @@ +package run.mone.m78.ip.common; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; + +/** + * @author goodjava@qq.com + * @date 2023/4/12 11:05 + */ +public abstract class JavaClassUtils { + + /** + * Create a class. + */ + public static void createClass(AnActionEvent e) { + createClass(e.getProject(), e.getData(PlatformDataKeys.EDITOR), "abc", ""); + } + + public static void createClass(Project project, Editor editor, String name, String code) { + + } + + + public static void createClass(Project project, Editor editor, String name, String code, boolean testClass) { + + } + + public static void createClass(Project project, Editor editor, String name, String code, boolean testClass, String packagePath) { + + } + + + public static void openClass(AnActionEvent e) { + + } + + public static void openClass(Project project, String className) { + + } + + + public static String getClassName(String className) { + String[] classNameParts = className.split("\\."); + String simpleClassName = classNameParts[classNameParts.length - 1]; + return simpleClassName; + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/MessageQueue.java b/athena-all/src/main/java/run/mone/m78/ip/common/MessageQueue.java new file mode 100644 index 000000000..7eb5a0717 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/MessageQueue.java @@ -0,0 +1,70 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.common; + +import run.mone.m78.ip.bo.Response; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.LinkedBlockingQueue; + +/** + * @author goodjava@qq.com + */ +public class MessageQueue { + + private LinkedBlockingQueue queue = new LinkedBlockingQueue<>(); + private LinkedBlockingQueue> sendQueue = new LinkedBlockingQueue<>(); + + + private static class LazyHolder { + private static MessageQueue ins = new MessageQueue(); + } + + + public static MessageQueue ins() { + return LazyHolder.ins; + } + + + public void offer(Response msg) { + queue.offer(msg); + } + + public void send(Map msg) { + sendQueue.offer(msg); + } + + + public Response poll() { + try { + return queue.take(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return null; + } + + public Map pollSend() { + try { + return sendQueue.take(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return new HashMap<>(); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/Mp3Player.java b/athena-all/src/main/java/run/mone/m78/ip/common/Mp3Player.java new file mode 100644 index 000000000..b0b1ead8c --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/Mp3Player.java @@ -0,0 +1,83 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.common; + +import com.intellij.openapi.diagnostic.Logger; + +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.Clip; +import javax.sound.sampled.UnsupportedAudioFileException; +import java.io.IOException; +import java.util.Objects; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/1 13:49 + */ +public class Mp3Player { + + private int point; + private Clip clip; + + private static final Logger log = Logger.getInstance(Mp3Player.class); + + + public void playMp3Url(String url) throws UnsupportedAudioFileException, IOException { + } + + public void playMp3File(String path) throws UnsupportedAudioFileException, IOException { + } + + private void playMp3File(AudioInputStream stream) throws IOException { + } + + public void pause() { + if (Objects.nonNull(clip)) { + // 获取当前播放中继点 + point = clip.getFramePosition(); + // 停止播放 + clip.stop(); + } + } + + public void play() { + if (isNewBegin()) { + // 重新播放一首歌 + try { + playMp3Url(); + } catch (UnsupportedAudioFileException | IOException e) { + e.printStackTrace(); + } + } else { + // 暂停继续播放 + // 设置播放点 + clip.setFramePosition(point); + // 继续播放 + clip.start(); + } + } + + public boolean isNewBegin() { + return Objects.isNull(clip); + } + + public void playMp3Url() throws UnsupportedAudioFileException, IOException { + playMp3Url(""); + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/Mp3PlayerV2.java b/athena-all/src/main/java/run/mone/m78/ip/common/Mp3PlayerV2.java new file mode 100644 index 000000000..51214ab51 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/Mp3PlayerV2.java @@ -0,0 +1,76 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.common; + +import com.intellij.openapi.diagnostic.Logger; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.TimeUnit; + +/** + * @Author goodjava@qq.com + */ +public class Mp3PlayerV2 { + + + private static final Logger log = Logger.getInstance(Mp3PlayerV2.class); + + private boolean begin; + + + private Mp3PlayerV2() { + + } + + + private static final class LazyHolder { + private static Mp3PlayerV2 ins = new Mp3PlayerV2(); + } + + public static final Mp3PlayerV2 ins() { + return LazyHolder.ins; + } + + + public static void main(String[] args) throws IOException, InterruptedException { + Mp3PlayerV2 player = new Mp3PlayerV2(); + player.play(new FileInputStream(new File("/tmp/a.mp3"))); + TimeUnit.SECONDS.sleep(5); + player.close(); + System.out.println("close"); + TimeUnit.SECONDS.sleep(5); + } + + + public synchronized void close() { + if (begin) { + begin = false; + } + } + + public synchronized void play(InputStream input) { + } + + public synchronized boolean isComplete() { + return true; + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/NotificationCenter.java b/athena-all/src/main/java/run/mone/m78/ip/common/NotificationCenter.java new file mode 100644 index 000000000..92d2c896f --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/NotificationCenter.java @@ -0,0 +1,72 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.common; + +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationType; +import com.intellij.notification.Notifications; +import com.intellij.openapi.project.Project; +import run.mone.m78.ip.util.LabelUtils; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/1 12:20 + */ +public class NotificationCenter { + + + public static void notice(String message) { + notice(message, NotificationType.INFORMATION); + } + + + public static void notice(String message, NotificationType type) { + Notification n = new Notification( + "Athena", + "Athena", + message, + type); + Notifications.Bus.notify(n); + } + + + /** + * 只有debug模式才输出 + * + * @param message + * @param type + * @param debug + */ + public static void notice(String message, NotificationType type, boolean debug) { + if (debug && LabelUtils.getLabelValue(null, "debug", "true").equals("true")) { + notice(message, type); + } + } + + public static void notice(final Project project, String message, boolean debug) { + if (debug) { + if (LabelUtils.getLabelValue(null, "debug", "true").equals("true")) { + Notification notification = new Notification("Athena Notifications", "Athena", message, NotificationType.INFORMATION); + Notifications.Bus.notify(notification, project); + } + } else { + Notification notification = new Notification("Athena Notifications", "Athena", message, NotificationType.INFORMATION); + Notifications.Bus.notify(notification, project); + } + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/OggPlayer.java b/athena-all/src/main/java/run/mone/m78/ip/common/OggPlayer.java new file mode 100644 index 000000000..a0287318f --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/OggPlayer.java @@ -0,0 +1,79 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.common; + + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.SourceDataLine; +import java.io.File; +import java.io.IOException; + + +/** + * @Author goodjava@qq.com + * @Date 2021/10/30 20:27 + */ +public class OggPlayer { + + public static void main(String[] args) { + OggPlayer player = new OggPlayer(); + player.play("/tmp/abc.ogg"); + } + + public void play(String filePath) { + final File file = new File(filePath); + + try { +// final AudioInputStream in = new VorbisAudioFileReader().getAudioInputStream(file); + final AudioInputStream in = null; + final AudioFormat outFormat = getOutFormat(in.getFormat()); + final DataLine.Info info = new DataLine.Info(SourceDataLine.class, outFormat); + + final SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info); + + if (line != null) { + line.open(outFormat); + line.start(); + stream(AudioSystem.getAudioInputStream(outFormat, in), line); + line.drain(); + line.stop(); + } + + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + + private AudioFormat getOutFormat(AudioFormat inFormat) { + final int ch = inFormat.getChannels(); + final float rate = inFormat.getSampleRate(); + return new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, rate, 16, ch, ch * 2, rate, false); + } + + private void stream(AudioInputStream in, SourceDataLine line) + throws IOException { + final byte[] buffer = new byte[65536]; + for (int n = 0; n != -1; n = in.read(buffer, 0, buffer.length)) { + line.write(buffer, 0, n); + } + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/OpenImageConsumer.java b/athena-all/src/main/java/run/mone/m78/ip/common/OpenImageConsumer.java new file mode 100644 index 000000000..6e101a960 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/OpenImageConsumer.java @@ -0,0 +1,98 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.common; + + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.UUID; +import java.util.function.Consumer; + + +/** + * @author goodjava@qq.com + */ +public class OpenImageConsumer implements Consumer { + + private static final Logger LOG = Logger.getInstance(OpenImageConsumer.class); + + private String imgUrl = ""; + + public OpenImageConsumer() { + } + + public OpenImageConsumer(String imgUrl) { + this.imgUrl = imgUrl; + } + + @Override + public void accept(DataContext dataContext) { + Project currentProject = dataContext.getData(PlatformDataKeys.PROJECT); + if (currentProject == null) { + LOG.warn("currentProject cannot be null"); + return; + } + LOG.info("image url:" + this.imgUrl); + String imagePath = imagePath(); + copyImg(imagePath, null); + VirtualFile image = LocalFileSystem.getInstance().refreshAndFindFileByPath(imagePath); + if (image == null) { + LOG.info("image is null"); + return; + } + + FileEditorManagerEx fileEditorManager = FileEditorManagerEx.getInstanceEx(currentProject); + fileEditorManager.openFile(image, false); + } + + private void copyImg(String path, InputStream is) { + try { + if (Files.exists(Paths.get(path))) { + Files.delete(Paths.get(path)); + } + Files.copy(is, Paths.get(path)); + } catch (IOException e) { + LOG.info("copy img error:" + e.getMessage()); + } finally { + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + + private String imagePath() { + String name = UUID.randomUUID().toString() + ".jpg"; + String defaultBaseDir = System.getProperty("java.io.tmpdir"); + String path = defaultBaseDir + File.separator + name; + return path; + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/OpenTextConsumer.java b/athena-all/src/main/java/run/mone/m78/ip/common/OpenTextConsumer.java new file mode 100644 index 000000000..b824d886e --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/OpenTextConsumer.java @@ -0,0 +1,79 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.common; + + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.function.Consumer; + + +/** + * 打开文本文件 + * @author goodjava@qq.com + */ +public class OpenTextConsumer implements Consumer { + + private static final Logger LOG = Logger.getInstance(OpenTextConsumer.class); + + private String content; + private String fileName; + + public OpenTextConsumer() { + } + + public OpenTextConsumer(String content,String fileName) { + this.content = content; + this.fileName = fileName; + } + + @Override + public void accept(DataContext dataContext) { + Project currentProject = dataContext.getData(PlatformDataKeys.PROJECT); + if (currentProject == null) { + LOG.warn("currentProject cannot be null"); + return; + } + + String name = fileName; + + try { + Files.write(Paths.get("/tmp/" + name), this.content.getBytes()); + } catch (IOException e) { + e.printStackTrace(); + } + + + VirtualFile textFile = LocalFileSystem.getInstance().refreshAndFindFileByPath("/tmp/" + name); + if (textFile == null) { + return; + } + +// FileEditorManagerEx fileEditorManager = FileEditorManagerEx.getInstanceEx(currentProject); +// fileEditorManager.openFile(textFile, false); + LOG.info("image has been opened"); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/PluginVersion.java b/athena-all/src/main/java/run/mone/m78/ip/common/PluginVersion.java new file mode 100644 index 000000000..accaa8efd --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/PluginVersion.java @@ -0,0 +1,29 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.common; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/5 11:46 + */ +public class PluginVersion { + + @Override + public String toString() { + return "2021110500"; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/ProjectCache.java b/athena-all/src/main/java/run/mone/m78/ip/common/ProjectCache.java new file mode 100644 index 000000000..b4dc5d0d5 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/ProjectCache.java @@ -0,0 +1,32 @@ +package run.mone.m78.ip.common; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; + +import java.util.concurrent.ConcurrentHashMap; + +public class ProjectCache { + + public static ConcurrentHashMap keyMap = new ConcurrentHashMap<>(); + + public static void put(Project project, String key, Object value) { + project.putUserData(getUserDataKey(key), value); + } + + public static Object get(Project project, String key) { + return project.getUserData(getUserDataKey(key)); + } + + public static void invalidate(Project project, String key) { + project.putUserData(getUserDataKey(key), null); + } + + private static Key getUserDataKey(String keyName) { + return keyMap.compute(keyName, (k, v) -> { + if (null == v) { + return new Key(k); + } + return v; + }); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/Prompt.java b/athena-all/src/main/java/run/mone/m78/ip/common/Prompt.java new file mode 100644 index 000000000..0a570f5a2 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/Prompt.java @@ -0,0 +1,142 @@ +package run.mone.m78.ip.common; + +import com.google.gson.Gson; +import lombok.extern.slf4j.Slf4j; +import run.mone.m78.ip.bo.PromptInfo; +import run.mone.m78.ip.bo.Tag; +import run.mone.m78.ip.bo.ZAddrRes; +import run.mone.m78.ip.bo.ZPromptRes; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * @author goodjava@qq.com + * @author caobaoyu + * @date 2023/4/15 08:38 + */ +@Slf4j +public class Prompt { + + private static Map promptMap = new HashMap<>(); + + private static CopyOnWriteArrayList promptMeta = new CopyOnWriteArrayList<>(); + + private static String zAddr = ""; + + private static AtomicBoolean loadFinish = new AtomicBoolean(); + + public static String get(String key) { + return promptMap.get(key); + } + + public static List getPromptMeta() { + return promptMeta; + } + + public static boolean isLoadFinish() { + return loadFinish.get(); + } + + + private static Gson gson = new Gson(); + + public static void flush() { + init(); + } + + public static int size() { + return promptMap.size(); + } + + + public static void init() { + + } + + public static List getPrompt() { + return null; + } + + + public static PromptInfo getPrompt(int type, String name) { + return null; + } + + + /** + * 将Z的结果转换为实体 + * + * @param data + * @return + */ + private static List convertZResToInfo(List data) { + return null; + } + + public static List promptList(String tagName) { + return null; + } + + public static boolean containsTag(List tags, String tagName) { + return false; + } + + /** + * 查询是那种类型 + * + * @param info + * @return + */ + public static PromptType getPromptType(PromptInfo info) { + return null; + } + + + public static ZAddrRes zAddrRes() { + return null; + } + + private static void initConfig(ZAddrRes zAddrRes) { + + } + + + public static PromptInfo getPromptInfo(String promptName) { + return null; + } + + public static List getPromptInfoByTag(String tag) { + return null; + } + + public static List getCollected() { + return null; + } + + /** + * 获取使用次数最多的size个prompt + * + * @param size + * @return + */ + public static List getMostUsed(int size) { + return null; + } + + /** + * 获取某个标签下使用次数最多的size个prompt + * + * @param size + * @param tag + * @return + */ + public static List getMostUsed(int size, String tag) { + return null; + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/PromptType.java b/athena-all/src/main/java/run/mone/m78/ip/common/PromptType.java new file mode 100644 index 000000000..8c7a9c8a2 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/PromptType.java @@ -0,0 +1,41 @@ +package run.mone.m78.ip.common; + +/** + * @author goodjava@qq.com + * @date 2023/5/29 10:31 + */ +public enum PromptType { + + createClass("创建类"), + modifyClass("修改类"), + createMethod("创建方法"), + createMethod2("创建方法2(可以指定参数)"), + modifyMethod("修改方法"), + comment("添加注释"), + lineByLineComment("添加逐行注释(也可以用来给方法添加注释)"), + createFile("创建文件"), + select("进入选择流程(类和方法)"), + removeComment("删除注释"), + checkPomVersion("检查POM依赖版本"), + generateBootStrapAnno("给启动类添加注解"), + showInfo("展示信息到对话框<打字机效果>"), + createClass2("创建类2"), + createClass4("创建类(直接就生成一个完整的类)"), + testPrompt("在文本文件中测试prompt"), + repleaceSelectContent("替换选中的文本内容"), + genBizMethodCode("生成业务方法"), + inlayHint("镶嵌"), + bot("机器人指令"), + generateMethod("生成技术代码"), + generateMiapiMethod("根据miapi知识库生成某接口调用方法"), + generateTestMethod("生成测试代码"), + generateInterface("提取公共方法生成接口"), + question("ai会向你提问") + ; + + private String desc; + + PromptType(String desc) { + this.desc = desc; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/ProxyUtils.java b/athena-all/src/main/java/run/mone/m78/ip/common/ProxyUtils.java new file mode 100644 index 000000000..89df49934 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/ProxyUtils.java @@ -0,0 +1,19 @@ +package run.mone.m78.ip.common; + +import org.apache.commons.lang3.StringUtils; + +/** + * @author goodjava@qq.com + * @date 2023/5/19 22:25 + */ +public class ProxyUtils { + + public static String getProxy() { + String proxy = ConfigUtils.getConfig().getChatgptProxy(); + if (StringUtils.isEmpty(proxy)) { + return null; + } + return proxy; + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/Safe.java b/athena-all/src/main/java/run/mone/m78/ip/common/Safe.java new file mode 100644 index 000000000..d2e123e91 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/Safe.java @@ -0,0 +1,42 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.common; + +import lombok.extern.slf4j.Slf4j; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/2 11:28 + */ +@Slf4j +public class Safe { + + + public static void run(ExRunnable runnable) { + try { + runnable.run(); + } catch (Throwable ex) { + log.error(ex.getMessage(), ex); + } + } + + + public interface ExRunnable { + void run() throws Throwable; + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/StringUtils.java b/athena-all/src/main/java/run/mone/m78/ip/common/StringUtils.java new file mode 100644 index 000000000..f3694976f --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/StringUtils.java @@ -0,0 +1,21 @@ +package run.mone.m78.ip.common; + +/** + * @author goodjava@qq.com + * @date 2023/5/18 22:26 + */ +public abstract class StringUtils { + + public static String convertToCamelCase(String input) { + StringBuilder result = new StringBuilder(); + String[] words = input.split("_"); + result.append(words[0]); + for (int i = 1; i < words.length; i++) { + String word = words[i]; + String capitalizedWord = Character.toUpperCase(word.charAt(0)) + word.substring(1); + result.append(capitalizedWord); + } + return result.toString(); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/TeslaConfigurable.java b/athena-all/src/main/java/run/mone/m78/ip/common/TeslaConfigurable.java new file mode 100644 index 000000000..74d2a66a3 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/TeslaConfigurable.java @@ -0,0 +1,107 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.common; + +import com.google.gson.Gson; +import com.intellij.ide.util.PropertiesComponent; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.options.SearchableConfigurable; +import run.mone.m78.ip.bo.TeslaPluginConfig; +import run.mone.m78.ip.ui.ConfigUi; +import org.apache.commons.lang3.mutable.MutableBoolean; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import run.mone.ultraman.AthenaContext; + +import javax.swing.*; +import java.util.ArrayList; +import java.util.List; + +/** + * @author goodjava@qq.com + *

+ * 管理 + */ +public class TeslaConfigurable implements SearchableConfigurable { + + private ConfigUi configUi; + + private MutableBoolean modified = new MutableBoolean(false); + + + @NotNull + @Override + public String getId() { + return "Athena"; + } + + @Nls(capitalization = Nls.Capitalization.Title) + @Override + public String getDisplayName() { + return getId(); + } + + @Nullable + @Override + public JComponent createComponent() { + if (null == configUi) { + configUi = new ConfigUi(modified); + } + return configUi.getContentPane(); + } + + @Override + public boolean isModified() { + return configUi.getModified().getValue(); + } + + @Override + public void apply() { + TeslaPluginConfig config = new TeslaPluginConfig(); + String oldServer = config.getDashServer(); + config.setDashServer(configUi.getDashServerTextField().getText()); + if (null != config.getDashServer() && (null == oldServer || !config.getDashServer().equals(oldServer))) { + Safe.run(() -> { + if (null != AthenaContext.ins().getAthenaTreeKeyAdapter()) { + AthenaContext.ins().getAthenaTreeKeyAdapter().loadMone(config.getDashServer(), "mone"); + } + }); + } + config.setNickName(configUi.getNickNameTextField().getText()); + config.setzToken(configUi.getzTokenPassword().getText().trim()); + config.setAiProxy(configUi.getAiProxyTextField().getText().trim()); + if (configUi.getModelComboBox().getModel().getSize() > 0 && null != configUi.getModelComboBox().getSelectedItem()) { + config.setModel(configUi.getModelComboBox().getSelectedItem().toString()); + AthenaContext.ins().setGptModel(config.getModel()); + } + ComboBoxModel model = configUi.getModelComboBox().getModel(); + List list = new ArrayList<>(); + for (int i = 0; i < model.getSize(); i++) { + list.add(model.getElementAt(i).toString()); + } + config.setModelList(list); + PropertiesComponent.getInstance().setValue("", new Gson().toJson(config)); + configUi.getModified().setValue(false); + + new Thread(Prompt::flush).start(); + + ApplicationManager.getApplication().getMessageBus() + .syncPublisher(UltramanNotifier.ULTRAMAN_ACTION_TOPIC).onEvent(new UltramanEvent("save_config", "")); + + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/UltramanEvent.java b/athena-all/src/main/java/run/mone/m78/ip/common/UltramanEvent.java new file mode 100644 index 000000000..563b88143 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/UltramanEvent.java @@ -0,0 +1,52 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.common; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/6 18:16 + */ +public class UltramanEvent { + + private String cmd; + + private Object data; + + public UltramanEvent(String cmd, Object data) { + this.cmd = cmd; + this.data = data; + } + + public UltramanEvent() { + } + + public String getCmd() { + return cmd; + } + + public void setCmd(String cmd) { + this.cmd = cmd; + } + + public Object getData() { + return data; + } + + public void setData(Object data) { + this.data = data; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/UltramanNotifier.java b/athena-all/src/main/java/run/mone/m78/ip/common/UltramanNotifier.java new file mode 100644 index 000000000..fa09a69a2 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/common/UltramanNotifier.java @@ -0,0 +1,31 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.common; + +import com.intellij.util.messages.Topic; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/6 17:59 + */ +public interface UltramanNotifier { + + public static Topic ULTRAMAN_ACTION_TOPIC = Topic.create("UltramanTopic", UltramanNotifier.class); + + void onEvent(UltramanEvent event); + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/component/ChatComponent.java b/athena-all/src/main/java/run/mone/m78/ip/component/ChatComponent.java new file mode 100644 index 000000000..5d3b09dd9 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/component/ChatComponent.java @@ -0,0 +1,46 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.component; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.project.Project; +import run.mone.m78.ip.ui.ChatUi; + +/** + * @author goodjava@qq.com + * 聊天组件 + */ +public class ChatComponent implements ApplicationComponent { + + + @Override + public String getComponentName() { + return "ChatComponent"; + } + + public void show(Project project, AnActionEvent anActionEvent) { + ChatUi dialog = new ChatUi(anActionEvent); + dialog.addWindowListener(dialog); + dialog.setSize(600, 400); + dialog.setLocationRelativeTo(null); + dialog.setVisible(true); + dialog.setResizable(false); + dialog.requestFocus(); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/component/CreateProjectComponent.java b/athena-all/src/main/java/run/mone/m78/ip/component/CreateProjectComponent.java new file mode 100644 index 000000000..75385dd22 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/component/CreateProjectComponent.java @@ -0,0 +1,45 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.component; + +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.project.Project; +import run.mone.m78.ip.ui.CodeGeneratorUi; + +/** + * @author goodjava@qq.com + */ +public class CreateProjectComponent implements ApplicationComponent { + + + @Override + public String getComponentName() { + return "CreateProjectComponent"; + } + + + public void show(Project project) { + CodeGeneratorUi dialog = new CodeGeneratorUi(project); + dialog.setLocationRelativeTo(null); + dialog.setVisible(true); + dialog.setResizable(true); + dialog.setSize(600, 400); + dialog.requestFocus(); + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/component/CreateSpringBootProjectComponent.java b/athena-all/src/main/java/run/mone/m78/ip/component/CreateSpringBootProjectComponent.java new file mode 100644 index 000000000..11fecba86 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/component/CreateSpringBootProjectComponent.java @@ -0,0 +1,44 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.component; + +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.project.Project; +import run.mone.m78.ip.ui.SpringBootProGenerator; + +/** + * @author goodjava@qq.com + */ +public class CreateSpringBootProjectComponent implements ApplicationComponent { + + + @Override + public String getComponentName() { + return "CreateSpringBootProjectComponent"; + } + + + public void show(Project project) { + SpringBootProGenerator dialog = new SpringBootProGenerator(project); + dialog.setSize(600, 400); + dialog.setLocationRelativeTo(null); + dialog.setVisible(true); + dialog.setResizable(false); + dialog.requestFocus(); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/component/FilterComponent.java b/athena-all/src/main/java/run/mone/m78/ip/component/FilterComponent.java new file mode 100644 index 000000000..2cf797090 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/component/FilterComponent.java @@ -0,0 +1,39 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.component; + +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.project.Project; +import run.mone.m78.ip.ui.FilterUi; + +public class FilterComponent implements ApplicationComponent { + + + @Override + public String getComponentName() { + return "FilterComponent"; + } + + public void show(Project project) { + FilterUi dialog = new FilterUi(project); + dialog.setSize(600, 400); + dialog.setLocationRelativeTo(null); + dialog.setVisible(true); + dialog.setResizable(false); + dialog.requestFocus(); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/component/NaviComponent.java b/athena-all/src/main/java/run/mone/m78/ip/component/NaviComponent.java new file mode 100644 index 000000000..bcc8eaae9 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/component/NaviComponent.java @@ -0,0 +1,43 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.component; + +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.project.Project; +import run.mone.m78.ip.ui.NaviUi; + +/** + * @author goodjava@qq.com + */ +public class NaviComponent implements ApplicationComponent { + + + @Override + public String getComponentName() { + return "NaviComponent"; + } + + public void show(Project project) { + NaviUi dialog = new NaviUi(); + dialog.setSize(600, 200); + dialog.setLocationRelativeTo(null); + dialog.setVisible(true); + dialog.setResizable(false); +// dialog.requestFocus(); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/component/PluginComponent.java b/athena-all/src/main/java/run/mone/m78/ip/component/PluginComponent.java new file mode 100644 index 000000000..c2d307e63 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/component/PluginComponent.java @@ -0,0 +1,45 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.component; + +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.project.Project; +import run.mone.m78.ip.ui.BuildUi; + +/** + * @author goodjava@qq.com + */ +public class PluginComponent implements ApplicationComponent { + + + @Override + public String getComponentName() { + return "PluginComponent"; + } + + public void show(Project project) { + String projectName = project.getName(); + String basePath = project.getBasePath(); + BuildUi dialog = new BuildUi(projectName,basePath); + dialog.setSize(600, 800); + dialog.setLocationRelativeTo(null); + dialog.setVisible(true); + dialog.setResizable(false); + dialog.requestFocus(); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/component/TeslaAppComponent.java b/athena-all/src/main/java/run/mone/m78/ip/component/TeslaAppComponent.java new file mode 100644 index 000000000..8d0233f94 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/component/TeslaAppComponent.java @@ -0,0 +1,327 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.component; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.intellij.AppTopics; +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.event.*; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.FileEditorManagerListener; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiJavaFile; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.util.PsiUtilBase; +import com.intellij.util.Consumer; +import com.intellij.util.messages.MessageBus; +import com.intellij.util.messages.MessageBusConnection; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; +import run.mone.m78.ip.bo.*; +import run.mone.m78.ip.common.*; +import run.mone.m78.ip.service.CodeService; +import run.mone.m78.ip.service.UltramanService; +import run.mone.m78.ip.util.ProjectUtils; +import run.mone.ultraman.bo.ParamsInfo; +import run.mone.ultraman.event.AthenaEventBus; +import run.mone.ultraman.listener.AthenaFileDocumentManagerListener; +import run.mone.ultraman.listener.AthenaFileEditorManagerListener; +import run.mone.ultraman.listener.AthenaMessageListenerImpl; +import run.mone.ultraman.service.AutoFlushBizService; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + */ +public class TeslaAppComponent implements ApplicationComponent { + + private static final Logger logger = Logger.getInstance(OpenImageConsumer.class); + + private boolean open = false; + + @Override + public void initComponent() { + UltramanService.getInstance().init(); + + MessageBus bus = ApplicationManager.getApplication().getMessageBus(); + @NotNull MessageBusConnection connection = bus.connect(); + connection.subscribe(AppTopics.FILE_DOCUMENT_SYNC, new AthenaFileDocumentManagerListener()); + connection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, new AthenaFileEditorManagerListener()); + connection.subscribe(Const.ATHENA_TOPIC, new AthenaMessageListenerImpl()); + EditorFactory.getInstance().addEditorFactoryListener(new EditorFactoryListener() { + @Override + public void editorCreated(@NotNull EditorFactoryEvent event) { + event.getEditor().getSelectionModel().addSelectionListener(new SelectionListener() { + @Override + public void selectionChanged(@NotNull SelectionEvent e) { + if (AthenaEventBus.ins().getListener().getParamsInfoConsumer() != null) { + Document document = e.getEditor().getDocument(); + PsiFile psiFile = PsiUtilBase.getPsiFileInEditor(e.getEditor(), e.getEditor().getProject()); + if (psiFile instanceof PsiJavaFile) { + String selectedText = document.getText(e.getNewRange()); + if (StringUtils.isNotEmpty(selectedText)) { + PsiMethod method = CodeService.getMethod(e.getEditor().getProject()); + if (null != method) { + List list = Arrays.stream(method.getParameterList().getParameters()).map(it -> it.getType().getCanonicalText()).collect(Collectors.toList()); + ParamsInfo info = new ParamsInfo(); + info.setParams(new Gson().toJson(list)); + AthenaEventBus.ins().post(info); + } + } + } + } + } + }); + } + }); + EditorFactory.getInstance().getEventMulticaster().addDocumentListener(new DocumentListener() { + @Override + public void documentChanged(@NotNull DocumentEvent event) { + Document document = event.getDocument(); + VirtualFile file = FileDocumentManager.getInstance().getFile(document); + AutoFlushBizService.notifyDocumentChanged(file); + + int offset = event.getOffset(); + int newLength = event.getNewLength(); +// System.out.printf("%d %d %d %d%n", event.getOldLength(), event.getNewLength(), event.getMoveOffset(), document.getTextLength()); + // actual logic depends on which line we want to call 'changed' when '\n' is inserted + int firstLine = document.getLineNumber(offset); + int lastLine = newLength == 0 ? firstLine : document.getLineNumber(offset + newLength <= document.getTextLength() ? offset + newLength : offset + newLength - 1); + if (firstLine == lastLine) { + return; + } + String last = document.getText().substring(document.getLineStartOffset(firstLine), document.getLineEndOffset(firstLine)); +// System.out.printf("new line %d %d %s%n", firstLine, lastLine, last); + if (!last.contains("//#:")) { + return; + } + last = last.trim(); + String all = document.getText(); + String[] codeReq = last.split("//#:"); + Map paramMap = new HashMap<>(); + paramMap.put("full_code", all); + paramMap.put("origin_code", last); + paramMap.put("requirements", codeReq[1]); + CodeService.generateCodeWithAi5(GenerateCodeReq.builder().build(), ProjectUtils.project(), "call_rika", null, paramMap, new AthenaBiConsumer(), new MessageConsumer() { + public void onEvent(AiMessage message) { + String x = message.getText(); + try { + ObjectMapper mapper = new ObjectMapper(); + JsonNode node = mapper.readTree(x); + String params = node.at("/arguments").asText(); + node = mapper.readTree(params); + String tf = node.at("/fixedCodes").asText(); + String to = node.at("/originalCodes").asText(); + List parsed = parse(to, tf); + String fixed = parsed.get(1); + String origin = parsed.get(0); + if (!to.contains("\n")) { + fixed = fixed.replace("\n", " "); + } + String finalFixed = fixed; + ApplicationManager.getApplication().invokeLater(() -> { + document.setText(document.getText().replace(origin, finalFixed)); + }); + } catch (Exception e) { + + } + } + }); + } + }); + if (!open) { + return; + } + String chatServer = ConfigUtils.getConfig().getChatServer(); + //处理接收到的信息 + new Thread(() -> { + try { + if (StringUtils.isEmpty(chatServer)) { + return; + } + + } catch (Throwable ex) { + logger.error(ex.getMessage(), ex); + } + + }).start(); + + + new Thread(() -> { + while (true) { + Map message = MessageQueue.ins().pollSend(); + if (null != message) { + Map m = new HashMap<>(10); + m.put("uri", "/mtop/arch/im"); + m.putAll(message); + } + } + }).start(); + + } + + private List parse(String str1, String str2) { + str1 = str1.trim(); + str2 = str2.trim(); + int start = 0; + int end = 0; + for (; start < str1.length() && start < str2.length(); start++) { + if (str1.charAt(start) != str2.charAt(start)) { + break; + } + } + for (; end < str1.length() && end < str2.length(); end++) { + if (str1.charAt(str1.length() - 1 - end) != str2.charAt(str2.length() - 1 - end)) { + break; + } + } + List res = new ArrayList<>(); + res.add(str1.substring(start, str1.length() - end).trim()); + res.add(str2.substring(start, str2.length() - end).trim()); + return res; + } + + @NotNull + private java.util.function.Consumer messageConsumer() { + return msg -> { + + logger.info("message consumer msg:" + msg); + final Map m = new Gson().fromJson(msg, Map.class); + + if (null == m || null == m.get("cmd")) { + logger.warn("msg:" + m); + return; + } + + try { + //收到通知 + if (m.get("cmd").toString().equals("notify")) { + String data = m.get("data").toString(); + logger.info("notify:" + data); + + ApplicationManager.getApplication().invokeLater(() -> { + Messages.showMessageDialog(data, "notify", Messages.getInformationIcon()); + }); + return; + } + + if (m.get("cmd").toString().equals("login")) { + Response> response = new Gson().fromJson(msg, new TypeToken>>() { + }.getType()); + MessageQueue.ins().offer(response); + return; + } + + //有人加入聊天室 + if (m.get("cmd").toString().toUpperCase().equals("login_user_info")) { + Response response = new Gson().fromJson(msg, new TypeToken>() { + }.getType()); + MessageQueue.ins().offer(response); + return; + } + + if (m.get("cmd").toString().equals("talk_message")) { + talk(msg); + return; + } + + //打开推广 + if (m.get("cmd").toString().equals("ad")) { + openAd(m); + return; + } + + //打开文本 + if (m.get("cmd").toString().equals("review")) { + openText(m); + return; + } + + if (m.get("cmd").toString().equals("logout_msg")) { + Response response = new Gson().fromJson(msg, new TypeToken>() { + }.getType()); + MessageQueue.ins().offer(response); + return; + } + } catch (Exception ex) { + logger.error(ex.getMessage(), ex); + } + }; + } + + private void talk(String msg) { + try { + Response response = new Gson().fromJson(msg, new TypeToken>() { + }.getType()); + MessageQueue.ins().offer(response); + } catch (Exception ex) { + System.out.println("talk ex:" + ex.getMessage()); + } + } + + /** + * 打开广告 + * + * @param m + */ + private void openAd(Map m) { + ApplicationManager.getApplication().invokeLater(() -> { + + DataManager.getInstance().getDataContextFromFocusAsync().onSuccess(new java.util.function.Consumer() { + @Override + public void accept(DataContext dataContext) { + new OpenImageConsumer(m.get("data").toString()).accept(dataContext); + } + }); + +// DataManager.getInstance().getDataContextFromFocus() +// .doWhenDone((Consumer) (dataContext -> new OpenImageConsumer(m.get("data").toString()).accept(dataContext))) +// .doWhenRejected((Consumer) logger::error); + + }); + } + + + /** + * 打开文本 + */ + private void openText(Map m) { + List list = (List) m.get("data"); + + ApplicationManager.getApplication().invokeLater(() -> { + + DataManager.getInstance().getDataContextFromFocus() + .doWhenDone((Consumer) (dataContext -> + new OpenTextConsumer(list.get(0), list.get(1)).accept(dataContext))) + .doWhenRejected((Consumer) logger::error); + + }); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/component/UltramanComponent.java b/athena-all/src/main/java/run/mone/m78/ip/component/UltramanComponent.java new file mode 100644 index 000000000..30ffb9493 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/component/UltramanComponent.java @@ -0,0 +1,46 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.component; + +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.project.Project; +import run.mone.m78.ip.ui.UltramanUi; + +/** + * @Author goodjava@qq.com + * @Date 2021/10/31 19:17 + */ +public class UltramanComponent implements ApplicationComponent { + + + @Override + public String getComponentName() { + return "UltramanComponent"; + } + + + + public void show(Project project) { + UltramanUi dialog = new UltramanUi(); + dialog.setSize(600, 800); + dialog.setLocationRelativeTo(null); + dialog.setVisible(true); + dialog.setResizable(false); + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/component/VersionComponent.java b/athena-all/src/main/java/run/mone/m78/ip/component/VersionComponent.java new file mode 100644 index 000000000..65a4b34e3 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/component/VersionComponent.java @@ -0,0 +1,43 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.component; + +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.project.Project; +import run.mone.m78.ip.ui.VersionUi; + +/** + * @author goodjava@qq.com + */ +public class VersionComponent implements ApplicationComponent { + + + @Override + public String getComponentName() { + return "VersionComponent"; + } + + public void show(Project project) { + VersionUi dialog = new VersionUi(); + dialog.setSize(600, 200); + dialog.setLocationRelativeTo(null); + dialog.setVisible(true); + dialog.setResizable(false); + dialog.requestFocus(); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/component/project/AthenaProjectComment.java b/athena-all/src/main/java/run/mone/m78/ip/component/project/AthenaProjectComment.java new file mode 100644 index 000000000..a3791e924 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/component/project/AthenaProjectComment.java @@ -0,0 +1,71 @@ +package run.mone.m78.ip.component.project; + + +import com.intellij.ide.projectView.ProjectView; +import com.intellij.ide.projectView.impl.ProjectViewPane; +import com.intellij.ide.projectView.impl.ProjectViewTree; +import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.project.Project; +import run.mone.m78.ip.common.NotificationCenter; +import org.jetbrains.annotations.NotNull; + +import javax.swing.tree.TreePath; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.concurrent.TimeUnit; + +/** + * @author goodjava@qq.com + * @date 2023/6/23 21:13 + */ +public class AthenaProjectComment implements ProjectComponent { + + + private Project project; + + public AthenaProjectComment(Project project) { + this.project = project; + } + + @Override + public void projectOpened() { + ProjectView projectView = ProjectView.getInstance(project); + new Thread(() -> { + int i = 200; + for (; i > 0; i--) { + ProjectViewPane projectViewPane = (ProjectViewPane) projectView.getCurrentProjectViewPane(); + if (projectViewPane != null) { + ProjectViewTree projectViewTree = (ProjectViewTree) projectViewPane.getTree(); + projectViewTree.addTreeSelectionListener(new AthenaTreeSelectionListener()); + projectViewTree.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2) { + ProjectViewTree t = projectViewTree; + TreePath treePath = t.getSelectionPath(); + AthenaTreeSelectionListener.selectTreeNode(treePath); + } + } + }); + NotificationCenter.notice(this.project, "tree listener init finish", true); + break; + } + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + }).start(); + } + + + @Override + public void projectClosed() { + } + + @Override + public @NotNull String getComponentName() { + return "AthenaProjectComment"; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/component/project/AthenaTreeSelectionListener.java b/athena-all/src/main/java/run/mone/m78/ip/component/project/AthenaTreeSelectionListener.java new file mode 100644 index 000000000..e91669c28 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/component/project/AthenaTreeSelectionListener.java @@ -0,0 +1,73 @@ +package run.mone.m78.ip.component.project; + +import com.intellij.ide.projectView.impl.nodes.ClassTreeNode; +import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode; +import com.intellij.psi.JavaDirectoryService; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiPackage; +import run.mone.m78.ip.bo.ClassInfo; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.Nullable; +import run.mone.ultraman.bo.PackageInfo; +import run.mone.ultraman.event.AthenaEventBus; + +import javax.swing.*; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreePath; + +/** + * @author goodjava@qq.com + * @date 2023/6/24 21:15 + */ +public class AthenaTreeSelectionListener implements TreeSelectionListener { + + + public static void selectTreeNode(TreePath path) { + if (null != path.getLastPathComponent() && path.getLastPathComponent() instanceof DefaultMutableTreeNode node) { + Object userObject = node.getUserObject(); + if (null != userObject) { + if (userObject instanceof PsiDirectoryNode pdn) { + PsiDirectory pd = pdn.getValue(); + if (null != pd) { + @Nullable PsiPackage psiPackage = JavaDirectoryService.getInstance().getPackage(pd); + if (null != psiPackage) { + String name = psiPackage.getQualifiedName(); + if (StringUtils.isNotEmpty(name) && AthenaEventBus.ins().getListener().getPackageConsumer() != null) { + PackageInfo pi = new PackageInfo(); + pi.setName(name); + int result = JOptionPane.showConfirmDialog(null, "Are you sure?", "Confirmation", JOptionPane.YES_NO_OPTION); + if (result == JOptionPane.YES_OPTION) { + AthenaEventBus.ins().post(pi); + } + } + } + } + } + + if (userObject instanceof ClassTreeNode ctn) { + PsiClass pc = ctn.getValue(); + if (null != pc) { + String name = pc.getQualifiedName(); + if (StringUtils.isNotEmpty(name) && AthenaEventBus.ins().getListener().getClassConsumer() != null) { + ClassInfo ci = ClassInfo.builder().className(pc.getQualifiedName()).build(); + AthenaEventBus.ins().post(ci); + } + } + } + } + + } + } + + + @Override + public void valueChanged(TreeSelectionEvent treeSelectionEvent) { + if (false) { + TreePath path = treeSelectionEvent.getPath(); + selectTreeNode(path); + } + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/consumer/CodeConsumer.java b/athena-all/src/main/java/run/mone/m78/ip/consumer/CodeConsumer.java new file mode 100644 index 000000000..f0a9cb23a --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/consumer/CodeConsumer.java @@ -0,0 +1,33 @@ +package run.mone.m78.ip.consumer; + +import com.intellij.openapi.editor.Editor; +import run.mone.m78.ip.bo.AiMessage; +import run.mone.m78.ip.bo.GenerateCodeReq; +import run.mone.m78.ip.bo.MessageConsumer; +import run.mone.m78.ip.service.CodeService; + +/** + * @author goodjava@qq.com + * @date 2023/7/16 09:25 + */ +public class CodeConsumer extends MessageConsumer { + + private Editor editor; + + private GenerateCodeReq req; + + public CodeConsumer(Editor editor, GenerateCodeReq req) { + this.editor = editor; + this.req = req; + } + + @Override + public void onEvent(AiMessage message) { + CodeService.writeCode4(req.getProject(), editor, message.getText(), false); + } + + @Override + public void end(AiMessage message) { + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/consumer/FinishConsumer.java b/athena-all/src/main/java/run/mone/m78/ip/consumer/FinishConsumer.java new file mode 100644 index 000000000..cabfdf786 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/consumer/FinishConsumer.java @@ -0,0 +1,32 @@ +package run.mone.m78.ip.consumer; + +import run.mone.m78.ip.bo.AiMessage; +import run.mone.m78.ip.bo.MessageConsumer; + +/** + * @author goodjava@qq.com + * @date 2023/7/23 11:43 + */ +public class FinishConsumer extends MessageConsumer { + + private StringBuilder sb = new StringBuilder(); + + @Override + public void begin(AiMessage message) { + super.begin(message); + } + + @Override + public void onEvent(AiMessage message) { + sb.append(message.getText()); + } + + public String getContent() { + return this.sb.toString(); + } + + @Override + public void end(AiMessage message) { + + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/dialog/AthenaTableCellEditor.java b/athena-all/src/main/java/run/mone/m78/ip/dialog/AthenaTableCellEditor.java new file mode 100644 index 000000000..37012557f --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/dialog/AthenaTableCellEditor.java @@ -0,0 +1,219 @@ +package run.mone.m78.ip.dialog; + +import com.google.common.base.Joiner; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import run.mone.m78.ip.bo.ClassInfo; +import run.mone.m78.ip.bo.CreateClassRes; +import run.mone.m78.ip.bo.Message; +import run.mone.m78.ip.bo.prompt.PromptParamType; +import run.mone.m78.ip.ui.CreateClassUi; +import run.mone.m78.ip.util.ProjectUtils; +import run.mone.m78.ip.bo.PromptInfo; +import run.mone.m78.ip.bo.prompt.PromptParam; +import run.mone.m78.ip.common.Const; +import run.mone.m78.ip.util.LabelUtils; +import lombok.Setter; +import org.apache.commons.lang3.StringUtils; +import run.mone.ultraman.bo.PackageInfo; +import run.mone.ultraman.bo.ParamsInfo; +import run.mone.ultraman.event.AthenaEventBus; +import run.mone.ultraman.event.ConsumerBo; + +import javax.swing.*; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableCellEditor; +import java.awt.*; +import java.util.function.Consumer; + +/** + * @author goodjava@qq.com + * @author caobaoyu + * @date 2023/6/15 14:02 + */ +public class AthenaTableCellEditor extends AbstractCellEditor implements TableCellEditor { + + private JComboBox comboBox; + + private JTextField textField; + + private JButton button; + + private JLabel label; + + private PromptInfo promptInfo; + + @Setter + private DialogWrapper dialogWrapper; + + @Setter + private DefaultTableModel tableModel; + + private Object value; + + /** + * 有若干列是combox + * + * @param project + * @param promptInfo + */ + public AthenaTableCellEditor(Project project, PromptInfo promptInfo) { + this.promptInfo = promptInfo; + this.textField = new JTextField(); + this.button = new JButton(); + this.label = new JLabel(); + this.comboBox = new JComboBox(); + addListenerToJComboBox(this.comboBox, project); + } + + + private void addListenerToJComboBox(JComboBox c, Project project) { + c.addActionListener(e -> { + JComboBox comboBox = (JComboBox) e.getSource(); + String selectedOption = (String) comboBox.getSelectedItem(); + + //创建类 + if (selectedOption.equals("New")) { + String packageStr = LabelUtils.getLabelValue(project, this.promptInfo, Const.REQ_PACKAGE, ""); + CreateClassUi createClassUi = new CreateClassUi(project, ProjectUtils.listAllModules(project), ProjectUtils.getCurrentModudleName(project), packageStr); + createClassUi.show(); + CreateClassRes res = createClassUi.getRes(); + if (res.getCode() != DialogWrapper.OK_EXIT_CODE) { + return; + } + String value = Joiner.on(".").join(res.getPackageStr(), res.getClassName()); + comboBox.addItem(value); + comboBox.setSelectedItem(value); + } + + if (selectedOption.equals("Params")) { + ConsumerBo bo = new ConsumerBo(); + bo.setType("params"); + this.dialogWrapper.getRootPane().getParent().setVisible(false); + bo.setConsumer((Consumer) (p) -> SwingUtilities.invokeLater(() -> { + if (this.value instanceof PromptParam pp) { + pp.getList().add(p.getParams()); + pp.setValue(p.getParams()); + } + this.dialogWrapper.getRootPane().getParent().setVisible(true); + })); + AthenaEventBus.ins().post(bo); + } + + //选择包路径 + if (selectedOption.equals("Select")) { + int result = JOptionPane.showConfirmDialog(null, Message.selectPackage, "Confirmation", JOptionPane.YES_NO_OPTION); + if (result != JOptionPane.YES_OPTION) { + return; + } + this.dialogWrapper.getRootPane().getParent().setVisible(false); + ConsumerBo bo = new ConsumerBo(); + + String subType = "package"; + if (this.value instanceof PromptParam pp) { + if (StringUtils.isNotEmpty(pp.getSubType())) { + subType = pp.getSubType(); + } + } + if (subType.equals("package")) { + bo.setType("package"); + bo.setConsumer((Consumer) (p) -> SwingUtilities.invokeLater(() -> { + if (this.value instanceof PromptParam pp) { + pp.getList().add(p.getName()); + pp.setValue(p.getName()); + } + this.dialogWrapper.getRootPane().getParent().setVisible(true); + })); + } + if (subType.equals("class")) { + bo.setType("class"); + bo.setConsumer((Consumer) (p) -> SwingUtilities.invokeLater(() -> { + if (this.value instanceof PromptParam pp) { + pp.getList().add(p.getName()); + pp.setValue(p.getName()); + } + this.dialogWrapper.getRootPane().getParent().setVisible(true); + })); + } + AthenaEventBus.ins().post(bo); + } + + if (selectedOption.equals("Select2")) { + DirectoryTreeDialog dialog = new DirectoryTreeDialog(project); + dialog.show(); + String selectedPath = dialog.getResult().getData().get("package"); + comboBox.addItem(selectedPath); + comboBox.setSelectedItem(selectedPath); + String modulePath = dialog.getResult().getData().get("module"); + addModuleRow(modulePath); + } + }); + } + + + @Override + public Object getCellEditorValue() { + if (this.value instanceof PromptParam pp) { + if (pp.getType().equals(PromptParamType.comboBox.name()) || pp.getType().equals(PromptParamType.code.name()) || pp.getType().equals(PromptParamType.params.name())) { + pp.setValue(this.comboBox.getSelectedItem().toString()); + } + if (pp.getType().equals(PromptParamType.textField.name())) { + pp.setValue(this.textField.getText().trim()); + } + return this.value; + } + return this.textField.getText(); + } + + @Override + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { + this.value = value; + if (this.value instanceof PromptParam pp) { + String type = pp.getType(); + if (type.equals(PromptParamType.button.name())) { + this.button.setText(pp.getValue()); + return this.button; + } + if (type.equals(PromptParamType.textField.name())) { + this.textField.setText(pp.getValue()); + return this.textField; + } + if (type.equals(PromptParamType.comboBox.name()) || type.equals(PromptParamType.code.name()) || type.equals(PromptParamType.params.name())) { + this.comboBox.setModel(new DefaultComboBoxModel(pp.getList().toArray(new String[0]))); + return this.comboBox; + } + if (type.equals(PromptParamType.label.name()) || type.equals(PromptParamType.editor.name())) { + this.label.setText(pp.getValue()); + return this.label; + } + } + this.textField.setText(this.value.toString()); + return this.textField; + + } + + private void addModuleRow(String modulePath) { + int rowCount = tableModel.getRowCount(); + boolean moduleExists = false; + int moduleRow = -1; + + // 遍历表格中的每一行,查找是否已经存在该module + for (int i = 0; i < rowCount; i++) { + String currentModule = (String) tableModel.getValueAt(i, 0); + if (currentModule.equals("module")) { + moduleExists = true; + moduleRow = i; + break; + } + } + + // 如果存在,则更新对应的modulePath + if (moduleExists) { + tableModel.setValueAt(modulePath, moduleRow, 1); + } else { + // 否则添加新的一行 + tableModel.addRow(new Object[]{"module", modulePath}); + } + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/dialog/ChromeDialog.java b/athena-all/src/main/java/run/mone/m78/ip/dialog/ChromeDialog.java new file mode 100644 index 000000000..b92f973f6 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/dialog/ChromeDialog.java @@ -0,0 +1,103 @@ +package run.mone.m78.ip.dialog; + +import com.intellij.openapi.application.ApplicationInfo; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.ui.jcef.JBCefApp; +import com.intellij.ui.jcef.JBCefBrowser; +import com.intellij.ui.jcef.JBCefClient; +import run.mone.m78.ip.listener.ChromeMessageRouterHandler; +import run.mone.m78.ip.util.ScreenSizeUtils; +import org.cef.browser.CefBrowser; +import org.cef.browser.CefFrame; +import org.cef.browser.CefMessageRouter; +import org.cef.callback.CefQueryCallback; +import org.cef.handler.CefMessageRouterHandlerAdapter; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.awt.*; +import java.util.HashMap; +import java.util.Map; + + +/** + * @author caobaoyu + * @description: + * @date 2023-06-13 16:42 + */ +public class ChromeDialog extends DialogWrapper { + + private String url; + + public static Map browserMap = new HashMap<>(); + + private Project project; + + private boolean hasHttpRequest; + + public ChromeDialog(String url, Project project) { + super(true); + this.url = url; + this.project = project; + this.hasHttpRequest = false; + init(); + setTitle("Chrome Browser"); + } + + + @Override + protected @Nullable JComponent createCenterPanel() { + JBCefBrowser browser = null; + JPanel webPanel = new JPanel(); + if (JBCefApp.isSupported()) { + if (System.getProperty("os.name").contains("Linux")) { + browser = JBCefBrowser.createBuilder().setOffScreenRendering(true).build(); + } else if (ApplicationInfo.getInstance().getBuild().asStringWithoutProductCode().startsWith("23")) { + browser = JBCefBrowser.createBuilder().setOffScreenRendering(false).build(); + } else { + browser = new JBCefBrowser(); + } + } + browser.loadURL(url); + browserMap.put(this.project.getName(),browser); + @NotNull JBCefClient client = browser.getJBCefClient(); + + //右键菜单 + CefMessageRouter cmr = CefMessageRouter.create(new CefMessageRouter.CefMessageRouterConfig("cef", "cefCancel")); + cmr.addHandler(new CefMessageRouterHandlerAdapter() { + @Override + public boolean onQuery(CefBrowser browser, CefFrame frame, long queryId, String request, boolean persistent, CefQueryCallback callback) { + if (request.indexOf("click:") == 0) { + hasHttpRequest = true; + closeDialog(); + } + // 返回false表示不拦截该请求,继续传递给其他处理器处理 + return false; + } + }, true); + cmr.addHandler(new ChromeMessageRouterHandler(project), false); + client.getCefClient().addMessageRouter(cmr); + + webPanel.add(browser.getComponent(), BorderLayout.CENTER); + webPanel.setSize(ScreenSizeUtils.size()); + webPanel.setVisible(true); + return webPanel; + } + + @Override + protected Action[] createActions() { + return new Action[0]; + } + + private void closeDialog() { + SwingUtilities.invokeLater(() -> { + ApplicationManager.getApplication().invokeLater(() -> { + close(DialogWrapper.OK_EXIT_CODE); + }); + }); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/dialog/DialogContext.java b/athena-all/src/main/java/run/mone/m78/ip/dialog/DialogContext.java new file mode 100644 index 000000000..d968f744f --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/dialog/DialogContext.java @@ -0,0 +1,15 @@ +package run.mone.m78.ip.dialog; + +import com.intellij.openapi.module.Module; +import lombok.Data; + +/** + * @author goodjava@qq.com + * @date 2023/5/16 10:08 + */ +@Data +public class DialogContext { + + private Module module; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/dialog/DialogReq.java b/athena-all/src/main/java/run/mone/m78/ip/dialog/DialogReq.java new file mode 100644 index 000000000..037dbea20 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/dialog/DialogReq.java @@ -0,0 +1,28 @@ +package run.mone.m78.ip.dialog; + +import com.intellij.openapi.module.Module; +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/5/15 16:01 + */ +@Data +@Builder +public class DialogReq implements Serializable { + + private String cmd; + + private Module module; + + private String name; + + private String type; + + @Builder.Default + private boolean createMethod = true; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/dialog/DialogResult.java b/athena-all/src/main/java/run/mone/m78/ip/dialog/DialogResult.java new file mode 100644 index 000000000..3c03070ff --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/dialog/DialogResult.java @@ -0,0 +1,25 @@ +package run.mone.m78.ip.dialog; + +import lombok.Data; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +/** + * @author goodjava@qq.com + * @date 2023/5/15 16:00 + */ +@Data +public class DialogResult implements Serializable { + + private int code; + + private String cmd; + + private String message; + + private Map data = new HashMap<>(); + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/dialog/DirectoryTreeDialog.java b/athena-all/src/main/java/run/mone/m78/ip/dialog/DirectoryTreeDialog.java new file mode 100644 index 000000000..7df5af0f8 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/dialog/DirectoryTreeDialog.java @@ -0,0 +1,126 @@ +package run.mone.m78.ip.dialog; + +import com.intellij.icons.AllIcons; +import com.intellij.ide.util.treeView.NodeRenderer; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.ComboBox; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.components.JBScrollPane; +import com.intellij.ui.treeStructure.Tree; +import run.mone.m78.ip.util.ProjectUtils; +import run.mone.m78.ip.util.ScreenSizeUtils; +import lombok.Getter; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import java.util.List; + + +/** + * @author goodjava@qq.com + * @author caobaoyu + * @date 2023/7/13 + * 弹出一个包路径树 + */ +public class DirectoryTreeDialog extends DialogWrapper { + + private final ComboBox moduleComboBox; + private final Tree tree; + private final JBScrollPane scrollPane; + + @Getter + private final DialogResult result = new DialogResult(); + + public DirectoryTreeDialog(Project project) { + super(project, false); + List moduleList = ProjectUtils.listAllModules(project); + moduleComboBox = new ComboBox<>(moduleList.toArray(new String[0])); + + VirtualFile sourceRoot = ProjectUtils.getSourceRoot(project, moduleComboBox.getSelectedItem().toString()); + DefaultMutableTreeNode root = buildTreeNodes(sourceRoot); + DefaultTreeModel treeModel = new DefaultTreeModel(root); + this.tree = new Tree(treeModel); + tree.setCellRenderer(new NodeRenderer() { + @Override + public void customizeCellRenderer(@NotNull JTree jTree, Object o, boolean b, boolean b1, boolean b2, int i, boolean b3) { + super.customizeCellRenderer(jTree, o, b, b1, b2, i, b3); + if (o instanceof DefaultMutableTreeNode) { + setIcon(AllIcons.Nodes.Folder); + } + } + }); + + moduleComboBox.addActionListener(e -> { + String moduleName = (String) moduleComboBox.getSelectedItem(); + VirtualFile sourceRoot1 = ProjectUtils.getSourceRoot(project, moduleName); + DefaultMutableTreeNode root1 = buildTreeNodes(sourceRoot1); + DefaultTreeModel treeModel1 = new DefaultTreeModel(root1); + tree.setModel(treeModel1); + }); + + setTitle("Select a Package"); + scrollPane = new JBScrollPane(tree); + scrollPane.setPreferredSize(ScreenSizeUtils.size()); + scrollPane.setMinimumSize(ScreenSizeUtils.size()); + init(); + } + + private DefaultMutableTreeNode buildTreeNodes(VirtualFile directory) { + DefaultMutableTreeNode node = new DefaultMutableTreeNode(directory.getName()); + for (VirtualFile child : directory.getChildren()) { + if (child.isDirectory() && !child.getName().startsWith(".")) { + DefaultMutableTreeNode childNode = buildTreeNodes(child); + node.add(childNode); + } + } + + return node; + } + + @Override + protected void doOKAction() { + TreePath[] selectionPaths = tree.getSelectionPaths(); + if (selectionPaths != null && selectionPaths.length > 0) { + for (TreePath path : selectionPaths) { + DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) path.getLastPathComponent(); + String selectedPackage = getPathFromRoot(selectedNode); + this.result.getData().put("package", selectedPackage); + } + } + String selectedModule = (String) moduleComboBox.getSelectedItem(); + this.result.getData().put("module", selectedModule); + super.doOKAction(); + } + + private String getPathFromRoot(DefaultMutableTreeNode node) { + StringBuilder path = new StringBuilder(); + boolean isFirst = true; + while (node != null) { + if (node.getParent() != null) { + if (!isFirst) { + path.insert(0, "."); + } else { + isFirst = false; + } + path.insert(0, node.getUserObject()); + } + node = (DefaultMutableTreeNode) node.getParent(); + } + return path.toString(); + } + + @Override + protected @Nullable JComponent createCenterPanel() { + JPanel panel = new JPanel(); + panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); + panel.add(moduleComboBox); + panel.add(scrollPane); + return panel; + } +} + diff --git a/athena-all/src/main/java/run/mone/m78/ip/dialog/ParamTableDialog.java b/athena-all/src/main/java/run/mone/m78/ip/dialog/ParamTableDialog.java new file mode 100644 index 000000000..22eff8871 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/dialog/ParamTableDialog.java @@ -0,0 +1,196 @@ +package run.mone.m78.ip.dialog; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.JavaPsiFacade; +import com.intellij.psi.PsiClass; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.ui.table.JBTable; +import run.mone.m78.ip.bo.ValueInfo; +import run.mone.m78.ip.bo.prompt.PromptParamType; +import run.mone.m78.ip.bo.ParamDialogReq; +import run.mone.m78.ip.bo.PromptInfo; +import run.mone.m78.ip.bo.prompt.PromptParam; +import run.mone.m78.ip.util.EditorUtils; +import run.mone.m78.ip.util.FileUtils; +import run.mone.m78.ip.util.ResourceUtils; +import run.mone.m78.ip.util.ScreenSizeUtils; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.Nullable; +import run.mone.ultraman.event.AthenaEventBus; +import run.mone.ultraman.event.ConsumerBo; + +import javax.swing.*; +import javax.swing.table.DefaultTableModel; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2023/5/30 09:30 + * 用来输入参数的一个泛化Table + */ +@Slf4j +public class ParamTableDialog extends DialogWrapper { + + private JBTable table; + + private Map initialData; + + /** + * 会有多个选择的(选择的就放到这里) + */ + @Getter + private Map valuesMap = new HashMap<>(); + + private Project project; + + private PromptInfo promptInfo; + + private ParamDialogReq req; + + @Setter + private Consumer> consumer; + + @Setter + private boolean edit; + + public ParamTableDialog(ParamDialogReq req, @Nullable Project project, Map initialData, Map> listMap, PromptInfo promptInfo) { + super(project); + this.req = req; + this.project = project; + this.promptInfo = promptInfo; + this.initialData = initialData; + init(); + setTitle(req.getTitle()); + } + + @Override + protected @Nullable JComponent createCenterPanel() { + JPanel panel = new JPanel(new BorderLayout()); + //key不允许被编辑 + DefaultTableModel tableModel = new DefaultTableModel() { + @Override + public boolean isCellEditable(int row, int column) { + return column != 0 && column != 2; + } + }; + tableModel.addColumn("Key"); + tableModel.addColumn("Value"); + + // 设置初始值 + if (initialData != null) { + for (Map.Entry entry : initialData.entrySet()) { + PromptParam pp = new PromptParam(); + pp.init(entry.getKey(), this.project, this.promptInfo); + tableModel.addRow(new Object[]{entry.getKey(), StringUtils.isNotEmpty(pp.getType()) ? pp : entry.getValue()}); + } + } + table = new JBTable(tableModel); + + table.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + int col = table.getSelectedColumn(); + int row = table.getSelectedRow(); + Object v = table.getValueAt(row, col); + if (v instanceof PromptParam pp) { + String type = pp.getType(); + if (type.equals("editor")) { + ConsumerBo bo = new ConsumerBo(); + bo.setType("value"); + bo.setConsumer((Consumer) (p) -> SwingUtilities.invokeLater(() -> { + pp.setValue(p.getValue()); + table.getModel().setValueAt(pp, row, 1); + ParamTableDialog.this.getRootPane().getParent().setVisible(true); + })); + AthenaEventBus.ins().post(bo); + ParamTableDialog.this.getRootPane().getParent().setVisible(false); + EditorUtils.openEditor(project, pp.getValue(), "param.md"); + } + } + } + }); + + + AthenaTableCellEditor atc = new AthenaTableCellEditor(project, this.promptInfo); + atc.setTableModel(tableModel); + atc.setDialogWrapper(this); + table.getColumnModel().getColumn(1).setCellEditor(atc); + panel.add(table, BorderLayout.CENTER); + panel.setPreferredSize(ScreenSizeUtils.size()); + panel.setMinimumSize(ScreenSizeUtils.size()); + return panel; + } + + @Override + public Dimension getPreferredSize() { + return ScreenSizeUtils.size(); + } + + @Override + protected void doOKAction() { + DefaultTableModel tableModel = (DefaultTableModel) table.getModel(); + for (int row = 0; row < tableModel.getRowCount(); row++) { + String key = (String) tableModel.getValueAt(row, 0); + Object value = tableModel.getValueAt(row, 1); + String v = ""; + if (value instanceof PromptParam pp) { + if (pp.getType().equals(PromptParamType.params.name())) { + String classList = pp.getValue(); + Type typeOfT = new TypeToken>() { + }.getType(); + List names = new Gson().fromJson(classList, typeOfT); + String s = names.stream().map(it -> { + PsiClass psiClass = JavaPsiFacade.getInstance(project).findClass(it, GlobalSearchScope.allScope(project)); + if (null == psiClass) { + return ""; + } + return psiClass.getText(); + }).collect(Collectors.joining("\n\n")); + v = classList + "\n\n" + s; + } else if (pp.getType().equals(PromptParamType.code.name())) {//如果是code,需要替换为代码 + String classPath = pp.getValue(); + PsiClass psiClass = JavaPsiFacade.getInstance(project).findClass(classPath, GlobalSearchScope.allScope(project)); + v = psiClass.getText(); + } else { + v = pp.getValue(); + } + } else { + v = (String) tableModel.getValueAt(row, 1); + } + valuesMap.put(key, v); + } + super.doOKAction(); + if (null != consumer) { + consumer.accept(valuesMap); + } + save(); + } + + //把配置保存到配置文件+刷新 + private void save() { + String title = req.getTitle(); + if (title.equals("config")) { + log.info("save config"); + String content = new GsonBuilder().setPrettyPrinting().create().toJson(this.valuesMap); + FileUtils.writeConfig(content, ResourceUtils.USER_HOME_ATHENA_FILE_NAME); + //刷新配置 + ResourceUtils.getAthenaConfig(this.project, true); + } + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/dialog/SelectClassAndMethodDialog.java b/athena-all/src/main/java/run/mone/m78/ip/dialog/SelectClassAndMethodDialog.java new file mode 100644 index 000000000..906a73c1a --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/dialog/SelectClassAndMethodDialog.java @@ -0,0 +1,246 @@ +package run.mone.m78.ip.dialog; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.psi.PsiClass; +import com.intellij.ui.components.JBList; +import run.mone.m78.ip.bo.ClassInfo; +import run.mone.m78.ip.bo.MethodInfo; +import run.mone.m78.ip.bo.ModuleInfo; +import run.mone.m78.ip.bo.PsiInfo; +import run.mone.m78.ip.service.ClassFinder; +import run.mone.m78.ip.service.CodeService; +import run.mone.m78.ip.util.ProjectUtils; +import run.mone.m78.ip.util.ScreenSizeUtils; +import lombok.Getter; +import org.apache.commons.compress.utils.Lists; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import javax.swing.event.ListDataEvent; +import javax.swing.event.ListDataListener; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +/** + * @author caobaoyu + * @author goodjava@qq.com + * @description: 对话框的一些操作 + * @date 2023-04-25 14:42 + */ +public class SelectClassAndMethodDialog extends DialogWrapper { + + public JPanel rootPanel; + + private JTabbedPane tabbedPane; + + private JTextField searchField; + + private Map> listMap = new HashMap<>(); + + private Project project; + + /** + * 调用后传出去的结果 + */ + @Getter + private DialogResult result = new DialogResult(); + + private DialogContext context = new DialogContext(); + + private String moduleName; + + /** + * 调用这个dialog传进来的参数 + */ + private DialogReq req; + + public SelectClassAndMethodDialog(Project project, DialogReq req) { + super(project); + this.project = project; + this.moduleName = req.getModule().getName(); + this.req = req; + this.context.setModule(req.getModule()); + init(); + setTitle("Athena(" + moduleName + ")"); + } + + + private void initList(List list, String name, int selectIndex) { + JPanel controllerPanel = new JPanel(new BorderLayout()); + JBList jbList = new JBList<>(list); + + jbList.setCellRenderer((list1, value, index, isSelected, cellHasFocus) -> { + JLabel label = new JLabel(value.toString()); + if (value.isHidden()) { + label.setText(""); + } + return label; + }); + + + jbList.setSelectedIndex(selectIndex); + controllerPanel.add(jbList, BorderLayout.CENTER); + tabbedPane.addTab(name, controllerPanel); + listMap.put(name, jbList); + } + + + private void changeListModel(List list, String name) { + DefaultListModel listModel = new DefaultListModel<>(); + listModel.addAll(list); + listMap.get(name).setModel(listModel); + listMap.get(name).setSelectedIndex(0); + } + + + @Nullable + @Override + protected JComponent createCenterPanel() { + rootPanel = new JPanel(); + rootPanel.setLayout(new BorderLayout()); + searchField = new JTextField(); + searchField.addActionListener(new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + String text = searchField.getText(); + String selectedTab = tabbedPane.getTitleAt(tabbedPane.getSelectedIndex()); + JBList tab = listMap.get(selectedTab); + ListModel listModel = tab.getModel(); + if (StringUtils.isNotEmpty(text)) { + for (int i = 0; i < listModel.getSize(); i++) { + PsiInfo value = listModel.getElementAt(i); + if (!value.getName().contains(text)) { + listModel.getElementAt(i).hidden(true); + } + } + } else { + for (int i = 0; i < listModel.getSize(); i++) { + listModel.getElementAt(i).hidden(false); + } + } + notifyChange(tab, listModel); + } + }); + // 创建一个选项卡面板 + tabbedPane = new JTabbedPane(); + + @NotNull List moduleList = getModuleList(); + initList(moduleList, "Module", getModuleIndex(moduleList)); + initList(Lists.newArrayList(), "Class", 0); + initList(Lists.newArrayList(), "Method", 0); + + JScrollPane scrollPane = new JScrollPane(tabbedPane); + + JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, searchField, scrollPane); + splitPane.setDividerLocation(searchField.getPreferredSize().height); + + rootPanel.add(splitPane, BorderLayout.CENTER); + rootPanel.setPreferredSize(ScreenSizeUtils.size()); + rootPanel.setMinimumSize(ScreenSizeUtils.size()); + + if (req.getCmd().equals("test")) { + tabbedPane.setSelectedIndex(0); + } + + return rootPanel; + } + + @Override + public Dimension getPreferredSize() { + return ScreenSizeUtils.size(); + } + + private int getModuleIndex(List moduleList) { + return IntStream.range(0, moduleList.size()).filter(i -> moduleList.get(i).getName().equals(this.moduleName)).findAny().getAsInt(); + } + + private static void notifyChange(JBList tab, ListModel listModel) { + ListDataListener[] listeners = ((DefaultListModel) listModel).getListDataListeners(); + for (ListDataListener listener : listeners) { + listener.contentsChanged(new ListDataEvent(tab, ListDataEvent.CONTENTS_CHANGED, 0, listModel.getSize())); + } + } + + @NotNull + private List getModuleList() { + return ProjectUtils.listAllModules(this.project).stream().map(it -> + ModuleInfo.builder().name(it). + build()).collect(Collectors.toList()); + } + + @Override + protected void doOKAction() { + // 获取用户选择的选项卡和列表项 + String selectedTab = tabbedPane.getTitleAt(tabbedPane.getSelectedIndex()); + String selectedItem = null; + + if (selectedTab.equals("Module")) { + String moduleName = this.listMap.get("Module").getSelectedValue().getName(); + String name = req.getName(); + String type = req.getType(); + List classList = ClassFinder.findClassList(project, type, name, moduleName); + classList.add(ClassInfo.builder().className("New").build()); + changeListModel(classList, "Class"); + tabbedPane.setSelectedIndex(1); + } + + if (selectedTab.equals("Class")) { + if (req.getCmd().equals("test") || req.getCmd().equals("docean_controller")) { + String clazz = this.listMap.get("Class").getSelectedValue().getName(); + this.result.getData().put("class", clazz); + PsiClass psiClass = CodeService.getPsiClass(project, context.getModule(), clazz); + List methodList = new ArrayList<>(); + if (null != psiClass) { + methodList.addAll(CodeService.methods(psiClass).stream().map(it -> { + MethodInfo mi = new MethodInfo(it); + return mi; + }).collect(Collectors.toList())); + this.result.getData().put("new_class", "false"); + } else { + //新的类的话,根本就不用选择方法 + this.result.getData().put("new_class", "true"); + this.result.getData().put("method", "New"); + if (clazz.equals("New")) { + String v = JOptionPane.showInputDialog("Enter class Name"); + if (StringUtils.isEmpty(v)) { + return; + } + this.result.getData().put("class", v); + } + } + + if (!req.isCreateMethod()) { + super.doOKAction(); + } + + methodList.add(0, new MethodInfo("New")); + changeListModel(methodList, "Method"); + this.result.setCmd(req.getCmd()); + tabbedPane.setSelectedIndex(2); + } + } + + if (selectedTab.equals("Method")) { + if (req.getCmd().equals("test") || req.getCmd().equals("docean_controller")) { + String method = this.listMap.get("Method").getSelectedValue().getName(); + this.result.getData().put("method", method); + super.doOKAction(); + } + } + + if (selectedTab.equals("Controller")) { + selectedItem = this.listMap.get("Controller").getSelectedValue().getName(); + } + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/dialog/SelectModuleDialog.java b/athena-all/src/main/java/run/mone/m78/ip/dialog/SelectModuleDialog.java new file mode 100644 index 000000000..239af2565 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/dialog/SelectModuleDialog.java @@ -0,0 +1,47 @@ +package run.mone.m78.ip.dialog; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.ComboBox; +import com.intellij.openapi.ui.DialogWrapper; +import lombok.Getter; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.util.List; + +/** + * @author caobaoyu + * @description: + * @date 2023-06-20 10:03 + */ +public class SelectModuleDialog extends DialogWrapper { + + private List moduleList; + private ComboBox moduleComboBox; + + @Getter + private String selectedModule; + + public SelectModuleDialog(Project project, List moduleList) { + super(project); + this.moduleList = moduleList; + init(); + setTitle("Athena"); + } + + + @Override + protected @Nullable JComponent createCenterPanel() { + JPanel panel = new JPanel(); + moduleComboBox = new ComboBox<>(moduleList.toArray(new String[0])); + panel.add(moduleComboBox); + return panel; + } + + @Override + protected void doOKAction() { + selectedModule = (String) moduleComboBox.getSelectedItem(); + super.doOKAction(); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/dialog/bo/CellValue.java b/athena-all/src/main/java/run/mone/m78/ip/dialog/bo/CellValue.java new file mode 100644 index 000000000..dc30a4d99 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/dialog/bo/CellValue.java @@ -0,0 +1,24 @@ +package run.mone.m78.ip.dialog.bo; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/7/16 00:17 + */ +@Data +public class CellValue implements Serializable { + + /** + * button textField combox editor + */ + private String type; + + private List list; + + private String value; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/enums/InvokePromptEnums.java b/athena-all/src/main/java/run/mone/m78/ip/enums/InvokePromptEnums.java new file mode 100644 index 000000000..870bfda9e --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/enums/InvokePromptEnums.java @@ -0,0 +1,43 @@ +package run.mone.m78.ip.enums; + +import lombok.Getter; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author caobaoyu + * @description: + * @date 2023-05-22 11:02 + */ +@Getter +public enum InvokePromptEnums { + /** + * 创建类 + */ + CREATE_CLASS(1, "createClass", "创建类"), + CREATE_METHOD(2, "createMethod", "创建方法"), + ADD_COMMENT(3, "addComment", "添加注释"), + CREATE_FILE(4, "createFile", "创建文件"), + UPDATE_CLASS(5, "updateClass", "修改类"), + + ; + private int code; + private String msg; + private String desc; + + InvokePromptEnums(int code, String msg, String desc) { + this.code = code; + this.msg = msg; + this.desc = desc; + } + + public static Map getInvokeMthMap() { + Map map = new HashMap<>(); + for (InvokePromptEnums value : InvokePromptEnums.values()) { + map.put(value.getCode(), value.getDesc()); + } + return map; + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/enums/ZTagEnums.java b/athena-all/src/main/java/run/mone/m78/ip/enums/ZTagEnums.java new file mode 100644 index 000000000..e7c2cb864 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/enums/ZTagEnums.java @@ -0,0 +1,36 @@ +package run.mone.m78.ip.enums; + +import lombok.Getter; + +/** + * @author caobaoyu + * @description: + * @date 2023-05-30 15:09 + */ +@Getter +public enum ZTagEnums { + + MI_API(9L, "miapi"), + METHOD(11L, "method"), + DUBBO(15L, "dubbo"), + PLUGIN(21L, "plugin"), + PLUGIN_INIT(30L,"plugin_init"); + + private Long code; + private String msg; + + ZTagEnums(Long code, String msg) { + this.code = code; + this.msg = msg; + } + + public static ZTagEnums getTagByMsg(String msg){ + for (ZTagEnums value : ZTagEnums.values()) { + if (value.getMsg().equals(msg)){ + return value; + } + } + return null; + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/enums/ZTypeEnums.java b/athena-all/src/main/java/run/mone/m78/ip/enums/ZTypeEnums.java new file mode 100644 index 000000000..1e813b132 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/enums/ZTypeEnums.java @@ -0,0 +1,50 @@ +package run.mone.m78.ip.enums; + +/** + * @author caobaoyu + * @description: 对应Z平台的prompt + * @date 2023-04-21 15:27 + */ +public enum ZTypeEnums { + + // 64-Athena 61-codegen + + CMD(64, "cmd", "cmd命令行prompt"), + COMMENT(64, "comment", "生成注释"), + REMOVE_COMMENT(64, "removeComment", "删除注释"), + GENERATE_METHOD(64, "generateMethod", "生成方法"), + COMPLETION(64, "completion", "检索"), + + FILED_DESC(64, "filedDesc", "类属性描述"), + METHOD_DESC(64, "methodDesc", "类方法描述"), + + GENERATE_HANDLER(64, "odin_handler", "生成一个handler"), + + GENERATE_MOON_HANDLER(64, "moon_handler", "生成一个moon handler"), + + CODE_CHECK(64, "code_check", "sonar代码检查Service"), + + MI_API(64, "mi_api", "生成miApi注解"), + + TEST_CODE(64, "test_code", "生成测试方法"), + + ODIN_MIDDLEWARE(64, "odin_middleware", "odin 中间件的一个使用demo"); + + ZTypeEnums(int type, String info, String desc) { + this.type = type; + this.info = info; + this.desc = desc; + } + + int type; + String info; + String desc; + + public int getType() { + return type; + } + + public String getInfo() { + return info; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/generator/ClassGenerator.java b/athena-all/src/main/java/run/mone/m78/ip/generator/ClassGenerator.java new file mode 100644 index 000000000..85a51a6e7 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/generator/ClassGenerator.java @@ -0,0 +1,54 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.generator; + +import run.mone.m78.ip.common.FileUtils; + +import java.io.File; +import java.util.Map; + +/** + * @author goodjava@qq.com + */ +public class ClassGenerator { + + private String projectPath; + private String projectName; + private String packagePath; + private String className; + private final String templateName; + private final String srcPath; + + + public ClassGenerator(String projectPath, String projectName, String srcPath, String packagePath, String className, String templateName) { + this.projectPath = projectPath; + this.projectName = projectName; + this.srcPath = srcPath; + this.packagePath = packagePath; + this.className = className; + this.templateName = templateName; + } + + public void generator(Map m) { + String template = FileUtils.getTemplate(templateName); + String str = FileUtils.renderTemplate(template, m); + FileUtils.writeFile(projectPath + File.separator + projectName + File.separator + srcPath + File.separator + packagePath + + File.separator + + className + ".java", str); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/generator/DirectoryGenerator.java b/athena-all/src/main/java/run/mone/m78/ip/generator/DirectoryGenerator.java new file mode 100644 index 000000000..0926d1bb1 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/generator/DirectoryGenerator.java @@ -0,0 +1,43 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.generator; + +import run.mone.m78.ip.common.FileUtils; + +import java.io.File; + +/** + * @author goodjava@qq.com + */ +public class DirectoryGenerator { + + private String projectPath; + private String projectName; + private String path; + + + public DirectoryGenerator(String projectPath, String projectName, String path) { + this.projectPath = projectPath; + this.projectName = projectName; + this.path = path; + } + + public void generator() { + FileUtils.createDirectories(projectPath + File.separator + projectName + File.separator + path); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/generator/FileGenerator.java b/athena-all/src/main/java/run/mone/m78/ip/generator/FileGenerator.java new file mode 100644 index 000000000..c61fe7994 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/generator/FileGenerator.java @@ -0,0 +1,48 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.generator; + +import run.mone.m78.ip.common.FileUtils; + +import java.io.File; +import java.util.Map; + +/** + * @author goodjava@qq.com + */ +public class FileGenerator { + + private String projectPath; + private String projectName; + private String path; + private final String templateName; + + + public FileGenerator(String projectPath, String projectName, String path, String templateName) { + this.projectPath = projectPath; + this.projectName = projectName; + this.path = path; + this.templateName = templateName; + } + + public void generator(Map m) { + String template = FileUtils.getTemplate(templateName); + String str = FileUtils.renderTemplate(template, m); + FileUtils.writeFile(projectPath + File.separator + projectName + File.separator + path, str); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/generator/PackageGenerator.java b/athena-all/src/main/java/run/mone/m78/ip/generator/PackageGenerator.java new file mode 100644 index 000000000..1f4bc4234 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/generator/PackageGenerator.java @@ -0,0 +1,40 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.generator; + +import run.mone.m78.ip.common.FileUtils; + +/** + * @author goodjava@qq.com + */ +public class PackageGenerator { + + private String projectPath; + private String projectName; + private String packageName; + + public PackageGenerator(String projectPath, String projectName, String packageName) { + this.projectPath = projectPath; + this.projectName = projectName; + this.packageName = packageName; + } + + public void generator() { + FileUtils.createDirectories(projectPath + projectName + "/src/main/java" + packageName); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/generator/PomGenerator.java b/athena-all/src/main/java/run/mone/m78/ip/generator/PomGenerator.java new file mode 100644 index 000000000..45a82b968 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/generator/PomGenerator.java @@ -0,0 +1,45 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.generator; + +import run.mone.m78.ip.common.FileUtils; + +import java.io.File; +import java.util.Map; + +/** + * @author goodjava@qq.com + */ +public class PomGenerator { + + private String projectPath; + private String projectName; + private final String tmlName; + + public PomGenerator(String projectPath, String projectName, String tmlName) { + this.projectPath = projectPath; + this.projectName = projectName; + this.tmlName = tmlName; + } + + public void generator(Map m) { + String template = FileUtils.getTemplate(tmlName); + String pomStr = FileUtils.renderTemplate(template, m); + FileUtils.writeFile(projectPath + File.separator + projectName + File.separator + "pom.xml", pomStr); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/listener/ChromeMessageRouterHandler.java b/athena-all/src/main/java/run/mone/m78/ip/listener/ChromeMessageRouterHandler.java new file mode 100644 index 000000000..8a5f90044 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/listener/ChromeMessageRouterHandler.java @@ -0,0 +1,583 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.listener; + +import cn.hutool.core.bean.BeanUtil; +import com.google.common.base.Splitter; +import com.google.common.collect.Maps; +import com.google.gson.Gson; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.newvfs.RefreshQueue; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.compress.utils.Lists; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableInt; +import org.apache.commons.lang3.mutable.MutableObject; +import org.apache.commons.lang3.tuple.Pair; +import org.cef.browser.CefBrowser; +import org.cef.browser.CefFrame; +import org.cef.callback.CefQueryCallback; +import org.cef.handler.CefMessageRouterHandlerAdapter; +import org.jetbrains.annotations.Nullable; +import run.mone.m78.ip.bo.*; +import run.mone.m78.ip.bo.z.EmbeddingStatus; +import run.mone.m78.ip.common.*; +import run.mone.m78.ip.enums.InvokePromptEnums; +import run.mone.m78.ip.service.CodeService; +import run.mone.m78.ip.service.PromptService; +import run.mone.m78.ip.service.RobotService; +import run.mone.m78.ip.service.ScriptService; +import run.mone.m78.ip.ui.VersionUi; +import run.mone.m78.ip.util.LabelUtils; +import run.mone.m78.ip.util.ProjectUtils; +import run.mone.m78.ip.util.ResourceUtils; +import run.mone.m78.ip.util.UltramanConsole; +import run.mone.ultraman.AthenaContext; +import run.mone.ultraman.bo.CodeReq; +import run.mone.ultraman.bo.Version; +import run.mone.ultraman.common.SafeRun; +import run.mone.ultraman.service.AthenaCodeService; +import run.mone.ultraman.service.ModuleService; +import run.mone.ultraman.state.ProjectFsmManager; + +import java.io.File; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2021/11/20 + *

+ * https://github.com/supsunc/swing-jcef-spring --> 参考 + * 也是通过页面调用过来的,这种的方式好处是不用开启端口,坏处是从单独的应用调用不过来 + */ +@Slf4j +public class ChromeMessageRouterHandler extends CefMessageRouterHandlerAdapter { + + private Project project; + + private Gson gson = new Gson(); + + public ChromeMessageRouterHandler(Project project) { + this.project = project; + } + + /** + * 前端直接可以调用过来 + * + * @param browser The corresponding browser. + * @param frame The frame generating the event. Instance only valid within the scope of this + * method. + * @param query_id The unique ID for the query. + * @param request + * @param persistent True if the query is persistent. + * @param callback Object used to continue or cancel the query asynchronously. + * @return + */ + @Override + public boolean onQuery(CefBrowser browser, CefFrame frame, long query_id, String request, boolean persistent, CefQueryCallback callback) { + if (request.indexOf("click:") == 0) { + String res = "success"; + String msg = request.substring(6).trim(); + Req req = gson.fromJson(msg, Req.class); + + Map m = Maps.newHashMap(); + Map p = Maps.newHashMap(); + m.put("project_path", project.getBasePath()); + m.put("console", new UltramanConsole()); + p.put("project_path", project.getBasePath()); + + //处理本地调用和消息处理的 + Pair messageRes = LocalHandler.handler(this.project, req); + if (messageRes.getKey() == 0) { + callback.success(messageRes.getValue()); + return true; + } + + //多模态调用 + String visionRes = VisionHandler.handler(this.project, req); + if (StringUtils.isNotEmpty(visionRes)) { + callback.success(visionRes); + return true; + } + + if (req.getCmd().equals("idea_insert_code")) { + log.info("idea insert code"); + String code = req.getData().get("code"); + ApplicationManager.getApplication().invokeLater(() -> { + CodeService.insertCode(project, code); + }); + } + + //调用miapi 这里需要拿到用户的key + if (req.getCmd().equals("miapi")) { + String key = ConfigUtils.getConfig().getChatgptKey(); + res = key; + } + + //拿到用户的z token + if (req.getCmd().equals("z_token")) { + String key = ConfigUtils.getConfig().getzToken(); + res = key; + } + + //获取http服务器信息和一些ide信息 + if (req.getCmd().equals("server_info")) { + res = this.getServerInfo(req); + } + + // 代码生成 + if (req.getCmd().equals("code_generate")) { + this.codeGenerate(req); + } + + // 获取prompt信息 + if (req.getCmd().equals("prompt_info")) { + res = this.getPromptInfo(req); + } + + // 获取调用类型 + if (req.getCmd().equals("get_invoke_type")) { + Map invokeMthMap = InvokePromptEnums.getInvokeMthMap(); + res = gson.toJson(invokeMthMap); + } + + // 根据prompt信息生成代码 + if (req.getCmd().equals("handler_generate")) { + res = this.handlerGenerate(req); + } + + // 预装的plugin能力 + if (req.getCmd().equals("ai_code_prompt")) { + if (LabelUtils.getLabelValue(this.project, Const.OPEN_GUIDE, "true").equals("false")) { + AiCodeRes aiCodeRes = new AiCodeRes(); + aiCodeRes.setMsg("Athena"); + res = gson.toJson(aiCodeRes); + } else { + res = this.getAiCodePrompt(); + } + } + + // 获取当前的project和module信息 + if (req.getCmd().equals("get_project_info")) { + res = this.getProjectInfo(); + } + + if (req.getCmd().equals("guide")) { + res = gson.toJson(ConfigCenter.getGuide()); + } + + //ai导航信息(上传代码的调用也再这里) + if (req.getCmd().equals("ai_guide")) { + res = this.aiGuide(req); + } + + + //有些提示词需要进行替换(比如选中的代码) + String promptRes = PromptHandler.handler(project, req); + if (StringUtils.isNotEmpty(promptRes)) { + res = promptRes; + } + + callback.success(res); + return true; + } + return false; + } + + + /** + * 获取服务器信息(本地可以开启一个http server) + * + * @param req 请求对象 + * @return 返回HTTP服务器信息的JSON字符串 + */ + public String getServerInfo(Req req) { + ServerInfo info = new ServerInfo(); + info.setSend(true); + info.setGptModel(AthenaContext.ins().getGptModel()); + info.setAiProxyDebug(AthenaContext.ins().isDebugAiProxy()); + info.setLocal(Boolean.valueOf(ResourceUtils.getAthenaConfig().getOrDefault(Const.OPEN_AI_LOCAL, "false"))); + info.setVision(Boolean.valueOf(ResourceUtils.getAthenaConfig().getOrDefault(Const.VISION, "false"))); + String portStr = ConfigUtils.getConfig().getChatServer(); + int port = 3458; + if (!StringUtils.isEmpty(portStr)) { + port = Integer.valueOf(port); + } + info.setPort(port); + SafeRun.run(() -> { + info.setProjectList(ProjectUtils.listOpenProjects()); + String curProjectName = req.getData().get("projectName"); + if (null != curProjectName) { + List moduleList = ProjectUtils.listAllModules(ProjectUtils.projectFromManager(curProjectName)).stream().filter(it -> !it.equals(curProjectName)).collect(Collectors.toList()); + info.setModuleList(moduleList); + } + }); + return gson.toJson(info); + } + + /** + * 生成Java代码并创建类。 + * + * @param req 请求对象,包含生成代码和类名。 + * @return 返回操作结果。 + */ + public String codeGenerate(Req req) { + String code = req.getData().get("code"); + String className = req.getData().get("className"); + ApplicationManager.getApplication().invokeAndWait(() -> { + Editor e = FileEditorManager.getInstance(project).getSelectedTextEditor(); + JavaClassUtils.createClass(project, e, className, code); + }); + return "ok"; + } + + + /** + * 获取prompt信息 + * + * @param req 请求对象 + * @return 返回HttpServerInfo对象的json字符串 + */ + public String getPromptInfo(Req req) { + ServerInfo info = new ServerInfo(); + String portStr = ConfigUtils.getConfig().getChatServer(); + int port = 3458; + if (!StringUtils.isEmpty(portStr)) { + port = Integer.valueOf(port); + } + info.setPort(port); + SafeRun.run(() -> { + info.setProjectList(ProjectUtils.listOpenProjects()); + String curProjectName = req.getData().get("projectName"); + if (null != curProjectName) { + info.setModuleList(ProjectUtils.listAllModules(ProjectUtils.projectFromManager(curProjectName))); + } + Prompt.flush(); + info.setPromptList(Prompt.getPromptMeta()); + }); + return gson.toJson(info); + } + + /** + * 处理生成代码请求 + * + * @param req 请求对象 + * @return 返回字符串"ok" + */ + public String handlerGenerate(Req req) { + ApplicationManager.getApplication().invokeLater(() -> { + String model = req.getData().get("model"); + String promptName = req.getData().get("prompt"); + String meta = req.getData().get("meta"); + String type = req.getData().get("type"); + String showDialog = req.getData().get("showDialog"); + + Project p = ProjectUtils.project(); + if (null == p) { + p = this.project; + } + String project = p.getName(); + PromptInfo promptInfo = Prompt.getPromptInfo(promptName); + PromptType promptType = Prompt.getPromptType(promptInfo); + GenerateCodeReq codeReq = GenerateCodeReq.builder().projectName(project).project(p).model(model).promptName(promptName) + .meta(meta).promptInfo(promptInfo).promptType(promptType).type(type) + .showDialog(showDialog).param(req.getData()) + .build(); + PromptService.dynamicInvoke(codeReq); + }); + return "ok"; + } + + + /** + * 获取AI代码提示信息 + * + * @return AI代码提示信息的JSON字符串 + */ + private String getAiCodePrompt() { + if (!Prompt.isLoadFinish()) { + return gson.toJson(AiCodeRes.builder().msg("loading").build()); + } + StringBuilder sb = new StringBuilder(); + CountDownLatch latch = new CountDownLatch(1); + ApplicationManager.getApplication().invokeLater(() -> { + try { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + boolean selected = false; + if (editor != null) { + String selectedText = editor.getSelectionModel().getSelectedText(); + selected = null != selectedText; + } + AiCodeRes codeRes = selected ? ConfigCenter.build("selected") : ConfigCenter.build("noselected"); + List promptInfoList = Lists.newArrayList(); + promptInfoList.addAll(codeRes.getPromptInfoList()); + AiCodeRes result = new AiCodeRes(); + result.setMsg(codeRes.getMsg()); + result.setPromptInfoList(promptInfoList); + sb.append(gson.toJson(result)); + } finally { + latch.countDown(); + } + }); + try { + latch.await(2, TimeUnit.SECONDS); + } catch (InterruptedException e) { + return ""; + } + return sb.toString(); + } + + /** + * AI引导方法,根据请求参数中的问题,获取相应的提示信息列表 + * + * @param req 请求参数对象,包含问题信息 + * @return 返回提示信息列表的JSON字符串 + */ + private String aiGuide(Req req) { + AiCodeRes res = new AiCodeRes(); + String question = req.getData().get("question"); + if (question.equals("flush")) { + Prompt.flush(); + res.setMsg("flush success"); + return gson.toJson(res); + } + + if (question.startsWith("invoke_code:")) { + List list = Splitter.on(":").splitToList(question); + if (list.size() == 4) { + String codeName = list.get(1); + String method = list.get(2); + String param = list.get(3); + Object codeRes = ScriptService.ins().invoke(ScriptService.getScript(codeName), method, Maps.newHashMap(), param); + res.setMsg("invoke code success:" + codeRes); + } else { + res.setMsg(list + " list size != 4"); + } + return gson.toJson(res); + } + + if (question.startsWith("model")) { + List list = Splitter.on(":").splitToList(question); + if (list.size() == 2) { + AthenaContext.ins().setGptModel(list.get(1)); + res.setMsg("set model success model:" + list.get(1)); + } + return gson.toJson(res); + } + + if (question.startsWith("aidebug")) { + List list = Splitter.on(":").splitToList(question); + if (list.size() == 2) { + AthenaContext.ins().setDebugAiProxy(Boolean.valueOf(list.get(1))); + res.setMsg("ai debug:" + list.get(1)); + } + return gson.toJson(res); + } + + if (question.equals("refreshconfig")) { + ResourceUtils.getAthenaConfig(this.project, true); + res.setMsg("refresh config success"); + return gson.toJson(res); + } + + //获取作者信息 + if (question.equals("author")) { + return author(res); + } + + if (question.startsWith("troubleshoot")) { + RobotService.troubleshoot(null, RobotReq.builder().project(this.project).param(question).build()); + return ""; + } + + //获取embedding 信息 + if (question.equals("embedding_status")) { + return embeddingStatus(req, res); + } + + //打开配置 + if (question.equals("config")) { + ApplicationManager.getApplication().invokeLater(() -> LabelUtils.showLabelConfigUi(this.project)); + res.setMsg("show config success"); + return gson.toJson(res); + } + + if (question.equals("collected")) { + res.setMsg(" "); + res.setPromptInfoList(buildAiCodePromptRes(Prompt.getCollected())); + return gson.toJson(res); + } + + if (question.equals("debug")) { + res.setMsg(new Version().toString()); + return gson.toJson(res); + } + + //刷新业务代码到知识库 + if (question.equals("flush_biz")) { + return flushBizCode(req, res); + } + + if (question.equals("class_len")) { + return getClassLen(res); + } + + //停止状态机 + if (question.equals("stop")) { + ProjectFsmManager.stop(project.getName()); + res.setMsg("退出状态机"); + return gson.toJson(res); + } + + //查询状态机状态 + if (question.equals("state")) { + String state = ProjectFsmManager.state(project.getName()); + res.setMsg("state:" + state); + return gson.toJson(res); + } + + AiCodeRes cache = ConfigCenter.build(question); + if (null == cache) { + res.setMsg(Message.unsupportedCommand); + return gson.toJson(res); + } + res.setMsg(cache.getMsg()); + if (!"help".equals(question)) { + List promptRes = Lists.newArrayList(); + List promptList = Prompt.getPromptInfoByTag(cache.getTagName()); + promptRes.addAll(cache.getPromptInfoList()); + promptRes.addAll(buildAiCodePromptRes(promptList)); + res.setPromptInfoList(promptRes); + } else { + res.setPromptInfoList(cache.getPromptInfoList()); + } + return gson.toJson(res); + } + + private String embeddingStatus(Req req, AiCodeRes res) { + String scope = req.getData().getOrDefault("scope", "project"); + CodeReq.CodeReqBuilder builder = CodeReq.builder(); + builder.projectName(this.project.getName()); + if (!scope.equals("project")) { + builder.moduleName(getModule(req.getData().get("module")).getName()); + } + EmbeddingStatus status = AthenaCodeService.embeddingStatus(builder.build()); + String msg = scope.equals("project") ? ("project_" + req.getData().get("project")) : ("module_" + req.getData().get("module")); + res.setMsg(gson.toJson(status) + ":" + msg); + return gson.toJson(res); + } + + //刷新业务代码到知识库 + private String flushBizCode(Req req, AiCodeRes res) { + String moduleName = req.getData().get("module"); + String scope = req.getData().get("scope"); + ApplicationManager.getApplication().invokeLater(() -> { + if ("project".equals(scope)) { + //Refresh all modules. + List list = ProjectUtils.listAllModules(this.project).stream().filter(it -> !it.equals(req.getData().get("project"))).collect(Collectors.toList()); + list.stream().forEach(it -> ModuleService.uploadModelText(this.project, getModule(it))); + } else { + ModuleService.uploadModelText(this.project, getModule(moduleName)); + } + }); + res.setMsg("flush biz success"); + return gson.toJson(res); + } + + //获取当前打开类的长度 + private String getClassLen(AiCodeRes res) { + MutableInt num = new MutableInt(); + ApplicationManager.getApplication().invokeAndWait(() -> { + String text = CodeService.getClassText(this.project); + num.setValue(text.length()); + }); + res.setMsg(String.valueOf(num.getValue())); + return gson.toJson(res); + } + + //获取作者信息 + private String author(AiCodeRes res) { + ApplicationManager.getApplication().invokeLater(() -> { + VersionUi versionUi = new VersionUi(); + versionUi.show(); + }); + res.setMsg(new Version().toString()); + return gson.toJson(res); + } + + @Nullable + private Module getModule(String moduleName) { + if (StringUtils.isEmpty(moduleName)) { + Mutable mutable = new MutableObject<>(); + ApplicationManager.getApplication().invokeAndWait(() -> { + mutable.setValue(ProjectUtils.getCurrentModule(this.project)); + }); + return mutable.getValue(); + } else { + return ProjectUtils.getModuleWithName(this.project, moduleName); + } + } + + /** + * 获取项目信息并以JSON格式返回。 + * 该方法通过调用ApplicationManager的invokeLater方法,异步获取项目名称和模块名称,并将其设置到ProjectModuleInfo对象中。 + * 最终将ProjectModuleInfo对象转换为JSON格式返回。 + * + * @return 以JSON格式返回的项目信息。 + */ + private String getProjectInfo() { + ProjectModuleInfo info = new ProjectModuleInfo(); + String projectName = this.project.getName(); + info.setProjectName(projectName); + return gson.toJson(info); + } + + + @Override + public void onQueryCanceled(CefBrowser browser, CefFrame frame, long query_id) { + } + + + private void refreshProject(String targetExtractionDir) { + VirtualFile targetFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(targetExtractionDir)); + RefreshQueue.getInstance().refresh(false, true, null, targetFile); + } + + private List buildAiCodePromptRes(List promptInfoList) { + List list = promptInfoList.stream().filter(p -> p.getTags().stream().anyMatch(tag -> tag.getName().equals("plugin"))).map(promptInfo -> { + AiCodePromptRes promptRes = new AiCodePromptRes(); + BeanUtil.copyProperties(promptInfo, promptRes); + promptRes.setType("cmd"); + promptRes.setShowDialog(promptInfo.getLabels().getOrDefault("showDialog", "false")); + return promptRes; + }).collect(Collectors.toList()); + return list; + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/listener/DevToolsDialog.java b/athena-all/src/main/java/run/mone/m78/ip/listener/DevToolsDialog.java new file mode 100644 index 000000000..da292ec0b --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/listener/DevToolsDialog.java @@ -0,0 +1,63 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.listener; + +import org.cef.browser.CefBrowser; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; + +/** + * @author goodjava@qq.com + * @date 2021/11/20 + */ +public class DevToolsDialog extends JDialog { + + private final CefBrowser devTools_; + + // 一般使用这个构造方法 + public DevToolsDialog(Frame owner, String title, CefBrowser browser) { + this(owner, title, browser, null); + } + + public DevToolsDialog(Frame owner, String title, CefBrowser browser, Point inspectAt) { + setLayout(new BorderLayout()); // 设置布局 + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); // 拿到屏幕尺寸 + setSize(screenSize.width / 3,screenSize.height / 3); //设置大小为屏幕尺寸的一半,可以自定大小 + + devTools_ = browser.getDevTools(inspectAt); // 获取到 browser 的 DevTools + add(devTools_.getUIComponent()); // 将其 UIComponent 添加上去 + + // 添加相关监听 + addComponentListener(new ComponentAdapter() { + @Override + public void componentHidden(ComponentEvent e) { + dispose(); + } + }); + } + + @Override + public void dispose() { + devTools_.close(true); // 关闭的时候触发此方法,关闭 DevTools + super.dispose(); + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/listener/LocalHandler.java b/athena-all/src/main/java/run/mone/m78/ip/listener/LocalHandler.java new file mode 100644 index 000000000..c67b1cbcd --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/listener/LocalHandler.java @@ -0,0 +1,119 @@ +package run.mone.m78.ip.listener; + +import com.intellij.openapi.project.Project; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; +import run.mone.m78.ip.bo.chatgpt.LocalReq; +import run.mone.m78.ip.bo.robot.*; +import run.mone.m78.ip.service.LocalAiService; +import run.mone.ultraman.AthenaContext; +import run.mone.ultraman.bo.ClientData; +import run.mone.ultraman.common.GsonUtils; +import run.mone.ultraman.state.AthenaEvent; +import run.mone.ultraman.state.ProjectFsmManager; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * @author goodjava@qq.com + * @date 2023/12/10 15:40 + */ +@Slf4j +public class LocalHandler { + + + @SneakyThrows + public static Pair handler(Project project, Req req) { + //本地调用(需要开启本地模式) + if (req.getCmd().equals("local_call")) { + return localCall(project, req); + } + + //获取消息列表 + if (req.getCmd().equals("list_msg")) { + List listRes = ProjectAiMessageManager.getInstance().listMsg(project); + return Pair.of(0, GsonUtils.gson.toJson(listRes)); + } + + //清空所有消息 + if (req.getCmd().equals("clear_msg")) { + ProjectAiMessageManager.getInstance().clearMsg(project); + return Pair.of(300, ""); + } + + //删除指定消息 + if (req.getCmd().equals("del_msg")) { + ProjectAiMessageManager.getInstance().delMsg(project, req.getData().get("msgId")); + return Pair.of(300, ""); + } + + //前端消息同步 + if (req.getCmd().equals("append_msg")) { + MessageReq messageReq = GsonUtils.gson.fromJson(req.getData().get("data"), MessageReq.class); + AiChatMessage aiChatMessage = AiChatMessage.builder().role(Role.valueOf(messageReq.getRole().toLowerCase())).message(messageReq.getMessage()).data(messageReq.getMessage()).build(); + MessageRes res = ProjectAiMessageManager.getInstance().appendMsg(project, aiChatMessage); + return Pair.of(0, GsonUtils.gson.toJson(res)); + } + + //event + if (req.getCmd().equals("event_msg")) { + MessageReq messageReq = GsonUtils.gson.fromJson(req.getData().get("data"), MessageReq.class); + messageReq.setProject(project.getName()); + EventRes res = ProjectAiMessageManager.getInstance().event(project, messageReq); + return Pair.of(0, GsonUtils.gson.toJson(res)); + } + + //回滚到某个状态(就是对某个问题重新提问) + if (req.getCmd().equals("state_rollback")) { + int index = Integer.valueOf(req.getData().get("index")); + Map map = new HashMap<>(); + map.put("index", String.valueOf(index)); + map.put("question", "modify_state"); + ProjectFsmManager.tell(project.getName(), map); + } + + //查询状态机信息 + if (req.getCmd().equals("state_ask")) { + Map map = new HashMap<>(); + map.put("question", "info"); + AthenaEvent event = ProjectFsmManager.ask(project.getName(), map); + event.getAskLatch().await(15, TimeUnit.SECONDS); + String result = event.getMeta().get("result"); + return Pair.of(0, result); + } + + //前端同步过来数据 + if (req.getCmd().equals("sync_client_data")) { + String data = req.getData().get("syncData"); + ClientData clientData = GsonUtils.gson.fromJson(data, ClientData.class); + String projectName = project.getName(); + AthenaContext.ins().getClientDataMap().put(projectName, clientData); + log.info("client sync data:{}", clientData); + } + + + return Pair.of(300, ""); + } + + /** + * Executes a local call to a service using the provided project and request data, deserializes the 'data' field from the request, and invokes the local AI service if data is not empty. Returns a Pair with status code 300 and an empty string. + */ + @NotNull + private static Pair localCall(Project project, Req req) { + String data = req.getData().getOrDefault("data", ""); + if (!StringUtils.isEmpty(data)) { + LocalReq localReq = GsonUtils.gson.fromJson(data, LocalReq.class); + //直接本地调用chatgpt + int num = Integer.valueOf(req.getData().getOrDefault("msg_num", "0")); + LocalAiService.localCall(project, localReq.getMsgList(), false, num); + } + return Pair.of(300, ""); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/listener/MenuHandler.java b/athena-all/src/main/java/run/mone/m78/ip/listener/MenuHandler.java new file mode 100644 index 000000000..dc65e5891 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/listener/MenuHandler.java @@ -0,0 +1,61 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.listener; + +import org.cef.browser.CefBrowser; +import org.cef.browser.CefFrame; +import org.cef.callback.CefContextMenuParams; +import org.cef.callback.CefMenuModel; +import org.cef.handler.CefContextMenuHandlerAdapter; + +import java.awt.*; + +/** + * @author goodjava@qq.com + * @date 2021/11/20 + */ +public class MenuHandler extends CefContextMenuHandlerAdapter { + private final Frame owner; + + public MenuHandler(Frame owner) { + this.owner = owner; + } + + private final static int MENU_ID_SHOW_DEV_TOOLS = 10000; + + @Override + public void onBeforeContextMenu(CefBrowser browser, CefFrame frame, CefContextMenuParams params, CefMenuModel model) { + //清除菜单项 + model.clear(); + model.addItem(CefMenuModel.MenuId.MENU_ID_VIEW_SOURCE, "view source"); + model.addItem(MENU_ID_SHOW_DEV_TOOLS, "inspect"); + } + + @Override + public boolean onContextMenuCommand(CefBrowser browser, CefFrame frame, CefContextMenuParams params, int commandId, int eventFlags) { + switch (commandId) { + case MENU_ID_SHOW_DEV_TOOLS: + // 打开开发者选项 + DevToolsDialog devToolsDlg = new DevToolsDialog(owner, "开发者选项", browser); + devToolsDlg.setLocationRelativeTo(null); + devToolsDlg.setVisible(true); + devToolsDlg.setResizable(false); + return true; + } + return false; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/listener/OpenAiListener.java b/athena-all/src/main/java/run/mone/m78/ip/listener/OpenAiListener.java new file mode 100644 index 000000000..0acdec9fc --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/listener/OpenAiListener.java @@ -0,0 +1,19 @@ +package run.mone.m78.ip.listener; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import lombok.Data; +import run.mone.openai.StreamListener; + +/** + * @author goodjava@qq.com + * @date 2023/5/19 14:25 + */ +@Data +public abstract class OpenAiListener implements StreamListener { + + private Project project; + + private Editor editor; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/listener/PromptHandler.java b/athena-all/src/main/java/run/mone/m78/ip/listener/PromptHandler.java new file mode 100644 index 000000000..0b50137c4 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/listener/PromptHandler.java @@ -0,0 +1,50 @@ +package run.mone.m78.ip.listener; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.SelectionModel; +import com.intellij.openapi.project.Project; +import run.mone.m78.ip.service.CodeService; +import run.mone.m78.ip.bo.robot.AiChatMessage; +import run.mone.m78.ip.bo.robot.ProjectAiMessageManager; +import run.mone.m78.ip.bo.robot.Role; +import run.mone.m78.ip.common.Const; +import run.mone.m78.ip.service.LocalAiService; +import run.mone.m78.ip.util.ResourceUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.mutable.MutableObject; +import run.mone.ultraman.manager.ConsoleViewManager; +import run.mone.ultraman.service.AiCodeService; +import run.mone.ultraman.state.ProjectFsmManager; + +import java.util.UUID; + +/** + * @author goodjava@qq.com + * @date 2023/12/10 16:01 + */ +public class PromptHandler { + + + //修改用户的问题 + public static String handler(Project project, Req req) { + return ""; + } + + //根据给定的提示更改提示信息,并在需要的情况下生成代码 + private static void changePrompt(Project project, String prompt, MutableObject r, Req req) { + + } + + + //移除选择 + private static void removeSelection(Project project) { + ApplicationManager.getApplication().invokeAndWait(() -> { + Editor editor = CodeService.getEditor(project); + if (null != editor) { + editor.getSelectionModel().removeSelection(); + } + }); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/listener/Req.java b/athena-all/src/main/java/run/mone/m78/ip/listener/Req.java new file mode 100644 index 000000000..216d9e3df --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/listener/Req.java @@ -0,0 +1,26 @@ +package run.mone.m78.ip.listener; + +import java.util.Map; + +public class Req { + + private String cmd; + + private Map data; + + public String getCmd() { + return cmd; + } + + public void setCmd(String cmd) { + this.cmd = cmd; + } + + public Map getData() { + return data; + } + + public void setData(Map data) { + this.data = data; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/listener/RequestHandler.java b/athena-all/src/main/java/run/mone/m78/ip/listener/RequestHandler.java new file mode 100644 index 000000000..b9ebd0c75 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/listener/RequestHandler.java @@ -0,0 +1,12 @@ +package run.mone.m78.ip.listener; + +import org.cef.handler.CefRequestHandlerAdapter; + +/** + * @author goodjava@qq.com + * @date 2023/11/22 18:40 + */ +public class RequestHandler extends CefRequestHandlerAdapter { + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/listener/TreeMouseClickedListener.java b/athena-all/src/main/java/run/mone/m78/ip/listener/TreeMouseClickedListener.java new file mode 100644 index 000000000..d926fc028 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/listener/TreeMouseClickedListener.java @@ -0,0 +1,102 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.listener; + +import com.intellij.ide.BrowserUtil; +import run.mone.m78.ip.bo.SpiderUrl; +import run.mone.m78.ip.service.ImageService; +import run.mone.m78.ip.service.MusicService; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreePath; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.List; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/10 10:59 + */ +public class TreeMouseClickedListener extends MouseAdapter { + + private JTree tree1; + + private JTextField textField1; + + private JPopupMenu popupMenu; + + public TreeMouseClickedListener(JTree tree1, JTextField textField1, JPopupMenu popupMenu) { + this.tree1 = tree1; + this.textField1 = textField1; + this.popupMenu = popupMenu; + } + + @Override + public void mouseClicked(MouseEvent mouseEvent) { + + if (mouseEvent.getClickCount() == 2) { + TreePath path = tree1.getPathForLocation(mouseEvent.getX(), mouseEvent.getY()); + DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); + String data = node.toString(); + System.out.println(data); + + + String text = textField1.getText(); + + if (text.equals("image")) { + new ImageService().openImage(data); + return; + } + + if (text.equals("music")) { + MusicService service = MusicService.ins(); + service.stop(); + + Object root = tree1.getModel().getRoot(); + int count = tree1.getModel().getChildCount(root); + List l = new ArrayList<>(); + for (int i = 0; i < count; i++) { + Object v = tree1.getModel().getChild(root, i); + l.add(v.toString()); + } + + service.playWithUrl(data); + return; + } + + //打开爬虫 + if (text.startsWith("spider")) { + SpiderUrl url = (SpiderUrl) node.getUserObject(); + BrowserUtil.browse(url.getUrl()); + return; + } + + } + + //中键 + if (mouseEvent.getButton() == MouseEvent.BUTTON3) { + if (textField1.getText().equals("task")) { + int x = mouseEvent.getX(); + int y = mouseEvent.getY(); + popupMenu.show(tree1, x, y); + } + } + + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/listener/UltrmanTreeKeyAdapter.java b/athena-all/src/main/java/run/mone/m78/ip/listener/UltrmanTreeKeyAdapter.java new file mode 100644 index 000000000..031eebacc --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/listener/UltrmanTreeKeyAdapter.java @@ -0,0 +1,272 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.listener; + +import com.google.gson.Gson; +import com.intellij.openapi.fileChooser.FileChooser; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.jcef.JBCefApp; +import com.intellij.ui.jcef.JBCefBrowser; +import com.intellij.ui.jcef.JBCefClient; +import run.mone.m78.ip.renderer.CustomIconRenderer; +import run.mone.m78.ip.util.ProjectUtils; +import run.mone.m78.ip.bo.SpiderUrl; +import run.mone.m78.ip.bo.TbTask; +import run.mone.m78.ip.common.ApiCall; +import run.mone.m78.ip.common.ConfigUtils; +import run.mone.m78.ip.service.SpiderService; +import run.mone.m78.ip.service.TaskService; +import run.mone.m78.ip.service.UserService; +import run.mone.m78.ip.util.FileUtils; +import run.mone.m78.ip.util.UltramanConsole; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.cef.browser.CefBrowser; +import org.cef.browser.CefFrame; +import org.cef.browser.CefMessageRouter; +import org.cef.callback.CefContextMenuParams; +import org.cef.callback.CefMediaAccessCallback; +import org.cef.callback.CefMenuModel; +import org.cef.handler.CefContextMenuHandlerAdapter; +import org.cef.handler.CefLifeSpanHandlerAdapter; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import java.awt.*; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/11 11:33 + */ +@Data +@Slf4j +public class UltrmanTreeKeyAdapter extends KeyAdapter { + + private Gson gson = new Gson(); + + private JTextField textField1; + private JTree tree1; + private JPanel webPannel; + private JPanel treePannel; + private int MENU_ID_SHOW_DEV_TOOLS = 288; + + private Project project; + + private JBCefBrowser browser; + + private JBCefClient client; + + public static Map browserMap = new ConcurrentHashMap<>(); + + public UltrmanTreeKeyAdapter(Project project, JTextField textField1, JTree tree1, JPanel webPannel, JPanel treePannel) { + this.project = project; + this.textField1 = textField1; + this.tree1 = tree1; + this.webPannel = webPannel; + this.treePannel = treePannel; + } + + public void loadMone(String apiUrl, String text) { + if (text.startsWith("mone")) { + String[] ss = text.split(":"); + if (JBCefApp.isSupported()) { + //需要退出老浏览器 + if (null != this.browser) { + this.client.dispose(); + this.browser.dispose(); + this.webPannel.remove(this.browser.getComponent()); + log.info("quit browser"); + } + + this.treePannel.setVisible(false); + if (System.getProperty("os.name").contains("Linux")) { + browser = JBCefBrowser.createBuilder().setOffScreenRendering(true).build(); + } else { + browser = JBCefBrowser.createBuilder().setOffScreenRendering(false).build(); + } + this.webPannel.add(browser.getComponent(), BorderLayout.CENTER); + String url = ss.length > 1 ? apiUrl + "?v=1" : apiUrl; + browser.loadURL(url); + + browserMap.put(this.project.getName(), browser); + + client = browser.getJBCefClient(); + + //允许录音 + client.getCefClient().addPermissionHandler((browser, frame, requesting_url, requested_permissions, callback) -> { + callback.Continue(CefMediaAccessCallback.MediaPermissionFlags.DEVICE_AUDIO_CAPTURE); + return true; + }); + + client.addLifeSpanHandler(new CefLifeSpanHandlerAdapter() { + @Override + public boolean onBeforePopup(CefBrowser browser, CefFrame frame, String target_url, String target_frame_name) { + //打开新的链接 + log.info("on before popup:" + browser.getURL() + "," + target_url); + return super.onBeforePopup(browser, frame, target_url, target_frame_name); + } + }, browser.getCefBrowser()); + + //右键菜单 + client.addContextMenuHandler(new CefContextMenuHandlerAdapter() { + @Override + public void onBeforeContextMenu(CefBrowser browser, CefFrame frame, CefContextMenuParams params, CefMenuModel model) { + model.clear(); + model.addItem(CefMenuModel.MenuId.MENU_ID_COPY, "copy"); + model.addItem(CefMenuModel.MenuId.MENU_ID_CUT, "cut"); + model.addItem(CefMenuModel.MenuId.MENU_ID_PASTE, "paste"); + model.setEnabled(CefMenuModel.MenuId.MENU_ID_PASTE, true); + model.addSeparator(); + model.addItem(CefMenuModel.MenuId.MENU_ID_RELOAD, "reload"); + model.addItem(MENU_ID_SHOW_DEV_TOOLS, "Developer options"); + } + + @Override + public boolean onContextMenuCommand(CefBrowser browser, CefFrame frame, CefContextMenuParams params, int commandId, int eventFlags) { + + switch (commandId) { + case 288: + // 打开开发者选项 + DevToolsDialog devToolsDlg = new DevToolsDialog(null, "Developer options", browser); + devToolsDlg.setVisible(true); + return true; + } + return false; + } + }, browser.getCefBrowser()); + + + CefMessageRouter cmr = CefMessageRouter.create(new CefMessageRouter.CefMessageRouterConfig("cef", "cefCancel")); + cmr.addHandler(new ChromeMessageRouterHandler(project), true); + client.getCefClient().addMessageRouter(cmr); + + this.webPannel.setVisible(true); + } + } + } + + @Override + public void keyPressed(KeyEvent keyEvent) { + if (keyEvent.getKeyCode() == KeyEvent.VK_ENTER) { + String text = textField1.getText(); + ApiCall apiCall = new ApiCall(); + this.webPannel.setVisible(false); + this.treePannel.setVisible(true); + + String apiUrl = ConfigUtils.getConfig().getDashServer(); + + if (text.startsWith("mone")) { + loadMone(apiUrl, text); + return; + } + + if (text.equals("music")) { + List list = apiCall.call(ApiCall.MUSIC_API); + setTreeModel("music", list); + } + + if (text.equals("image")) { + List list = apiCall.call(ApiCall.IMAGE_API); + setTreeModel("image", list); + } + + if (text.equals("text")) { + List list = apiCall.call(ApiCall.TEXT_API); + setTreeModel("text", list); + } + + if (text.equals("user")) { + UserService userService = new UserService(); + List list = userService.users(); + setTreeModel("user", list); + } + + if (text.equals("task")) { + TaskService taskService = new TaskService(); + List list = taskService.tasks(ConfigUtils.user()).stream().map(it -> { + TbTask task = gson.fromJson(it, TbTask.class); + return task; + }).collect(Collectors.toList()); + setTreeModel("task", list, it -> it.getContent()); + } + + + if (text.startsWith("spider:")) { + String[] ss = text.split(":"); + SpiderService service = new SpiderService(); + List list = service.list(ss[1]); + setTreeModel("spider", list, (it) -> it.getTitle()); + } + + //文件上传和下载(目前有bug) + if (text.startsWith("&&&file:")) { + String[] ss = text.split(":"); + String cmd = ss[1]; + String name = ss[2]; + + if (cmd.equals("download")) { + FileUtils.download(name, "/tmp/"); + UltramanConsole.append("download " + name + " success"); + } + + if (cmd.equals("upload")) { + try { + FileChooserDescriptor chooserDescriptor = new FileChooserDescriptor(true, true, true, true, true, true); + VirtualFile virtualFile = FileChooser.chooseFile(chooserDescriptor, ProjectUtils.project(), null); + if (null != virtualFile) { + String path = virtualFile.getPath(); + FileUtils.upload(name, path); + UltramanConsole.append("upload " + name + " success"); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + } + } + + + private void setTreeModel(String name, List list) { + setTreeModel(name, list, (str) -> str); + } + + private void setTreeModel(String name, List list, Function function) { + DefaultMutableTreeNode root = new DefaultMutableTreeNode("root"); + list.forEach(it -> { + DefaultMutableTreeNode node = new DefaultMutableTreeNode(function.apply(it)); + node.setUserObject(it); + root.add(node); + }); + DefaultTreeModel treeModel = new DefaultTreeModel(root); + tree1.setModel(treeModel); + tree1.setCellRenderer(new CustomIconRenderer(name)); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/listener/VisionHandler.java b/athena-all/src/main/java/run/mone/m78/ip/listener/VisionHandler.java new file mode 100644 index 000000000..cb5b07f68 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/listener/VisionHandler.java @@ -0,0 +1,135 @@ +package run.mone.m78.ip.listener; + +import cn.hutool.core.codec.Base64; +import com.google.common.collect.ImmutableMap; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.Task; +import com.intellij.openapi.project.Project; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; +import run.mone.m78.ip.bo.GenerateCodeReq; +import run.mone.m78.ip.bo.PromptInfo; +import run.mone.m78.ip.bo.chatgpt.*; +import run.mone.m78.ip.common.ChromeUtils; +import run.mone.m78.ip.common.Prompt; +import run.mone.m78.ip.common.PromptType; +import run.mone.m78.ip.service.LocalAiService; +import run.mone.m78.ip.service.PromptService; +import run.mone.ultraman.background.AthenaTask; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +/** + * @author goodjava@qq.com + * @date 2023/12/10 15:45 + */ +public class VisionHandler { + + public static String handler(Project project, Req req) { + //传递录制的声音 + if (req.getCmd().equals("sound")) { + return saveSound(project, req); + } + + //播放声音 + if (req.getCmd().equals("play sound")) { + return playSound2(project, req); + } + + //多模态,可以对图像提问 + if (req.getCmd().equals("vision")) { + return vision(project, req); + } + return ""; + } + + //保存声音(从chatgpt 哪里获取音频文件) + @NotNull + private static String saveSound(Project project, Req req) { + String res; + String data = req.getData().get("sound"); + String mp3Path = "/tmp/openai.mp3"; + + AthenaTask.start(new Task.Backgroundable(project, "save sound", true) { + @Override + public void run(@NotNull ProgressIndicator indicator) { + try { + byte[] newData = Base64.decode(data.getBytes()); + Files.write(Paths.get(mp3Path), newData); + } catch (IOException e) { + throw new RuntimeException(e); + } + Pair r = LocalAiService.callChatgptTranscriptions(new File(mp3Path)); + ChromeUtils.call(project.getName(), r.getValue(), 0); + if (r.getKey() == 0) { + callBot(project, r.getValue()); + } + } + }); + res = "ok:" + data.length(); + return res; + } + + @NotNull + private static String playSound2(Project project, Req req) { + String res; + AthenaTask.start(new Task.Backgroundable(project, "play sound", true) { + @Override + public void run(@NotNull ProgressIndicator indicator) { + Pair v = playSound(req); + if (v.getKey() == 0) { + String s = v.getValue(); + ChromeUtils.call(project.getName(), s, 777); + } + } + }); + res = ""; + return res; + } + + //多模态能力(可以识别图片) + @NotNull + private static String vision(Project project, Req req) { + String res; + String text = req.getData().get("text"); + String image = req.getData().get("image_url"); + ReqMessage r = ReqMessage.builder() + .content(com.google.common.collect.Lists.newArrayList( + ReqContent.builder().type("text").text(text).build(), + ReqContent.builder().type("image_url").image_url(ImageUrl.builder().url(image).build()).build() + )).build(); + + AthenaTask.start(new Task.Backgroundable(project, "vision", true) { + @Override + public void run(@NotNull ProgressIndicator indicator) { + String rv = LocalAiService.vision(VisionReq.builder().messages(com.google.common.collect.Lists.newArrayList(r)).build()); + ChromeUtils.call(project.getName(), rv, 0); + } + }); + res = ""; + return res; + } + + private static Pair playSound(Req req) { + return LocalAiService.speech(SpeechReq.builder().input(req.getData().get("input")).build()); + } + + public static void callBot(Project project, String prompt) { + ApplicationManager.getApplication().invokeLater(() -> { + PromptInfo promptInfo = Prompt.getPromptInfo("bot"); + PromptType promptType = Prompt.getPromptType(promptInfo); + PromptService.dynamicInvoke(GenerateCodeReq.builder() + .project(project) + .promptType(promptType) + .promptInfo(promptInfo) + .promptName(promptInfo.getPromptName()) + .param(ImmutableMap.of("code", prompt)) + .promptName("bot").build()); + }); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/renderer/CustomIconRenderer.java b/athena-all/src/main/java/run/mone/m78/ip/renderer/CustomIconRenderer.java new file mode 100644 index 000000000..cb3aa7f7e --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/renderer/CustomIconRenderer.java @@ -0,0 +1,36 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.renderer; + +import com.intellij.openapi.util.IconLoader; + +import javax.swing.tree.DefaultTreeCellRenderer; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/12 09:53 + */ +public class CustomIconRenderer extends DefaultTreeCellRenderer { + + + public CustomIconRenderer(String name) { + openIcon = IconLoader.getIcon("/icons/" + name + ".png"); + setLeafIcon(openIcon); + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/search/AthenaSearchEverywhereContributor.java b/athena-all/src/main/java/run/mone/m78/ip/search/AthenaSearchEverywhereContributor.java new file mode 100644 index 000000000..4c504f2dd --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/search/AthenaSearchEverywhereContributor.java @@ -0,0 +1,178 @@ +package run.mone.m78.ip.search; + +import com.intellij.ide.actions.searcheverywhere.SearchEverywhereContributor; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMethod; +import com.intellij.util.Processor; +import run.mone.m78.ip.bo.ElementInfo; +import run.mone.m78.ip.bo.GenerateCodeReq; +import run.mone.m78.ip.common.Prompt; +import run.mone.m78.ip.common.PromptType; +import run.mone.m78.ip.service.CodeService; +import run.mone.m78.ip.service.PromptService; +import run.mone.m78.ip.bo.PromptInfo; +import run.mone.m78.ip.common.Const; +import run.mone.m78.ip.util.LabelUtils; +import lombok.SneakyThrows; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import run.mone.openai.common.MutableObject; + +import javax.swing.*; +import java.awt.*; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2023/5/27 12:08 + */ +public class AthenaSearchEverywhereContributor implements SearchEverywhereContributor { + + private Project project; + + private Module module; + + public AthenaSearchEverywhereContributor(Project project, Module module) { + this.project = project; + this.module = module; + } + + @NotNull + @Override + public String getSearchProviderId() { + return "AthenaTab"; + } + + @NotNull + @Override + public String getGroupName() { + return "Athena"; + } + + + @Override + public boolean showInFindResults() { + return true; + } + + + /** + * 真正执行prompt的地方 + * + * @param selectedItem item chosen by user + * @param text text from search field + * @return + */ + @Override + public boolean processSelectedItem(@NotNull AthenaSearchInfo selectedItem, int modifiers, @NotNull String text) { + String promptName = selectedItem.getValue(); + PromptInfo promptInfo = Prompt.getPromptInfo(promptName); + PromptType promptType = Prompt.getPromptType(promptInfo); + PromptService.dynamicInvoke(GenerateCodeReq.builder().project(this.project).module(module).promptName(promptInfo.getPromptName()).promptInfo(promptInfo).promptType(promptType).build()); + return true; + } + + @Override + public @NotNull ListCellRenderer getElementsRenderer() { + return new DefaultListCellRenderer() { + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + if (value instanceof AthenaSearchInfo) { + AthenaSearchInfo si = (AthenaSearchInfo) value; + setText(si.getDesc() + ":" + si.getMethodName()); + } + return this; + } + }; + } + + @Nullable + @Override + public Object getDataForItem(@NotNull AthenaSearchInfo element, @NotNull String dataId) { + return null; + } + + @Override + public int getSortWeight() { + return 0; + } + + @Override + public boolean isShownInSeparateTab() { + return true; + } + + @Override + public boolean isEmptyPatternSupported() { + return true; + } + + + @Override + public void fetchElements(@NotNull String pattern, @NotNull ProgressIndicator progressIndicator, @NotNull Processor consumer) { + if (LabelUtils.open(this.project, Const.DISABLE_SEARCH)) { + return; + } + List promptList = Prompt.promptList(Const.SEARCH); + List list = promptList.stream().map(prompt -> { + ElementInfo ei = getElementInfo(prompt); + return AthenaSearchInfo.builder().methodName(ei.getName()).value(prompt.getPromptName()).desc(prompt.getDesc()).build(); + }).collect(Collectors.toList()); + + // 根据输入的 pattern 进行过滤 + List filteredList = pattern.isBlank() ? list : list.stream() + .filter(info -> null != info.getMethodName() && (info.getDesc().contains(pattern) || info.getMethodName().contains(pattern))) + .toList(); + + for (AthenaSearchInfo item : filteredList) { + if (progressIndicator.isCanceled()) { + return; + } + consumer.process(item); + } + } + + + @SneakyThrows + private ElementInfo getElementInfo(PromptInfo promptInfo) { + MutableObject mo = new MutableObject<>(); + mo.setData(ElementInfo.builder().name("").build()); + PromptType promptType = Prompt.getPromptType(promptInfo); + SwingUtilities.invokeAndWait(() -> { + switch (promptType) { + case comment, lineByLineComment, modifyMethod, createMethod2, removeComment, createMethod -> { + PsiMethod method = (PsiMethod) CodeService.getParentOfType(this.project, PsiMethod.class); + if (null != method) { + ElementInfo ei = ElementInfo.builder().name(method.getName()).build(); + mo.setData(ei); + } + } + case modifyClass, createClass, createFile -> { + PsiClass psiClass = (PsiClass) CodeService.getParentOfType(this.project, PsiClass.class); + if (null != psiClass) { + ElementInfo ei = ElementInfo.builder().name(psiClass.getName()).build(); + mo.setData(ei); + } + } + default -> { + PsiMethod method = (PsiMethod) CodeService.getParentOfType(this.project, PsiMethod.class); + if (null == method) { + ElementInfo ei = ElementInfo.builder().name("").build(); + mo.setData(ei); + } else { + ElementInfo ei = ElementInfo.builder().name(method.getName()).build(); + mo.setData(ei); + } + } + } + }); + return mo.getData(); + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/search/AthenaSearchEverywhereContributorFactory.java b/athena-all/src/main/java/run/mone/m78/ip/search/AthenaSearchEverywhereContributorFactory.java new file mode 100644 index 000000000..322776cef --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/search/AthenaSearchEverywhereContributorFactory.java @@ -0,0 +1,23 @@ +package run.mone.m78.ip.search; + +import com.intellij.ide.actions.searcheverywhere.SearchEverywhereContributor; +import com.intellij.ide.actions.searcheverywhere.SearchEverywhereContributorFactory; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.module.Module; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author goodjava@qq.com + * @date 2023/5/27 12:08 + */ +public class AthenaSearchEverywhereContributorFactory implements SearchEverywhereContributorFactory { + + + @Override + public @NotNull SearchEverywhereContributor createContributor(@NotNull AnActionEvent initEvent) { + @Nullable Module module = initEvent.getData(LangDataKeys.MODULE); + return new AthenaSearchEverywhereContributor(initEvent.getProject(), module); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/search/AthenaSearchInfo.java b/athena-all/src/main/java/run/mone/m78/ip/search/AthenaSearchInfo.java new file mode 100644 index 000000000..04ec19f11 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/search/AthenaSearchInfo.java @@ -0,0 +1,27 @@ +package run.mone.m78.ip.search; + +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/5/27 12:08 + */ +@Data +@Builder +public class AthenaSearchInfo implements Serializable { + + private String type; + + private String selectValue; + + private String value; + + private String desc; + + private String methodName; + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/search/MyChooseByNameContributor.java b/athena-all/src/main/java/run/mone/m78/ip/search/MyChooseByNameContributor.java new file mode 100644 index 000000000..14fe6670c --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/search/MyChooseByNameContributor.java @@ -0,0 +1,74 @@ +package run.mone.m78.ip.search; + +import com.intellij.navigation.ChooseByNameContributor; +import com.intellij.navigation.ItemPresentation; +import com.intellij.navigation.NavigationItem; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.NlsSafe; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +/** + * @author goodjava@qq.com + * @date 2023/5/27 09:34 + */ +public class MyChooseByNameContributor implements ChooseByNameContributor { + + + @NotNull + @Override + public String[] getNames(Project project, boolean includeNonProjectItems) { + // Return the names of the elements you want to include in the search results. + return new String[]{"MyCustomElement"}; + } + + @NotNull + @Override + public NavigationItem[] getItemsByName(String name, String pattern, Project project, boolean includeNonProjectItems) { + // Return the elements that match the given name. + if ("MyCustomElement".equals(name)) { + return new NavigationItem[]{new NavigationItem() { + @Override + public @Nullable @NlsSafe String getName() { + return "run.mone.service.MoneService"; + } + + @Override + public @Nullable ItemPresentation getPresentation() { + return new ItemPresentation() { + @Override + public @NlsSafe @Nullable String getPresentableText() { + return "vvv"; + } + + @Override + public @Nullable Icon getIcon(boolean unused) { + return null; + } + }; + } + + @Override + public void navigate(boolean requestFocus) { + + } + + @Override + public boolean canNavigate() { + return true; + } + + @Override + public boolean canNavigateToSource() { + return true; + } + }}; + } + return new NavigationItem[0]; + } + + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/search/MyCustomNavigationItem.java b/athena-all/src/main/java/run/mone/m78/ip/search/MyCustomNavigationItem.java new file mode 100644 index 000000000..d2f29b12c --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/search/MyCustomNavigationItem.java @@ -0,0 +1,65 @@ +package run.mone.m78.ip.search; + +import com.intellij.navigation.ItemPresentation; +import com.intellij.navigation.NavigationItem; +import com.intellij.openapi.util.NlsSafe; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +/** + * @author goodjava@qq.com + * @date 2023/5/27 09:35 + */ +public class MyCustomNavigationItem implements NavigationItem { + + @Override + public void navigate(boolean requestFocus) { + // Implement the navigation logic here. + } + + @Override + public boolean canNavigate() { + return true; + } + + @Override + public boolean canNavigateToSource() { + return true; + } + + + @Override + public @Nullable @NlsSafe String getName() { + return "run.mone.service.MoneService"; + } + + @Nullable + @Override + public ItemPresentation getPresentation() { + return new ItemPresentation() { + @Nullable + @Override + public String getPresentableText() { + return "MyCustomElement"; + } + + @Nullable + @Override + public String getLocationString() { + return "gopgogogogo"; + } + + @Nullable + @Override + public Icon getIcon(boolean unused) { + return null; + } + }; + } +} + + + + + diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/AbstractService.java b/athena-all/src/main/java/run/mone/m78/ip/service/AbstractService.java new file mode 100644 index 000000000..aa64165d0 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/service/AbstractService.java @@ -0,0 +1,48 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.service; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import run.mone.m78.ip.common.Context; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/7 21:01 + */ +public abstract class AbstractService { + + private AbstractService next; + + public abstract void execute(Context context, AnActionEvent e); + + + public void setNext(AbstractService service) { + this.next = service; + } + + + public void next(Context context, AnActionEvent e) { + if (null != next) { + this.next.execute(context, e); + } else { + //到尾部了 + context.setStatus(1); + } + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/AiService.java b/athena-all/src/main/java/run/mone/m78/ip/service/AiService.java new file mode 100644 index 000000000..9fb373b27 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/service/AiService.java @@ -0,0 +1,24 @@ +package run.mone.m78.ip.service; + +import com.google.gson.JsonObject; +import run.mone.m78.ip.common.Const; +import run.mone.m78.ip.util.LabelUtils; + +/** + * @author goodjava@qq.com + * @date 2023/12/5 22:51 + */ +public class AiService { + + + //同时支持远程和本地的(本地的被限流的次数会更少) + public static JsonObject call(String req, long timeout, boolean vip) { + if (LabelUtils.open(Const.OPEN_AI_TEST)) { + return LocalAiService.call(req, timeout); + } + return ProxyAiService.call(req, timeout, vip); + + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/ChatGptService.java b/athena-all/src/main/java/run/mone/m78/ip/service/ChatGptService.java new file mode 100644 index 000000000..cb32a1ba1 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/service/ChatGptService.java @@ -0,0 +1,31 @@ +package run.mone.m78.ip.service; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import run.mone.m78.ip.common.Context; +import lombok.extern.slf4j.Slf4j; + +/** + * @author goodjava@qq.com + * @date 2023/3/11 21:36 + *

+ * 在editor中生成代码的都走这里了 + */ +@Slf4j +public class ChatGptService extends AbstractService { + + + @Override + public void execute(Context context, AnActionEvent e) { + String content = context.getContent(); + if (null != e) { + context.setProject(e.getProject()); + } + if (!(content.startsWith("//"))) { + next(context, e); + return; + } + PromptService.generateMethod(e.getProject(), content); + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/ClassFinder.java b/athena-all/src/main/java/run/mone/m78/ip/service/ClassFinder.java new file mode 100644 index 000000000..a4eec91e5 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/service/ClassFinder.java @@ -0,0 +1,28 @@ +package run.mone.m78.ip.service; + +import com.intellij.openapi.project.Project; +import run.mone.m78.ip.bo.ClassInfo; +import run.mone.m78.ip.util.AnnoUtils; +import org.apache.commons.compress.utils.Lists; + +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/5/23 13:36 + */ +public class ClassFinder { + + + public static List findClassList(Project project, String type, String name, String moduleName) { + if (type.equals("anno")) { + return AnnoUtils.findClassWithAnno(project, name, moduleName); + } + if (type.equals("endWith")) { + return CodeService.getClassList(project, name, moduleName); + } + return Lists.newArrayList(); + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/ClipboardService.java b/athena-all/src/main/java/run/mone/m78/ip/service/ClipboardService.java new file mode 100644 index 000000000..a6f52344c --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/service/ClipboardService.java @@ -0,0 +1,34 @@ +package run.mone.m78.ip.service; + +import lombok.SneakyThrows; + +import java.awt.*; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; + +/** + * @author goodjava@qq.com + * @date 2023/5/21 23:27 + */ +public class ClipboardService { + + + /** + * 从剪贴板复制东西 + * @return + */ + @SneakyThrows + public static String getData() { + Toolkit toolkit = Toolkit.getDefaultToolkit(); + Clipboard clipboard = toolkit.getSystemClipboard(); + DataFlavor[] flavors = new DataFlavor[]{ + DataFlavor.stringFlavor // 获取剪贴板中的文本内容 + }; + Transferable contents = clipboard.getContents(null); + String text = (String) contents.getTransferData(flavors[0]); + return text; + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/CodeService.java b/athena-all/src/main/java/run/mone/m78/ip/service/CodeService.java new file mode 100644 index 000000000..484d72e19 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/service/CodeService.java @@ -0,0 +1,861 @@ +package run.mone.m78.ip.service; + +import com.google.common.collect.Maps; +import com.google.gson.Gson; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.PsiTreeUtil; +import run.mone.m78.ip.bo.ClassInfo; +import run.mone.m78.ip.bo.GenerateCodeReq; +import run.mone.m78.ip.bo.MessageConsumer; +import run.mone.m78.ip.bo.ProxyAsk; +import run.mone.m78.ip.common.Context; +import run.mone.m78.ip.util.EditorUtils; +import run.mone.m78.ip.util.ImportUtils; +import run.mone.m78.ip.util.PsiClassUtils; +import run.mone.m78.ip.util.UltramanConsole; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import okhttp3.Response; +import org.apache.commons.compress.utils.Lists; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Model; +import org.apache.maven.model.io.xpp3.MavenXpp3Reader; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import run.mone.ultraman.common.ImportCode; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.function.BiConsumer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + */ +@Slf4j +public class CodeService extends AbstractService { + + private static Gson gson = new Gson(); + + /** + * 打个某个指定的class + * + * @param project + * @param className + */ + public static PsiClass openJavaClass(Project project, String className) { + return null; + } + + + public static PsiClass[] getClassesInPackage(Project project, String packageName) { + return null; + } + + + /** + * 移动到方法的开头,且插入空行 + * Navigate to the beginning of the method and insert a blank line. + * + * @param project + */ + public static void moveToMethodAndInsertLine(Project project) { + + } + + public static String getMethodAndLineNumbers(PsiMethod method) { + return ""; + } + + public static String getClassName(PsiClass psiClass) { + return ""; + } + + + private static boolean readCodeContinue(String lineCode) { + return lineCode.trim().startsWith("//") || lineCode.trim().startsWith("/*") + || lineCode.trim().startsWith("*") || lineCode.trim().startsWith("*/"); + } + + public static String getClassAndLineNumbers(PsiClass psiClass) { + return ""; + } + + public static void addField(Project project, Document document, PsiClass psiClass, String code, String name) { + + } + + /** + * 添加方法 + * + * @param project + * @param code + */ + public static void addMethod(Project project, String code) { + + } + + + public static void insertCode(Project project, String code) { + } + + public static void insertCode(Project project, String code, boolean enter) { + } + + + /** + * 添加 import list + * + * @param project + * @param importStrList + */ + @SneakyThrows + public static void addImport(Project project, List importStrList) { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + addImport(project, editor, importStrList); + } + + + public static void addImport(Project project, Editor editor, List importStrList) { + ImportUtils.addImport(project, editor, importStrList); + } + + + public static PsiClass createPsiClass(PsiElementFactory factory, String className) { + return ImportUtils.createPsiClass(factory, className); + } + + + /** + * 根据需求直接生成方法 + * + * @param project + * @param prompt + */ + public static void generateMethod(Project project, String prompt) { + } + + /** + * 向方法中添加语句 + * + * @param project + * @param code + */ + public static void addStatementToMethod(Project project, String code) { + + } + + /** + * 把代码写入Idea Editor + * + * @param project + * @param editor + * @param code + */ + public static void writeCode2(Project project, Editor editor, String code) { + writeCode4(project, editor, code, true); + } + + public static void writeCode4(Project project, Editor editor, String code, boolean appendT) { + + } + + public static void moveCaretToEndOfLine(Editor editor) { + Document document = editor.getDocument(); + CaretModel caretModel = editor.getCaretModel(); + int lineNumber = document.getLineNumber(caretModel.getOffset()); + int lineEndOffset = document.getLineEndOffset(lineNumber); + caretModel.moveToOffset(lineEndOffset); + } + + private static boolean isFirstColumn(int offset, Editor editor) { + int lineNumber = editor.getDocument().getLineNumber(offset); + int lineStartOffset = editor.getDocument().getLineStartOffset(lineNumber); + boolean isFirstColumn = (offset - lineStartOffset) == 0; + return isFirstColumn; + } + + + public static void writeCode3(Project project, String code) { + UltramanConsole.append(project, code, false); + } + + + public static Pair lineAndColumnNum(Document document, int offset) { + int lineNumber = document.getLineNumber(offset) + 1; + int columnNumber = offset - document.getLineStartOffset(lineNumber - 1); + return Pair.of(lineNumber, columnNumber); + } + + + /** + * 移动到指定行号 + * + * @param project + * @param lineNumber + */ + public static void moveLine(Project project, int lineNumber) { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + LogicalPosition position = new LogicalPosition(lineNumber - 1, 0); // 创建逻辑位置对象 + editor.getCaretModel().moveToLogicalPosition(position); // 将光标移动到指定行 + } + + + /** + * 关闭当前Editor + * + * @param project + */ + public static void closeEditor(Project project) { + EditorUtils.closeEditor(project); + } + + /** + * 格式化当前代码 + */ + public static void formatCode(Project project) { + if (null == project) { + return; + } + } + + @Nullable + public static Project deleteCode(@NotNull Editor editor) { + return null; + } + + + /** + * 删除指定行 + * + * @param project + * @param lineToDelete + */ + public static void deleteLine(Project project, int lineToDelete) { + } + + + /** + * 返回所有method + * + * @param project + * @return + */ + public static List methods(Project project) { + Editor editor = getEditor(project); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + PsiElement elementAtCaret = psiFile.findElementAt(editor.getCaretModel().getOffset()); + PsiClass currentPsiClass = PsiTreeUtil.getParentOfType(elementAtCaret, PsiClass.class); + return Arrays.stream(currentPsiClass.getAllMethods()).map(it -> it.getName()).collect(Collectors.toList()); + } + + + /** + * 通过module查询会快点 + * + * @param project + * @param module + * @param name + * @return + */ + public static PsiClass getPsiClass(Project project, Module module, String name) { + PsiClass psiClass = JavaPsiFacade.getInstance(project).findClass(name, GlobalSearchScope.moduleScope(module)); + return psiClass; + } + + + public static List methods(PsiClass psiClass) { + return Arrays.stream(psiClass.getMethods()).filter(it -> it.getModifierList().hasModifierProperty("public")).map(it -> it.getName()).collect(Collectors.toList()); + } + + + public static List fields(Project project) { + Editor editor = getEditor(project); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + PsiElement elementAtCaret = psiFile.findElementAt(editor.getCaretModel().getOffset()); + PsiClass currentPsiClass = PsiTreeUtil.getParentOfType(elementAtCaret, PsiClass.class); + return Arrays.stream(currentPsiClass.getAllFields()).map(it -> it.getName()).collect(Collectors.toList()); + } + + public static PsiMethod getMethod(Project project) { + return null; + } + + public static String getMethodCode(Project project) { + return ApplicationManager.getApplication().runReadAction((Computable) () -> getMethod(project).getText()); + } + + public static PsiField getPsiField(Project project) { + return null; + } + + + public static boolean isTextSelected(Editor editor) { + return editor.getSelectionModel().hasSelection(); + } + + public static String getSelectedText(Editor editor) { + if (isTextSelected(editor)) { + SelectionModel selectionModel = editor.getSelectionModel(); + String selectedText = selectionModel.getSelectedText(); + return selectedText; + } + return ""; + } + + + public static PsiElement getSelectedPsiMethod(Editor editor, PsiFile psiFile) { + SelectionModel selectionModel = editor.getSelectionModel(); + int start = selectionModel.getSelectionStart(); + int end = selectionModel.getSelectionEnd(); + for (int i = start; i < end; i++) { + PsiElement element = psiFile.findElementAt(i); + @Nullable PsiMethod pm = PsiTreeUtil.getParentOfType(element, PsiMethod.class); + if (null != pm) { + return pm; + } + } + return null; + } + + public static PsiMethod getPsiMethodWithLineNum(Project project, Document document, int lineNum) { + return null; + } + + public static PsiField getPsiFieldWithLineNum(Project project, Document document, int lineNum) { + return ApplicationManager.getApplication().runReadAction((Computable) () -> { + @Nullable PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document); + int start = document.getLineStartOffset(lineNum - 1); + int end = document.getLineEndOffset(lineNum - 1); + for (int i = start; i < end; i++) { + PsiElement element = psiFile.findElementAt(i); + @Nullable PsiField field = PsiTreeUtil.getParentOfType(element, PsiField.class); + if (null != field) { + return field; + } + } + return null; + }); + } + + + public static PsiClass getPsiClassWithLineNum(Project project, Document document, int lineNum) { + return ApplicationManager.getApplication().runReadAction((Computable) () -> { + @Nullable PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document); + int start = document.getLineStartOffset(lineNum - 1); + int end = document.getLineEndOffset(lineNum - 1); + for (int i = start; i < end; i++) { + PsiElement element = psiFile.findElementAt(i); + @Nullable PsiClass pm = PsiTreeUtil.getParentOfType(element, PsiClass.class); + if (null != pm) { + return pm; + } + } + return null; + }); + + } + + + public static TextRange getTextRange(Project project, final Class clazz) { + Editor editor = getEditor(project); + CaretModel caretModel = editor.getCaretModel(); + int offset = caretModel.getOffset(); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + PsiElement elementAtCaret = psiFile.findElementAt(offset); + + while (true) { + if (elementAtCaret.getClass().equals(clazz)) { + return elementAtCaret.getTextRange(); + } + elementAtCaret = elementAtCaret.getParent(); + if (null == elementAtCaret) { + return null; + } + } + } + + public static String getText(Project project, Class clazz) { + Editor editor = getEditor(project); + CaretModel caretModel = editor.getCaretModel(); + int offset = caretModel.getOffset(); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + PsiElement elementAtCaret = psiFile.findElementAt(offset); + PsiElement element = PsiTreeUtil.getParentOfType(elementAtCaret, clazz); + return element.getText(); + } + + public static TextRange getParentTextRange(Project project) { + Editor editor = getEditor(project); + CaretModel caretModel = editor.getCaretModel(); + int offset = caretModel.getOffset(); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + return psiFile.findElementAt(offset).getParent().getParent().getTextRange(); + } + + + public static PsiClass getPsiClass(Project project) { + Editor editor = getEditor(project); + if (null == editor) { + return null; + } + CaretModel caretModel = editor.getCaretModel(); + int offset = caretModel.getOffset(); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + PsiElement elementAtCaret = psiFile.findElementAt(offset); + PsiClass psiClass = PsiTreeUtil.getParentOfType(elementAtCaret, PsiClass.class); + return psiClass; + } + + + public static PsiElement getParentOfType(Project project, Class clazz) { + Editor editor = getEditor(project); + if (null == editor) { + return null; + } + CaretModel caretModel = editor.getCaretModel(); + int offset = caretModel.getOffset(); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + PsiElement elementAtCaret = psiFile.findElementAt(offset); + PsiElement res = PsiTreeUtil.getParentOfType(elementAtCaret, clazz); + return res; + } + + + public static PsiClass getPsiClass2(Project project) { + Editor editor = getEditor(project); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + PsiClass psiClass = Arrays.stream(psiFile.getChildren()).filter(it -> it instanceof PsiClass).map(it -> (PsiClass) it).findFirst().get(); + return psiClass; + } + + + public static PsiMethod getMethod(PsiClass psiClass, String methodName) { + PsiMethod[] methods = psiClass.findMethodsByName(methodName, false); + return methods[0]; + } + + + public static Map getLineContentsAndNumbersForMethod(PsiMethod method) { + return Maps.newHashMap(); + } + + + public static String getClassText(Project project) { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + return editor.getDocument().getText(); + } + + public static String getClassText2(Project project) { + return ""; + } + + + /** + * 根据prompt删除注解 + * + * @param project + */ + public static void removeComments(Project project) { + } + + + public static void createEmptyClass(Project project, String moduleName, String packageName, String className) { + createEmptyClass(project, moduleName, packageName, className, false); + } + + /** + * 创建空的类 + * + * @param project + * @param packageName + * @param className + */ + public static void createEmptyClass(Project project, String moduleName, String packageName, String className, boolean testPath) { + PsiClassUtils.createEmptyClass(project, moduleName, packageName, className, testPath); + } + + + public static void createEmptyClass(Project project, String moduleName, String packageName, String className, boolean testPath, boolean isInterface) { + PsiClassUtils.createEmptyClass(project, moduleName, packageName, className, testPath, false, null, isInterface); + } + + + public static void createEmptyClass(Project project, String moduleName, String packageName, String className, boolean testPath, List annoList) { + PsiClassUtils.createEmptyClass(project, moduleName, packageName, className, testPath, annoList); + } + + + public static PsiDirectory getSourceDirectory(Project project, String moduleName, boolean testPath) { + return PsiClassUtils.getSourceDirectory(project, moduleName, testPath); + } + + public static PsiDirectory getSourceDirectory(Project project, boolean testPath, String packagePath) { + return PsiClassUtils.getSourceDirectory(project, testPath, packagePath); + } + + public static PsiDirectory getSourceDirectory(Project project) { + return PsiClassUtils.getSourceDirectory(project, "", false); + } + + + public static List getClassByServiceAnno(Project project, String anno) { + return null; + } + + private static List getAllJavaFiles(PsiDirectory dir) { + return null; + } + + + /** + * 创建包路径 + * + * @param project + * @param packageName + */ + public static void createPackage(Project project, String packageName) { + + } + + public static List listMethodInfo(String clazz) { + return Lists.newArrayList(); + } + + /** + * 生成一个moon demo的handler + * + * @param project + */ + public static void generateMoonHandler(Project project) { + + } + + /** + * 获取当前类的package 路径 + * + * @param project + * @return 包路径 + */ + public static String getPackagePath(Project project) { + Editor editor = getEditor(project); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + PsiElement elementAtCaret = psiFile.findElementAt(editor.getCaretModel().getOffset()); + // 获取最近的PsiClass + PsiClass currentPsiClass = PsiTreeUtil.getParentOfType(elementAtCaret, PsiClass.class); + PsiJavaFile psiJavaFile = (PsiJavaFile) currentPsiClass.getContainingFile(); + PsiPackage psiPackage = JavaPsiFacade.getInstance(currentPsiClass.getProject()).findPackage(psiJavaFile.getPackageName()); + return psiPackage.getQualifiedName(); + } + + + @Override + public void execute(Context context, AnActionEvent e) { + this.next(context, e); + } + + public static void addClassAnno(Project project, PsiClass psiClass, List annoList) { + + } + + /** + * 删除这个编辑器中的所有内容 + * + * @param project + */ + public static void deleteCode(Project project) { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + WriteCommandAction.runWriteCommandAction(project, () -> { + editor.getDocument().setText(""); + }); + Caret caret = editor.getCaretModel().getPrimaryCaret(); + caret.moveToOffset(0); + } + + public static void deleteTextRange(Project project, TextRange range) { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + WriteCommandAction.runWriteCommandAction(project, () -> { + Document document = editor.getDocument(); + document.deleteString(range.getStartOffset(), range.getEndOffset()); + PsiDocumentManager.getInstance(project).commitDocument(document); + }); + } + + + public static boolean isClass(String text) { + if (text.contains(" class ")) { + return true; + } + return false; + } + + public static boolean isPrivateField(String text) { + if (text.contains("private") && text.contains(";")) { + return true; + } + return false; + } + + + private static Integer getNumFromStr(String str) { + Pattern pattern = Pattern.compile("\\d+"); + Matcher matcher = pattern.matcher(str); + String lineNumber = "0"; + if (matcher.find()) { + lineNumber = matcher.group(); + } + return Integer.valueOf(lineNumber); + } + + /** + * 通过chatgpt生成代码,然后插入编辑器中 + * + * @param project + * @param context + * @param prompt + */ + public static void generateCodeWithAi(Project project, String context, String[] prompt, BiConsumer consumer) { + + } + + public static void generateCodeWithAi2(Project project, String promptName, String[] pramas, BiConsumer consumer) { + generateCodeWithAi3(project, promptName, pramas, Maps.newHashMap(), consumer); + } + + + public static void generateCodeWithAi3(Project project, String promptName, String[] pramas, Map paramMap, BiConsumer consumer) { + generateCodeWithAi4(project, promptName, pramas, paramMap, consumer, new MessageConsumer()); + } + + + public static void generateCodeWithAi4(Project project, String promptName, String[] pramas, Map paramMap, BiConsumer consumer, MessageConsumer messageConsumer) { + generateCodeWithAi5(GenerateCodeReq.builder().promptName(promptName).project(project).build(), project, promptName, pramas, paramMap, consumer, messageConsumer); + } + + + @SneakyThrows + public static String call(String promptName, Map paramMap) { + return ""; + } + + + public static void generateCodeWithAi5(GenerateCodeReq req, Project project, String promptName, String[] pramas, Map paramMap, BiConsumer consumer, MessageConsumer messageConsumer) { + + } + + public static void setModelAndDebug(Project project, ProxyAsk pa, Map paramMap, GenerateCodeReq req) { + } + + private static int getCodeSize(Map paramMap) { + return 1; + } + + + @NotNull + private static String getErrorMessage(Throwable t, Response response) { + String message = ""; + if (null != response) { + message = response.message(); + if (StringUtils.isNotEmpty(message)) { + message = "错误原因:" + message; + } else { + message = ""; + } + } + if (null != t) { + message += t.getMessage(); + } + return message; + } + + + public static void generateCodeWithAi(Project project, String context, String[] prompt) { + generateCodeWithAi(project, context, prompt, (p, code) -> { + writeCode(p, code); + }); + } + + + /** + * 直接插入代码 + * + * @param project + * @param str + */ + public static void writeCode(Project project, String str) { + + } + + + /** + * 选中一个方法 + * + * @param project + */ + public static PsiMethod selectMethod(Project project) { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + if (null == editor) { + return null; + } + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + if (psiFile == null) { + return null; + } + PsiElement element = psiFile.findElementAt(editor.getCaretModel().getOffset()); + PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class); + return method; + } + + public static void deleteMethod(Project project, PsiMethod method) { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + if (null == editor) { + return; + } + + if (null == method) { + return; + } + Document document = editor.getDocument(); + int startOffset = method.getTextRange().getStartOffset(); + + editor.getCaretModel().getPrimaryCaret().moveToOffset(startOffset); + + int endOffset = method.getTextRange().getEndOffset(); + WriteCommandAction.runWriteCommandAction(project, () -> document.deleteString(startOffset, endOffset)); + } + + public static void deletePsiClass(Project project, PsiClass psiClass) { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + Document document = editor.getDocument(); + int startOffset = psiClass.getTextRange().getStartOffset(); + editor.getCaretModel().getPrimaryCaret().moveToOffset(startOffset); + int endOffset = psiClass.getTextRange().getEndOffset(); + WriteCommandAction.runWriteCommandAction(project, () -> document.deleteString(startOffset, endOffset)); + } + + + public static Editor getEditor(Project project) { + return EditorUtils.getEditor(project); + } + + public static Document getDocument(Project project) { + return getEditor(project).getDocument(); + } + + + /** + * 添加空行 + * + * @param project + * @param document + * @param num + */ + public static void addLineBreak(Project project, Document document, int lineNum, int num) { + + } + + public static List getClassList(Project project, String end, String mn) { + return null; + } + + + private static String findPomDependencies(String basePath, String groupId, String artifactId, String version) throws IOException { + File baseDir = new File(basePath); + String[] extensions = {"xml"}; + boolean recursive = true; + + Collection pomFiles = FileUtils.listFiles(baseDir, extensions, recursive); + for (File pomFile : pomFiles) { + try { + MavenXpp3Reader reader = new MavenXpp3Reader(); + Model model = reader.read(new FileReader(pomFile)); + List dependencies = model.getDependencies(); + for (Dependency dependency : dependencies) { + if (dependency.getGroupId().equals(groupId) && + dependency.getArtifactId().equals(artifactId) && + dependency.getVersion().equals(version)) { + // 找到了指定的依赖项 + return "找到了"; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + return "没找到"; + } + + + /** + * 获取方法的注释 + * + * @param psiMethod + * @return + */ + public static String getMethodComment(PsiMethod psiMethod) { + PsiDocComment comment = psiMethod.getDocComment(); + if (comment != null) { + return comment.getText(); + } + return null; + } + + /** + * 获取属性的注释 + * + * @param psiField + * @return + */ + public static String getFieldComment(PsiField psiField) { + PsiDocComment comment = psiField.getDocComment(); + if (comment != null) { + return comment.getText(); + } + return ""; + } + + public static ImportCode createClassAndAddEmptyLine(Project project, String module, String packageName, String className, String classNameSuffix, boolean isTestClass, boolean isInterface) { + return null; + } + + private static void addEmptyLine(Project project, PsiClass openJavaClass, Editor editor) { + PsiMethod @NotNull [] methods = openJavaClass.getMethods(); + int offset = 0; + if (0 == methods.length) { + offset = openJavaClass.getTextRange().getEndOffset() - 3; + } else { + PsiMethod psiMethod = methods[methods.length - 1]; + offset = psiMethod.getTextRange().getEndOffset(); + } + editor.getCaretModel().moveToOffset(offset); + CodeService.writeCode2(project, editor, "\n"); + + } + + + @Override + public void next(Context context, AnActionEvent e) { + super.next(context, e); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/DocumentService.java b/athena-all/src/main/java/run/mone/m78/ip/service/DocumentService.java new file mode 100644 index 000000000..d2e1246e1 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/service/DocumentService.java @@ -0,0 +1,52 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.service; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.diagnostic.Logger; +import org.apache.commons.lang3.tuple.Pair; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/6 12:08 + */ +public class DocumentService { + + private static final Logger log = Logger.getInstance(DocumentService.class); + + /** + * 用ide打开文件 + * + * @param name + * @param text + */ + public void open(String name, String text) { + log.info("open file"); + } + + /** + * 获取文件内容和文件名(content,fileName) + * + * @param anActionEvent + * @return + */ + public Pair getContent(AnActionEvent anActionEvent) { + log.info("get content"); + return null; + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/EditorService.java b/athena-all/src/main/java/run/mone/m78/ip/service/EditorService.java new file mode 100644 index 000000000..84ca1dac1 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/service/EditorService.java @@ -0,0 +1,16 @@ +package run.mone.m78.ip.service; + +import com.intellij.openapi.editor.Editor; + +/** + * @author goodjava@qq.com + * @date 2023/5/19 22:08 + */ +public class EditorService { + + + public static void readOnly(Editor editor, boolean readOnly) { + editor.getDocument().setReadOnly(readOnly); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/ImageService.java b/athena-all/src/main/java/run/mone/m78/ip/service/ImageService.java new file mode 100644 index 000000000..68340dba9 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/service/ImageService.java @@ -0,0 +1,48 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.service; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.diagnostic.Logger; +import run.mone.m78.ip.common.Context; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/6 20:23 + */ +public class ImageService extends AbstractService { + + private static final Logger log = Logger.getInstance(ImageService.class); + + /** + * 使用ide 打开图片 + */ + public void open(String t) { + + } + + + public void openImage(String url) { + + } + + @Override + public void execute(Context context, AnActionEvent e) { + + this.next(context, e); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/LocalAiService.java b/athena-all/src/main/java/run/mone/m78/ip/service/LocalAiService.java new file mode 100644 index 000000000..4a9b83b76 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/service/LocalAiService.java @@ -0,0 +1,139 @@ +package run.mone.m78.ip.service; + +import com.google.common.collect.Lists; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.intellij.openapi.project.Project; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.tuple.Pair; +import run.mone.m78.ip.bo.AiMessage; +import run.mone.m78.ip.bo.chatgpt.*; +import run.mone.m78.ip.common.Const; +import run.mone.m78.ip.util.ResourceUtils; +import run.mone.openai.StreamListener; +import run.mone.ultraman.common.GsonUtils; + +import java.io.File; +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/11/23 13:56 + *

+ * 这个类允许你本地直连chatgpt(如果是国内的网络需要设置open_ai_proxy) + */ +@Slf4j +public class LocalAiService { + + + private static String getOpenAiUrl() { + String url = ResourceUtils.getAthenaConfig().getOrDefault(Const.OPEN_AI_PROXY, ""); + return url; + } + + + /** + * 调用chatgpt的语音翻译(你需要有chatgpt的账号) + * + * @param file + * @return + */ + @SneakyThrows + public static Pair callChatgptTranscriptions(File file) { + return Pair.of(200, ""); + } + + + /** + * 把文字转成语音 + * + * @param req + * @return + */ + @SneakyThrows + public static Pair speech(SpeechReq req) { + return null; + } + + + //多模态调用(支持图片) + public static String vision(VisionReq req) { + return ""; + } + + + public static JsonObject call(List messageList) { + Completions completions = Completions.builder() + .stream(false) + .response_format(Format.builder().build()).messages(messageList).build(); + String req = GsonUtils.gson.toJson(completions); + return call(req); + } + + + public static JsonObject call(String req) { + return call(req, 5000); + } + + //这个会直接调用chatgpt + @SneakyThrows + public static JsonObject call(String req, long timeout) { + return null; + } + + + //直接问问题(直接调用chatgpt) + public static void completions(String req, StreamListener sl) { + } + + + private static String parse(String data) { + log.info(data); + if (data.equals("[DONE]")) { + return ""; + } + return ""; + } + + private static JsonObject parseJson(String data) { + log.info("data:{}", data); + JsonObject obj = GsonUtils.gson.fromJson(data, JsonObject.class); + JsonArray choices = obj.getAsJsonArray("choices"); + return GsonUtils.gson.fromJson(choices.get(0).getAsJsonObject().getAsJsonObject("").get("").getAsString(), JsonObject.class); + } + + //本地直接调用chatgpt,单条提问 + public static void localCall(Project project, String prompt) { + localCall(project, Lists.newArrayList(Message.builder().content(prompt).role("user").build()), false, 0); + } + + + public static void localCall(String projectName, boolean code) { + } + + + public static void localCall(Project project, List messageList, boolean code, int num) { + } + + + public static List getLastElements(List list, int num) { + return null; + } + + private static void chat(Project project, boolean code, List newMessageList, String projectName, String id) { + } + + + //调用ai proxy(进行聊天) + private static void aiProxyChat(Project project, List newMessageList) { + + } + + //每次都只发一部分(发送到右侧 athena) + private static void sendMsg(AiMessage message, String projectName) { + + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/MusicService.java b/athena-all/src/main/java/run/mone/m78/ip/service/MusicService.java new file mode 100644 index 000000000..a36a9ab2f --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/service/MusicService.java @@ -0,0 +1,116 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.service; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.ApplicationManager; +import run.mone.m78.ip.action.ActionEnum; +import run.mone.m78.ip.common.ApiCall; +import run.mone.m78.ip.common.Context; +import run.mone.m78.ip.common.Mp3PlayerV2; +import run.mone.m78.ip.common.NotificationCenter; +import run.mone.m78.ip.common.Safe; +import org.apache.commons.lang.StringUtils; + +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/6 11:46 + */ +public class MusicService extends AbstractService { + + private List list = new ArrayList<>(); + + private int index; + + private String musicUrl; + + public void setList(List list) { + this.list = list; + } + + private static final class LazyHolder { + private static MusicService ins = new MusicService(); + } + + public static MusicService ins() { + return LazyHolder.ins; + } + + private MusicService() { + Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> { + if (StringUtils.isNotEmpty(musicUrl)) { + if (Mp3PlayerV2.ins().isComplete()) { + play(musicUrl); + } + } + }, 0, 1, TimeUnit.SECONDS); + } + + public synchronized void play(String t) { + musicUrl = t; + ApplicationManager.getApplication().invokeLater(() -> { + Safe.run(() -> { + if (StringUtils.startsWith(t, ActionEnum.diga.name() + ":")) { + String url = new ApiCall().callIt(ApiCall.MUSIC_API, t.replaceFirst(ActionEnum.diga.name() + ":", "") + ".mp3"); + InputStream input = new URL(url).openStream(); + Mp3PlayerV2.ins().play(input); + return; + } + String url = new ApiCall().callOne(ApiCall.MUSIC_API); + NotificationCenter.notice("music:" + url); + InputStream input = new URL(url).openStream(); + //这里会启用一个新的线程 + Mp3PlayerV2.ins().play(input); + }); + }); + } + + public void playWithUrl(String url) { + Safe.run(() -> { + InputStream input = new URL(url).openStream(); + Mp3PlayerV2.ins().play(input); + }); + } + + public synchronized void stop() { + this.musicUrl = ""; + Safe.run(() -> Mp3PlayerV2.ins().close()); + } + + @Override + public void execute(Context context, AnActionEvent e) { + String content = context.getContent(); + if (content.equals(ActionEnum.diga.name()) || StringUtils.startsWith(content, ActionEnum.diga.name() + ":")) { + play(content); + return; + } + + if (content.equals(ActionEnum.diga_stop.name())) { + stop(); + return; + } + + this.next(context, e); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/PromptService.java b/athena-all/src/main/java/run/mone/m78/ip/service/PromptService.java new file mode 100644 index 000000000..01befe325 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/service/PromptService.java @@ -0,0 +1,356 @@ +package run.mone.m78.ip.service; + +import com.google.gson.Gson; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMethod; +import run.mone.m78.ip.bo.GenerateCodeReq; +import run.mone.m78.ip.bo.Message; +import run.mone.m78.ip.bo.PromptContext; +import run.mone.m78.ip.bo.RobotContext; +import run.mone.m78.ip.util.HintUtils; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; +import java.util.Map; + +import static run.mone.m78.ip.util.PromptUtils.*; + +/** + * @author goodjava@qq.com + * @author baoyu + * @date 2023/5/11 21:53 + *

+ * 这个类主要处理Prompt在Idea中的落地(写入编辑器) + */ +@Slf4j +public class PromptService { + + private static Gson gson = new Gson(); + + /** + * 动态执行 + * + * @param req + * @return + */ + public static String dynamicInvoke(GenerateCodeReq req) { + setReq(req); + switch (req.getPromptType()) { + case createClass -> createClass(req.getProject(), req.getModule().getName(), req.getPromptName()); + case createClass4 -> createClass4(req); + case createMethod -> createMethod(req); + case createMethod2 -> createMethod2(req); + case comment -> addComment(req); + case lineByLineComment -> lineByLineCommentOrCode(req.getPromptName(), req); + case createFile -> createFile(req.getPromptName(), req.getFileName(), req); + case modifyClass -> updateClass(req); + case modifyMethod -> updateMethod(req); + case select -> select(req, req.getProject(), req.getModule(), req.getPromptInfo()); + case removeComment -> removeComment(req.getProject()); + case showInfo -> showInfo(req); + case repleaceSelectContent -> repleaceSelectContent(req); + case testPrompt -> testPrompt(req); + case checkPomVersion -> checkPomVersion(req); + case generateBootStrapAnno -> generateAnnoForBootStrap(req.getPromptName(), req.getProject()); + case inlayHint -> inlayHint(req); + case genBizMethodCode -> genBizMethodCode(req); + case generateMethod -> generateMethod(req, req.getProject(), ""); + case bot -> RobotService.bot(req); + case generateMiapiMethod -> generateMiapiMethod(req); + case generateInterface -> generateInterface(req); + case question -> question(req); + case createClass2 -> + createClass2(req.getProject(), req.getPromptName(), req.getShowDialog(), req.getParam()); + default -> { + return "UnSupport"; + } + } + return "ok"; + } + + private static void createClass4(GenerateCodeReq req) { + + } + + //ai会向你提问(绝大部分分多步的操作,ai问你更合适) + private static void question(GenerateCodeReq req) { + + } + + //后边代码尽量用这里获取的内容,editor中的内容放入到req中,避免后边的再次获取 + public static void setReq(GenerateCodeReq req) { + + } + + private static String getClassPackage(String qualifiedName) { + int lastDotIndex = qualifiedName.lastIndexOf('.'); + if (lastDotIndex >= 0) { + return qualifiedName.substring(0, lastDotIndex); + } + return ""; + } + + + //获取编辑器的注释信息 + private static String getComment(Editor editor) { + return getComment(editor, "//biz:"); + } + + private static String getComment(Editor editor, String str) { + return ""; + } + + + /** + * 生成业务方法 + * + * @param req + */ + public static void genBizMethodCode(GenerateCodeReq req) { + + } + + private static String addCode(GenerateCodeReq req, Map m, PromptContext context) { + return ""; + } + + + //添加上下文信息到映射中 + private static void addContext(GenerateCodeReq req, Map m, PromptContext promptContext) { + + } + + public static String getResourceFromAi(Project project, Map m, PromptContext promptContext, List resourceCode) { + return ""; + } + + + public static void inlayHint(GenerateCodeReq req) { + + } + + /** + * 测试prompt的接口 + * + * @param req + */ + private static void testPrompt(GenerateCodeReq req) { + + } + + private static void repleaceSelectContent(GenerateCodeReq req) { + + } + + /** + * 在聊天窗口显示信息 + * + * @param req + */ + public static void showInfo(GenerateCodeReq req) { + + } + + + public static void generateMethod(Project project, String content) { + + } + + + //创建方法都收口在这里了 + public static void generateMethod(GenerateCodeReq req) { + + } + + private static void initAiReqMap(GenerateCodeReq req, Map aiReqMap) { + + } + + private static void analysisScope(GenerateCodeReq req, PromptContext context) { + + } + + private static void addField(GenerateCodeReq req, Map map) { + + } + + private static void addClass(GenerateCodeReq req, Map map, PromptContext context) { + + } + + + public static String getCode(GenerateCodeReq req, PromptContext context) { + return ""; + } + + /** + * 删除逐行注释 + * + * @param project + */ + private static void removeComment(Project project) { + PsiMethod psiMethod = CodeService.getMethod(project); + Editor editor = CodeService.getEditor(project); + if (null == psiMethod) { + HintUtils.show(editor, Message.selectMethodMsg, true); + return; + } + PsiMethodUtils.deleteCommentsFromMethod(project, psiMethod, comment -> comment.getText().startsWith("//Athena:")); + } + + + + /** + * 生成方法(在edit中) + * + * @param project + * @param text + */ + public static void generateMethod(GenerateCodeReq req, Project project, String text) { + + } + + + private static void createMethod(GenerateCodeReq req) { + + } + + /** + * stream样式添加注释 + */ + public static void comment2(RobotContext context, GenerateCodeReq req) { + } + + /** + * 给出一些修改代码的意见 + */ + public static void modifyCodeSuggest(RobotContext context, GenerateCodeReq req) { + } + + /** + * 需要导入那些依赖 + * + * @param context + * @param req + */ + public static void getImport(RobotContext context, GenerateCodeReq req) { + req.setPromptName("get_import"); + addComment(req); + } + + + /** + * 根据类生成sql建表文件 + * + * @param context + * @param req + */ + public static void createTabStatement(RobotContext context, GenerateCodeReq req) { + createFile("create_tab_statement", "tmp.sql", req); + } + + /** + * 把class转换为json文件 + * + * @param context + * @param req + */ + public static void classJson(RobotContext context, GenerateCodeReq req) { + createFile("class_json", "tmp.json", req); + } + + + /** + * 根据业务需求直接生成代码 + * + * @param context + * @param req + */ + public static void bizCodeGen(RobotContext context, GenerateCodeReq req) { + } + + + + + /** + * 创建方法2 + *

+ * 会打开两个表单 + * 1.填参数 + * 2.选中类和方法 + * + *

+ * 选择类和方法,然后插入代码 + *

+ * 可以用来生成Controller中的方法 + * + * @param req + */ + public static void createMethod2(GenerateCodeReq req) { + + + } + + public static void addFields(Project project, String serviceName, String shortServiceName, PsiClass psiClass, Editor editor) { + } + + public static void addImports(GenerateCodeReq req, Project project, String serviceName, String reqClass, Editor editor) { + } + + public static void addImports(GenerateCodeReq req, Project project, String serviceName, String reqClass, Editor editor, boolean unitTest, boolean resource, String unitVersion) { + + } + + /** + * 给interface中添加方法(返回值可能被包装要注意) + * + * @param psiClass + */ + private static void addMethodToInterface(GenerateCodeReq req, PsiClass psiClass, PsiMethod pm, PsiClass reqClass) { + + } + + private static void modifyReq(GenerateCodeReq req, PsiMethod pm, String reqClass) { + + } + + private static void setLabels(GenerateCodeReq req, Map map) { + + } + + + /** + * 生成使用中间件的代码 + * + * @param context + * @param req + */ + public static void midCodeGen(RobotContext context, GenerateCodeReq req) { + } + + /** + * 逐行注释 + * + * @param context + * @param req + */ + public static void cc(RobotContext context, GenerateCodeReq req) { + } + + /** + * fix(问题修复,给出来的是建议) + * + * @param context + * @param req + */ + public static void fix(RobotContext context, GenerateCodeReq req) { + } + + //暂时只生成接口引入 + public static void generateMiapiMethod(GenerateCodeReq req) { + + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/ProxyAiService.java b/athena-all/src/main/java/run/mone/m78/ip/service/ProxyAiService.java new file mode 100644 index 000000000..016ebfd93 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/service/ProxyAiService.java @@ -0,0 +1,41 @@ +package run.mone.m78.ip.service; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import run.mone.m78.ip.bo.chatgpt.Message; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/12/5 22:13 + */ +@Slf4j +public class ProxyAiService { + + + private static Gson gson = new Gson(); + + public static JsonObject call(List messageList) { + return call(messageList, 50000); + } + + public static JsonObject call(String r, long time, boolean vip) { + String pa = "jsonStr"; + String req = gson.toJson(pa); + return call0(req, time, vip); + } + + //调用ai proxy (调用的是json接口,返回的数据一定是json格式) + public static JsonObject call0(String req, long time, boolean vip) { + return null; + } + + public static JsonObject call(List messageList, long time) { + String pa = "jsonStr"; + String req = gson.toJson(pa); + return call0(req, time, true); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/PsiMethodUtils.java b/athena-all/src/main/java/run/mone/m78/ip/service/PsiMethodUtils.java new file mode 100644 index 000000000..a82638d23 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/service/PsiMethodUtils.java @@ -0,0 +1,49 @@ +package run.mone.m78.ip.service; + +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.function.Predicate; + +/** + * @author goodjava@qq.com + * @date 2023/6/3 22:31 + */ +public class PsiMethodUtils { + + + /** + * 删除指定方法中的注释 + * + * @param psiMethod + */ + public static void deleteCommentsFromMethod(Project project, PsiMethod psiMethod, Predicate predicate) { + @NotNull Collection comments = PsiTreeUtil.collectElementsOfType(psiMethod, PsiComment.class); + WriteCommandAction.runWriteCommandAction(project, () -> { + for (PsiComment comment : comments) { + if (predicate.test(comment)) { + comment.delete(); + } + } + }); + } + + /** + * 修改方法名 + * + * @param project 项目对象 + * @param document 文档对象 + * @param method 方法对象 + * @param newName 新方法名 + */ + public static void modifyMethodName(Project project, Document document, PsiMethod method, String newName) { + + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/RobotService.java b/athena-all/src/main/java/run/mone/m78/ip/service/RobotService.java new file mode 100644 index 000000000..3c2b0070e --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/service/RobotService.java @@ -0,0 +1,312 @@ +package run.mone.m78.ip.service; + +import com.google.common.collect.ImmutableMap; +import com.google.gson.Gson; +import com.intellij.ide.BrowserUtil; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.Task; +import com.intellij.openapi.ui.Messages; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.mutable.Mutable; +import org.apache.commons.lang.mutable.MutableObject; +import org.jetbrains.annotations.NotNull; +import run.mone.m78.ip.bo.GenerateCodeReq; +import run.mone.m78.ip.bo.RobotContext; +import run.mone.m78.ip.bo.RobotReq; +import run.mone.m78.ip.common.ChromeUtils; +import run.mone.m78.ip.util.*; +import run.mone.ultraman.background.AthenaTask; +import run.mone.ultraman.common.GitProjectOpener; +import run.mone.ultraman.service.AthenaCodeService; + +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author goodjava@qq.com + * @date 2023/4/19 14:21 + *

+ * 所有通过语音过来的请求,都会在这里处理 + */ +@Slf4j +public class RobotService { + + private static Gson gson = new Gson(); + + public static String invoke(String methodName, RobotContext context, RobotReq req) { + try { + Method method = RobotService.class.getMethod(methodName, RobotContext.class, RobotReq.class); + if (null == method) { + return null; + } + Object obj = method.invoke(null, context, req); + if (obj instanceof Void || null == obj) { + return "ok"; + } + return obj.toString(); + } catch (NoSuchMethodException ex) { + return "主人你说的话我不懂"; + } catch (Throwable ex) { + ex.printStackTrace(); + return ex.getMessage(); + } + } + + + public static String openBrowser(RobotContext context, RobotReq req) { + BrowserUtil.browse(req.getParam(), ProjectUtils.projectFromManager()); + return "ok"; + } + + public static String test(String param) { + return "res:" + param; + } + + + public static String test(RobotContext context, RobotReq req) { + return "res:" + req.getParam(); + } + + public static String openClass(RobotContext context, RobotReq req) { + ApplicationManager.getApplication().invokeLater(() -> CodeService.openJavaClass(ProjectUtils.projectFromManager(), req.getParam())); + return "ok"; + } + + public static String openProject(RobotContext context, RobotReq req) { + ApplicationManager.getApplication().invokeLater(() -> { + GitProjectOpener.openGitProject(req.getParam()); + }); + return "ok"; + } + + public static String createPackage(RobotContext context, RobotReq req) { + ApplicationManager.getApplication().invokeLater(() -> { + CodeService.createPackage(ProjectUtils.projectFromManager(), req.getParam()); + }); + return "ok"; + } + + public static String generateMoonHandler(RobotContext context, RobotReq req) { + ApplicationManager.getApplication().invokeLater(() -> { + CodeService.generateMoonHandler(ProjectUtils.projectFromManager()); + }); + return "ok"; + } + + public static void message(RobotContext context, RobotReq req) { + ApplicationManager.getApplication().invokeLater(() -> { + Messages.showMessageDialog(ProjectUtils.projectFromManager(), "mone", req.getParam(), Messages.getInformationIcon()); + }); + } + + public static void consoleMessage(RobotContext context, RobotReq req) { + ApplicationManager.getApplication().invokeLater(() -> { + UltramanConsole.append(req.getParam()); + }); + } + + public static void addMethod(RobotContext context, RobotReq req) { + ApplicationManager.getApplication().invokeLater(() -> CodeService.addMethod(ProjectUtils.projectFromManager(), req.getParam())); + } + + public static void addStatement(RobotContext context, RobotReq req) { + ApplicationManager.getApplication().invokeLater(() -> CodeService.addStatementToMethod(ProjectUtils.projectFromManager(), req.getParam())); + } + + public static void moveLine(RobotContext context, RobotReq req) { + ApplicationManager.getApplication().invokeLater(() -> { + CodeService.moveLine(ProjectUtils.projectFromManager(), Integer.valueOf(req.getParam())); + }); + } + + //关闭当前编辑器 + public static void closeEditor(RobotContext context, RobotReq req) { + ApplicationManager.getApplication().invokeLater(() -> { + CodeService.closeEditor(req.getProject()); + }); + } + + //执行代码 + public static void runClass(RobotContext context, RobotReq req) { + ApplicationManager.getApplication().invokeLater(() -> { + RunUntil.run(req.getProject()); + }); + } + + //滚动屏幕 + public static void scroll(RobotContext context, RobotReq req) { + ApplicationManager.getApplication().invokeLater(() -> { + EditorUtils.scroll(req.getProject()); + }); + } + + public static void getClassByAnno(RobotContext context, RobotReq req) { + ApplicationManager.getApplication().invokeLater(() -> { + CodeService.getClassByServiceAnno(ProjectUtils.projectFromManager(), req.getParam()); + }); + } + + public static void listRecentProjects(RobotContext context, RobotReq req) { + ApplicationManager.getApplication().invokeLater(() -> { + ProjectUtils.recentProjects(); + }); + } + + public static void listAllModules(RobotContext context, RobotReq req) { + ApplicationManager.getApplication().invokeLater(() -> { + ProjectUtils.listAllModules(ProjectUtils.projectFromManager()); + }); + } + + public static void getPackageClass(RobotContext context, RobotReq req) { + ApplicationManager.getApplication().invokeLater(() -> { + CodeService.getClassesInPackage(ProjectUtils.projectFromManager(), req.getParam()); + }); + } + + public static void addComment(RobotContext context, RobotReq req) { + ApplicationManager.getApplication().invokeLater(() -> { + CodeService.getClassesInPackage(ProjectUtils.projectFromManager(), req.getParam()); + }); + } + + public static void removeComments(RobotContext context, RobotReq req) { + ApplicationManager.getApplication().invokeLater(() -> CodeService.removeComments(ProjectUtils.projectFromManager())); + } + + public static void generateMethod(RobotContext context, RobotReq req) { + ApplicationManager.getApplication().invokeLater(() -> CodeService.generateMethod(ProjectUtils.projectFromManager(), req.getParam())); + } + + public static void go(RobotContext context, RobotReq req) { + // 为了适配语音输入的路由 + } + + public static List projects(RobotContext context, RobotReq req) { + return ProjectUtils.listOpenProjects(); + } + + public static List modules(RobotContext context, RobotReq req) { + return ProjectUtils.listAllModules(ProjectUtils.projectFromManager(req.getParam())); + } + + public static String say(RobotContext context, RobotReq req) { + return req.getParam(); + } + + + public static Object formatCode(RobotContext context, RobotReq req) { + Mutable obj = new MutableObject(); + ApplicationManager.getApplication().invokeAndWait(() -> { + CodeService.formatCode(req.getProject()); + obj.setValue("success"); + }); + return obj.getValue(); + } + + public static void deleteLine(RobotContext context, RobotReq req) { + ApplicationManager.getApplication().invokeLater(() -> CodeService.deleteLine(ProjectUtils.projectFromManager(), Integer.valueOf(req.getParam()))); + } + + + public static void terminal(RobotContext context, RobotReq req) { + log.info("terminal:{}", req.getParam()); + ApplicationManager.getApplication().invokeLater(() -> TerminalUtils.send(req.getProject(), req.getParam())); + } + + + //同声翻译 + public static void translate(RobotContext context, RobotReq req) { + ApplicationManager.getApplication().invokeLater(() -> { + Map map = new HashMap<>(); + map.put("code", req.getParam()); + String res = AthenaCodeService.callProxy(req.getProject(), map, "fanyi", 10).value(); + System.out.println(res); + ChromeUtils.call(req.getProject().getName(), res, 0); + } + ); + } + + //官网检索 + public static void web123(RobotContext context, RobotReq req) { + + } + + + //打开某个指定的app + public static void openApp(RobotContext context, RobotReq req) { + try { + Runtime.getRuntime().exec("/usr/bin/open -a " + req.getParam()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + //错误分析 + public static void troubleshoot(RobotContext context, RobotReq req) { + + } + + public static String getTroubleshootType(RobotContext context, RobotReq req) { + return ""; + } + + + public static String getPromptCmd(String cmd) { + return ""; + } + + + /** + * 这里的逻辑先调用chatgpt拿到命令列表,然后调用相应的函数 + * + * @param req + */ + private static void bot0(GenerateCodeReq req) { + + } + + //执行脚本 + public static Object runScript(Map map, String promptCmd) { + return null; + } + + public static Object runScriptMethod(Map map, String methodName) { + return null; + } + + private static Map makeBindMap() { + return ImmutableMap.of( + "log", log, + "gson", gson + ); + } + + private static void setKV(Map map, GenerateCodeReq req) { + + } + + + //支持机器人命令 + public static void bot(GenerateCodeReq req) { + AthenaTask.start(new Task.Backgroundable(req.getProject(), "bot run", true) { + @SneakyThrows + @Override + public void run(@NotNull ProgressIndicator indicator) { + bot0(req); + } + }); + + } + + public static void dynamicCallPrompt(GenerateCodeReq req, String promptName) { + + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/ScriptService.java b/athena-all/src/main/java/run/mone/m78/ip/service/ScriptService.java new file mode 100644 index 000000000..f2a4b4d18 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/service/ScriptService.java @@ -0,0 +1,59 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.service; + +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import java.util.Map; + +/** + * @author goodjava@qq.com + * @date 2021/12/19 + */ +@Slf4j +public class ScriptService { + + private ScriptEngineManager factory = new ScriptEngineManager(ScriptService.class.getClassLoader()); + + private ScriptEngine engine; + + + private ScriptService() { + engine = factory.getEngineByName("groovy"); + } + + @SneakyThrows + public static String getScript(String name) { + return ""; + } + + private static final class LazyHolder { + private static final ScriptService ins = new ScriptService(); + } + + public static ScriptService ins() { + return LazyHolder.ins; + } + + public Object invoke(String script, String functionName, Map bindValues, Object... args) { + return null; + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/SpiderService.java b/athena-all/src/main/java/run/mone/m78/ip/service/SpiderService.java new file mode 100644 index 000000000..3333e3030 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/service/SpiderService.java @@ -0,0 +1,36 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.service; + +import com.google.gson.Gson; +import run.mone.m78.ip.bo.SpiderUrl; + +import java.util.List; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/10 10:47 + */ +public class SpiderService { + + private Gson gson = new Gson(); + + public List list(String name) { + return null; + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/TaskService.java b/athena-all/src/main/java/run/mone/m78/ip/service/TaskService.java new file mode 100644 index 000000000..a105ab331 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/service/TaskService.java @@ -0,0 +1,32 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.service; + +import java.util.List; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/9 14:04 + */ +public class TaskService { + + + public List tasks(String name) { + return null; + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/TestService.java b/athena-all/src/main/java/run/mone/m78/ip/service/TestService.java new file mode 100644 index 000000000..396b2e879 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/service/TestService.java @@ -0,0 +1,37 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.service; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import lombok.extern.slf4j.Slf4j; +import run.mone.m78.ip.common.Context; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/7 21:43 + */ +@Slf4j +public class TestService extends AbstractService { + @Override + public void execute(Context context, AnActionEvent e) { + String content = context.getContent(); + if (content.equals("test")) { + } + this.next(context, e); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/TextService.java b/athena-all/src/main/java/run/mone/m78/ip/service/TextService.java new file mode 100644 index 000000000..b3be6808a --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/service/TextService.java @@ -0,0 +1,56 @@ +package run.mone.m78.ip.service; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; + + +/** + * @author goodjava@qq.com + * @date 2023/5/17 15:46 + */ +@Slf4j +public class TextService { + + + public static void writeContent(Project project, String fileName, String moduleName, Runnable runnable) { + writeContent(project, fileName, moduleName, runnable, null); + } + + + public static String readContent(Project project, String module, String fileName) { + PsiDirectory directory = getPsiDirectory(project, module); + if (null == directory) { + return ""; + } + PsiFile file = directory.findFile(fileName); + if (null == file) { + return ""; + } + return file.getText(); + } + + + public static void writeContent(Project project, String fileName, String moduleName, Runnable runnable, String content) { + + } + + @NotNull + private static String getFileContent(String content) { + String fileContent = " "; + if (StringUtils.isNotEmpty(content)) { + fileContent = content; + } + return fileContent; + } + + + private static PsiDirectory getPsiDirectory(Project project, String moduleName) { + return null; + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/UltramanService.java b/athena-all/src/main/java/run/mone/m78/ip/service/UltramanService.java new file mode 100644 index 000000000..2741f8024 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/service/UltramanService.java @@ -0,0 +1,20 @@ +package run.mone.m78.ip.service; + +import com.intellij.openapi.components.ServiceManager; +import run.mone.m78.ip.client.GrpcClient; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/5 12:38 + */ +public interface UltramanService { + static UltramanService getInstance() { + return ServiceManager.getService(UltramanService.class); + } + + void run(); + + void init(); + + GrpcClient client(); +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/UltramanServiceImpl.java b/athena-all/src/main/java/run/mone/m78/ip/service/UltramanServiceImpl.java new file mode 100644 index 000000000..bd84bb934 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/service/UltramanServiceImpl.java @@ -0,0 +1,42 @@ +package run.mone.m78.ip.service; + +import run.mone.m78.ip.client.GrpcClient; +import lombok.extern.slf4j.Slf4j; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/5 12:38 + */ +@Slf4j +public class UltramanServiceImpl implements UltramanService { + + private GrpcClient grpcClient; + + private boolean openHttpServer = false; + + + public UltramanServiceImpl() { + grpcClient = new GrpcClient(); + } + + + @Override + public void run() { + log.info("athena run"); + } + + @Override + public void init() { + log.info("athena service init"); + + } + + private static void openHttpServer() throws Exception { + + } + + @Override + public GrpcClient client() { + return grpcClient; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/UserService.java b/athena-all/src/main/java/run/mone/m78/ip/service/UserService.java new file mode 100644 index 000000000..bab7d6118 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/service/UserService.java @@ -0,0 +1,52 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.service; + +import com.google.gson.Gson; +import com.intellij.openapi.actionSystem.AnActionEvent; +import run.mone.m78.ip.bo.UserBo; +import run.mone.m78.ip.common.ApiCall; +import run.mone.m78.ip.common.Context; + +import java.util.List; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/6 12:52 + */ +public class UserService extends AbstractService { + + private Gson gson = new Gson(); + + + public List users() { + ApiCall apiCall = new ApiCall(); + return apiCall.call(ApiCall.USER_API); + } + + + public List userBoList() { + return null; + } + + + @Override + public void execute(Context context, AnActionEvent e) { + this.next(context, e); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/XmlService.java b/athena-all/src/main/java/run/mone/m78/ip/service/XmlService.java new file mode 100644 index 000000000..c558a6fec --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/service/XmlService.java @@ -0,0 +1,56 @@ +package run.mone.m78.ip.service; + +import com.intellij.openapi.project.Project; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.maven.model.Model; +import org.apache.maven.model.io.xpp3.MavenXpp3Writer; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Map; + +/** + * @author goodjava@qq.com + * @date 2023/5/21 22:07 + */ +public class XmlService { + + /** + * 方便操纵xml,这里的作用是修改maven 中的 pom 加入依赖 + * + * @param project + * @param moduleName + * @param dependency + */ + public static void openMavenPomAndModify(Project project, String moduleName, String dependency) { + + } + + public static Pair checkPomVersion(Project project, String groupId, String artifactId, String version) { + return null; + } + + @NotNull + private static Pair insertDependency(Project project, String groupId, String artifactId, String version, Map modulePathMap) throws IOException, XmlPullParserException { + return null; + } + + private static Pair writeDependency(Model model, File pomFile) { + return null; + } + + private static String buildDependencyString(String groupId, String artifactId, String version) { + return String.format("```\n" + + "\n" + + " \t%s\n" + + " \t%s\n" + + " \t%s\n" + + "", groupId, artifactId, version); + + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/BuildUi.form b/athena-all/src/main/java/run/mone/m78/ip/ui/BuildUi.form new file mode 100644 index 000000000..d3e5c1ca3 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/BuildUi.form @@ -0,0 +1,279 @@ + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/BuildUi.java b/athena-all/src/main/java/run/mone/m78/ip/ui/BuildUi.java new file mode 100644 index 000000000..f86d2eb85 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/BuildUi.java @@ -0,0 +1,367 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.ui; + +import run.mone.m78.ip.bo.IdeaPluginInfoBo; +import run.mone.m78.ip.bo.PluginDeleteParam; +import run.mone.m78.ip.common.ConfigUtils; +import run.mone.m78.ip.util.XmlUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.mutable.MutableInt; + +import javax.swing.*; +import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * @author goodjava@qq.com + */ +public class BuildUi extends JDialog { + + + private static final String VERSION = "0.0.1:2019-07-17"; + + + private JPanel contentPane; + private JButton buttonOK; + private JButton buttonCancel; + private JTextField projectNameField; + private JTextField pathField; + private JTextArea textArea1; + private JButton pushButton; + private JButton startButton; + private JButton stopButton; + private JButton statusButton; + private JTextField statusField; + private JTextField versionTextField; + private JTextField pluginUrltextField; + private JTextField gatewayServerTextField; + private JTextField pluginIdtextField; + private JTextField mvnPathTextField; + private JComboBox opsServercomboBox; + private JComboBox groupComboBox; + + + private final String projectName; + private final String projectPath; + + + private IdeaPluginInfoBo pluginInfo; + + + public BuildUi(String projectName, String projectPath) { + this.projectName = projectName; + this.projectPath = projectPath; + + + Map m = XmlUtils.getKV(projectPath + File.separator + projectName + "-service" + File.separator + "pom.xml", "manifestEntries"); + + this.versionTextField.setText(m.get("Plugin-Version")); + this.pluginUrltextField.setText(m.get("Plugin-Url")); + this.mvnPathTextField.setText(m.get("Plugin-MvnPath")); + //gateway服务器 + this.gatewayServerTextField.setText(m.get("Plugin-GateWayServer")); + + if (StringUtils.isNotEmpty(this.projectName) && StringUtils.isNotEmpty(this.projectPath)) { + projectNameField.setText(this.projectName); + pathField.setText(this.projectPath); + } + + String localOps = ConfigUtils.getConfig().getOpsLocal(); + String stagingOps = ConfigUtils.getConfig().getOpsStaging(); + + this.opsServercomboBox.addItem(new ComboBoxItme("staging", stagingOps)); + this.opsServercomboBox.addItem(new ComboBoxItme("local", localOps)); + + + String groups = ConfigUtils.getConfig().getGroupList(); + if (StringUtils.isNotEmpty(groups)) { + String[] ss = groups.split(","); + Arrays.stream(ss).forEach(it -> { + groupComboBox.addItem(it); + }); + } else { + groupComboBox.addItem(""); + } + + + setContentPane(contentPane); + setModal(true); + getRootPane().setDefaultButton(buttonOK); + + buttonOK.addActionListener(e -> build()); + + buttonCancel.addActionListener(e -> onCancel()); + + // call onCancel() when cross is clicked + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + onCancel(); + } + }); + + // call onCancel() on ESCAPE + contentPane.registerKeyboardAction(e -> { + //退出 + onCancel(); + }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + + pushButton.addActionListener(e -> { + //推送上去 + push(); + }); + //获取状态 + statusButton.addActionListener(e -> { + //获取状态 + }); + startButton.addActionListener(e -> { + //启动 + start(); + }); + + stopButton.addActionListener(e -> { + //停止 + stop(); + }); + + + this.setSize(this.getWidth() + 1, this.getHeight() + 1); + } + + class ComboBoxItme { + private String type; + private String name; + + public ComboBoxItme(String type, String name) { + this.type = type; + this.name = name; + } + + @Override + public String toString() { + return type + ":" + name; + } + } + + + private String getToken() { + String token = ConfigUtils.getConfig().getToken(); + return token; + } + + + private static final int timeOut = 3000; + + + private int stop() { + + this.stopButton.setEnabled(false); + + new Thread(() -> { + MutableInt status = new MutableInt(-1); + try { + + + PluginDeleteParam pluginDeleteParam = new PluginDeleteParam(); + pluginDeleteParam.setName(projectNameField.getText()); + pluginDeleteParam.setToken(getToken()); + pluginDeleteParam.setUserName(getUserName()); + + + if (!this.groupComboBox.getSelectedItem().toString().equals("")) { + List groupList = new ArrayList<>(); + groupList.add(this.groupComboBox.getSelectedItem().toString()); + pluginDeleteParam.setGroupList(groupList); + } + + pluginDeleteParam.setId(Integer.valueOf(pluginIdtextField.getText())); + + + } catch (Throwable ex) { + ex.printStackTrace(); + SwingUtilities.invokeLater(() -> { + textArea1.setText(""); + textArea1.append("stop:" + ex.getMessage() + "\r\n"); + this.startButton.setEnabled(true); + }); + + } + + SwingUtilities.invokeLater(() -> { + textArea1.setText(""); + textArea1.append("stop:" + status.getValue() + "\r\n"); + this.stopButton.setEnabled(true); + }); + }).start(); + + + return 1; + } + + /** + * 启动插件 + * + * @return + */ + private int start() { + + this.startButton.setEnabled(false); + + new Thread(() -> { + try { + + PluginDeleteParam pluginDeleteParam = new PluginDeleteParam(); + pluginDeleteParam.setToken(getToken()); + pluginDeleteParam.setUserName(getUserName()); + //设置插件名称 + pluginDeleteParam.setName(projectNameField.getText()); + + List addressList = new ArrayList<>(); + pluginDeleteParam.setAddressList(addressList); + + pluginDeleteParam.setId(Integer.valueOf(pluginIdtextField.getText())); + + + if (!this.groupComboBox.getSelectedItem().toString().equals("")) { + List groupList = new ArrayList<>(); + groupList.add(this.groupComboBox.getSelectedItem().toString()); + pluginDeleteParam.setGroupList(groupList); + } + + + } catch (Throwable ex) { + ex.printStackTrace(); + SwingUtilities.invokeLater(() -> { + textArea1.setText(""); + textArea1.append("start:" + ex.getMessage() + "\r\n"); + this.startButton.setEnabled(true); + }); + } + + }).start(); + + + return 1; + } + + + private String getServerAddress() { + ComboBoxItme item = (ComboBoxItme) this.opsServercomboBox.getSelectedItem(); + return item.name; + } + + /** + * 上传jar包 + */ + private void push() { + this.pushButton.setEnabled(false); + new Thread(() -> { + try { + if (pluginIdtextField.getText().equals("-1")) { + } else { + } + + + } catch (Throwable ex) { + ex.printStackTrace(); + SwingUtilities.invokeLater(() -> { + textArea1.setText(ex.getMessage()); + this.pushButton.setEnabled(true); + }); + } + + }).start(); + } + + private String getUserName() { + String name = ConfigUtils.getConfig().getNickName(); + return name; + } + + + //build + private void build() { + + this.buttonOK.setEnabled(false); + + new Thread(() -> { + String cmd = mvnPathTextField.getText().trim() + " clean compile package -Dmaven.test.skip=true -f " + projectPath + File.separator + "pom.xml"; + Runtime run = Runtime.getRuntime(); + try { + Process p = run.exec(cmd); + BufferedInputStream in = new BufferedInputStream(p.getInputStream()); + BufferedReader inBr = new BufferedReader(new InputStreamReader(in)); + String lineStr; + while ((lineStr = inBr.readLine()) != null) { + System.out.println(lineStr); + String l = lineStr; + SwingUtilities.invokeLater(() -> { + textArea1.append(l); + textArea1.append("\r\n"); + }); + + + } + //检查命令是否执行失败。 + if (p.waitFor() != 0) { + if (p.exitValue() == 1) { + SwingUtilities.invokeLater(() -> textArea1.append("build error")); + } + } + + SwingUtilities.invokeLater(() -> { + this.buttonOK.setEnabled(true); + }); + + inBr.close(); + in.close(); + } catch (Exception e) { + e.printStackTrace(); + SwingUtilities.invokeLater(() -> { + this.buttonOK.setEnabled(true); + textArea1.append("build:" + e.getMessage()); + }); + } + + + }).start(); + + + } + + private void onCancel() { + dispose(); + } + + public static void main(String[] args) { + BuildUi dialog = new BuildUi("databank", "/private/tmp/databank"); + dialog.pack(); + dialog.setVisible(true); + System.exit(0); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/ChatUi.form b/athena-all/src/main/java/run/mone/m78/ip/ui/ChatUi.form new file mode 100644 index 000000000..c039b60fd --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/ChatUi.form @@ -0,0 +1,81 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/ChatUi.java b/athena-all/src/main/java/run/mone/m78/ip/ui/ChatUi.java new file mode 100644 index 000000000..a1a5b9723 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/ChatUi.java @@ -0,0 +1,323 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.ui; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.event.DocumentListener; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import run.mone.m78.ip.bo.Response; +import run.mone.m78.ip.bo.UserVo; +import run.mone.m78.ip.common.ConfigUtils; +import run.mone.m78.ip.common.MessageQueue; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import java.awt.event.*; +import java.lang.reflect.InvocationTargetException; +import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.IntStream; + +/** + * @author goodjava@qq.com + */ +public class ChatUi extends JDialog implements WindowListener { + + private boolean open = false; + + private static final Logger logger = Logger.getInstance(ChatUi.class); + + + private JPanel contentPane; + private JTextArea textArea1; + private JTree tree1; + private JTextArea textArea2; + private AnActionEvent event; + + private volatile boolean stop = false; + + public ChatUi(AnActionEvent anActionEvent) { + if (!open) { + return; + } + + this.event = anActionEvent; + setContentPane(contentPane); + setModal(true); + + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + onCancel(); + } + }); + + contentPane.registerKeyboardAction(e -> onCancel(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + + + new Thread(() -> { + while (true) { + final Response res = MessageQueue.ins().poll(); + if (null != res) { + + if (res.getCmd().equals("$exit$")) { + break; + } + + try { + SwingUtilities.invokeAndWait(() -> { + + String cmd = res.getCmd(); + + if (cmd.equals("talk_message")) { + textArea2.append(res.getSenderId() + ":" + res.getData().toString()); + return; + } + + //登陆好友的信息 + if (cmd.equals("login")) { + List list = (List) res.getData(); + list.stream().forEach(u -> { + addUser(u); + }); + return; + } + + if (cmd.equals("logout_msg")) { + String uid = res.getData().toString(); + deleteUser(uid); + return; + } + + //有新用户登陆 + if (cmd.equals("login_user_info")) { + UserVo user = (UserVo) res.getData(); + addUser(user); + return; + } + + }); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + } + logger.info("chat ui stop"); + + }).start(); + + init(); + + this.setSize(this.getWidth() + 1, this.getHeight() + 1); + textArea1.addKeyListener(new KeyAdapter() { + @Override + public void keyReleased(KeyEvent e) { + + if (e.getModifiers() == 2 || e.getKeyCode() == 10) { + sendMessage(); + } + } + }); + } + + /** + * 发送消息 + * + * @return + */ + @NotNull + private void sendMessage() { + //发送消息 + Map m = new HashMap<>(2); + m.put("cmd", "talk"); + String msg = textArea1.getText().trim() + "\r\n"; + m.put("message", msg); + + if (null != tree1.getSelectionPath()) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree1.getSelectionPath().getLastPathComponent(); + UserVo uv = (UserVo) node.getUserObject(); + String id = uv.getId(); + if (!id.equals("YouPin")) { + m.put("receiverId", id); + } + + //变为review代码(只有选中别人的时候可以是这种操作) + if (msg.equals("$review$\r\n") && !id.equals("YouPin") && !id.equals("robot")) { + m.put("cmd", "review"); + Project project = event.getProject(); + PsiFile psiFile = event.getData(LangDataKeys.PSI_FILE); + if (null == psiFile) { + return; + } + Document document = PsiDocumentManager.getInstance(project).getDocument(psiFile); + m.put("data", document.getText()); + m.put("name", psiFile.getName()); + + final String _id = id; + final String _name = psiFile.getName(); + + //添加事件(修改就会触发) + document.addDocumentListener(new DocumentListener() { + @Override + public void documentChanged(@NotNull DocumentEvent event) { + Map m = new HashMap<>(); + m.put("cmd", "review"); + m.put("data", event.getDocument().getText()); + m.put("name", _name); + m.put("receiverId", _id); + MessageQueue.ins().send(m); + } + }); + } + + } + MessageQueue.ins().send(m); + textArea1.setText(""); + } + + + private void init() { + if (StringUtils.isNotEmpty(ConfigUtils.getConfig().getNickName())) { + Map msg = new HashMap<>(2); + msg.put("cmd", "login"); + msg.put("id", ConfigUtils.getConfig().getNickName()); + msg.put("name", ConfigUtils.getConfig().getNickName()); + MessageQueue.ins().send(msg); + System.out.println("init finish"); + } else { + this.textArea1.setText("请先设置昵称"); + } + } + + + /** + * 添加用户 + * + * @param user + */ + private void addUser(UserVo user) { + DefaultTreeModel model = (DefaultTreeModel) tree1.getModel(); + DefaultMutableTreeNode root = (DefaultMutableTreeNode) tree1.getModel() + .getRoot(); + DefaultMutableTreeNode child = new DefaultMutableTreeNode(user); + model.insertNodeInto(child, root, root.getChildCount()); + } + + + /** + * 移除用户 + * + * @param uid + */ + private void deleteUser(String uid) { + DefaultMutableTreeNode top = (DefaultMutableTreeNode) tree1.getModel() + .getRoot(); + Optional op = IntStream.range(0, top.getChildCount()).mapToObj(i -> (DefaultMutableTreeNode) top.getChildAt(i)).filter(it -> { + UserVo vo = (UserVo) it.getUserObject(); + return vo.getId().equals(uid); + } + + ).findAny(); + + if (op.isPresent()) { + top.remove(op.get()); + this.tree1.updateUI(); + } + } + + + private void onCancel() { + this.stop = true; + dispose(); + } + + + + public static void main(String[] args) throws URISyntaxException { + +// client = new WsClient(); +// client.init(new URI("ws://127.0.0.1:8089/ws"), (msg) -> { +// System.out.println("-------------->" + msg); +// }); +// client.connect(); +// + ChatUi dialog = new ChatUi(null); + dialog.pack(); + dialog.setVisible(true); + System.exit(0); + } + + private void createUIComponents() { + tree1 = new JTree(); + DefaultMutableTreeNode top = new DefaultMutableTreeNode(new UserVo("YouPin", "YouPIn")); + DefaultMutableTreeNode dp = new DefaultMutableTreeNode(new UserVo("robot", "robot")); + top.add(dp); + + DefaultTreeModel treeModel = new DefaultTreeModel(top); + this.tree1.setModel(treeModel); + } + + @Override + public void windowOpened(WindowEvent e) { + + } + + @Override + public void windowClosing(WindowEvent e) { + Response res = new Response<>(0, "", "", "$exit$"); + MessageQueue.ins().offer(res); + } + + @Override + public void windowClosed(WindowEvent e) { + + } + + @Override + public void windowIconified(WindowEvent e) { + + } + + @Override + public void windowDeiconified(WindowEvent e) { + } + + @Override + public void windowActivated(WindowEvent e) { + + } + + @Override + public void windowDeactivated(WindowEvent e) { + + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/CodeGeneratorUi.form b/athena-all/src/main/java/run/mone/m78/ip/ui/CodeGeneratorUi.form new file mode 100644 index 000000000..bbec0e6b1 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/CodeGeneratorUi.form @@ -0,0 +1,171 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/CodeGeneratorUi.java b/athena-all/src/main/java/run/mone/m78/ip/ui/CodeGeneratorUi.java new file mode 100644 index 000000000..377e5c8c4 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/CodeGeneratorUi.java @@ -0,0 +1,255 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.ui; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import run.mone.m78.ip.generator.ClassGenerator; +import run.mone.m78.ip.generator.DirectoryGenerator; +import run.mone.m78.ip.generator.FileGenerator; +import run.mone.m78.ip.generator.PomGenerator; +import org.apache.commons.lang3.StringUtils; + +import javax.swing.*; +import java.awt.event.*; +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +public class CodeGeneratorUi extends JDialog { + private JPanel contentPane; + private JButton buttonOK; + private JButton buttonCancel; + + private JTextField projectPathField; + private JTextField urlField; + private JTextField projectNameField; + private JTextField groupIdField; + private JTextField packageField; + private JTextField versionField; + private JTextField authorField; + private JLabel projectField; + + private Project project; + + public CodeGeneratorUi(Project project) { + this.project = project; + setContentPane(contentPane); + setModal(true); + getRootPane().setDefaultButton(buttonOK); + + buttonOK.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + onOK(); + } + }); + + buttonCancel.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + onCancel(); + } + }); + + // call onCancel() when cross is clicked + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + onCancel(); + } + }); + + // call onCancel() on ESCAPE + contentPane.registerKeyboardAction(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + onCancel(); + } + }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + + this.setSize(this.getWidth()+1,this.getHeight()+1); + } + + private void onOK() { + + String projectPath = projectPathField.getText().trim(); + String projectName = projectNameField.getText().trim(); + String srcPath = "/src/main/java/"; + String groupId = groupIdField.getText().trim(); + String packageName = packageField.getText().trim(); + String author = authorField.getText().trim(); + String versionId = versionField.getText().trim(); + String url = urlField.getText().trim(); + + String packagePath = packageName.replaceAll("\\.", "/"); + + //创建项目 + DirectoryGenerator directoryGenerator = new DirectoryGenerator(projectPath, projectName, ""); + directoryGenerator.generator(); + + //创建module + DirectoryGenerator apiModule = new DirectoryGenerator(projectPath, projectName, projectName + "-api" + + File.separator + srcPath); + apiModule.generator(); + + generateApiPom(projectPath, projectName, groupId, versionId); + + + DirectoryGenerator commonModule = new DirectoryGenerator(projectPath, projectName, projectName + "-common" + + File.separator + srcPath + ); + commonModule.generator(); + + generateCommonPom(projectPath, projectName, groupId, versionId); + + + String serviceSrcPath = projectName + "-service" + File.separator + srcPath; + String serviceFullSrcPath = serviceSrcPath + File.separator + packagePath; + +// generateDubboService(author, projectPath, projectName, packageName); + + + DirectoryGenerator serviceModule = new DirectoryGenerator(projectPath, projectName, serviceFullSrcPath); + serviceModule.generator(); + + generateServicePom(projectPath, projectName, groupId, author, versionId, url); + + generageParentPom(projectPath, projectName, groupId, versionId); + generageGitignore(projectPath, projectName); + + //生成入口类 + generateHandler(projectPath, projectName, packageName, author, url, packagePath, serviceSrcPath); + + //生成plugin handler 配置文件 + generateExtensions(projectPath, projectName, packageName); + + if (null != project) { + Messages.showMessageDialog(project, "Success", "Generate Success", null); + } + + } + + private void generageGitignore(String projectPath, String projectName) { + FileGenerator mdGenerator = new FileGenerator(projectPath, projectName, ".gitignore", "springboot_gitignore.tml"); + mdGenerator.generator(new HashMap<>()); + } + + private void generateExtensions(String projectPath, String projectName, String handlerPkg) { + //生成文件夹 + DirectoryGenerator directoryGenerator = new DirectoryGenerator(projectPath, projectName, projectName + "-service/src/main/resources/META-INF"); + directoryGenerator.generator(); + + //生成文件 + FileGenerator fileGenerator = new FileGenerator(projectPath, projectName, projectName + "-service/src/main/resources/META-INF/extensions.idx", "extensions.tml"); + Map m = new HashMap<>(2); + m.put("package", handlerPkg); + m.put("project", StringUtils.capitalize(projectName)); + fileGenerator.generator(m); + } + + private void generateHandler(String projectPath, String projectName, String packageName, String author, String url, String packagePath, String serviceSrcPath) { + ClassGenerator classGenerator = new ClassGenerator(projectPath, projectName, serviceSrcPath, packagePath, StringUtils.capitalize(projectName) + "Handler", "handler_class.tml"); + Map m = new HashMap<>(4); + m.put("package", packageName); + m.put("author", author); + m.put("url", url); + m.put("project", StringUtils.capitalize(projectName)); + classGenerator.generator(m); + } + + + private void generateDubboService(String author, String projectPath, String projectName, String packageName, String packagePath, String serviceSrcPath) { + ClassGenerator classGenerator = new ClassGenerator(projectPath, projectName, serviceSrcPath, packagePath, StringUtils.capitalize(projectName) + "Service", "dubbo_service_class.tml"); + Map m = new HashMap<>(3); + m.put("package", packageName); + m.put("project", StringUtils.capitalize(projectName)); + m.put("author", author); + classGenerator.generator(m); + } + + + private void generateApiPom(String projectPath, String projectName, String groupId, String versionId) { + //生成api module 下的pom文件 + PomGenerator apiPomGenerator = new PomGenerator(projectPath, projectName + File.separator + projectName + "-api", "pom_api.tml"); + Map ampom = new HashMap<>(); + ampom.put("groupId", groupId); + ampom.put("parent_artifactId", projectName); + ampom.put("artifactId", projectName + "-api"); + ampom.put("version", versionId + "-SNAPSHOT"); + ampom.put("plugin_id", projectName); + ampom.put("version_id", versionId); + apiPomGenerator.generator(ampom); + } + + private void generateCommonPom(String projectPath, String projectName, String groupId, String versionId) { + //生成api module 下的pom文件 + PomGenerator commonPomGenerator = new PomGenerator(projectPath, projectName + File.separator + projectName + "-common", "pom_common.tml"); + Map cmpom = new HashMap<>(); + cmpom.put("groupId", groupId); + cmpom.put("parent_artifactId", projectName); + cmpom.put("artifactId", projectName + "-common"); + cmpom.put("version", versionId + "-SNAPSHOT"); + commonPomGenerator.generator(cmpom); + } + + private void generageParentPom(String projectPath, String projectName, String groupId, String versionId) { + //生成主项目的pom文件 + PomGenerator pomGenerator = new PomGenerator(projectPath, projectName, "pom.tml"); + Map mpom = new HashMap<>(); + mpom.put("groupId", groupId); + mpom.put("artifactId", projectName); + mpom.put("version", versionId + "-SNAPSHOT"); + mpom.put("api_module", projectName + "-api"); + mpom.put("common_module", projectName + "-common"); + mpom.put("service_module", projectName + "-service"); + pomGenerator.generator(mpom); + } + + private void generateServicePom(String projectPath, String projectName, String groupId, String author, String versionId, + String url + + ) { + //生成service module 下的pom文件 + PomGenerator servicePomGenerator = new PomGenerator(projectPath, projectName + File.separator + projectName + "-service", "pom_service.tml"); + Map smpom = new HashMap<>(); + smpom.put("groupId", groupId); + smpom.put("parent_artifactId", projectName); + smpom.put("artifactId", projectName + "-service"); + smpom.put("version", versionId + "-SNAPSHOT"); + smpom.put("plugin_id", projectName); + smpom.put("version_id", versionId); + smpom.put("author", author); + smpom.put("plugin", projectName); + smpom.put("plugin_url", url); + servicePomGenerator.generator(smpom); + } + + private void onCancel() { + dispose(); + } + + public static void main(String[] args) { + CodeGeneratorUi dialog = new CodeGeneratorUi(null); + dialog.pack(); + // 设置对话框大小是否可改变 + dialog.setResizable(true); + dialog.setSize(500, 400); + dialog.setVisible(true); + System.exit(0); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/ConfigUi.form b/athena-all/src/main/java/run/mone/m78/ip/ui/ConfigUi.form new file mode 100644 index 000000000..cd7d4e7c6 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/ConfigUi.form @@ -0,0 +1,151 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/ConfigUi.java b/athena-all/src/main/java/run/mone/m78/ip/ui/ConfigUi.java new file mode 100644 index 000000000..3a2f27b43 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/ConfigUi.java @@ -0,0 +1,172 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.ui; + +import run.mone.m78.ip.bo.ZAddrRes; +import run.mone.m78.ip.common.Prompt; +import run.mone.m78.ip.bo.TeslaPluginConfig; +import run.mone.m78.ip.common.ConfigUtils; +import lombok.Getter; +import org.apache.commons.lang3.mutable.MutableBoolean; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.event.*; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + *

+ * 保存配置 + */ +public class ConfigUi extends JDialog { + + private JPanel contentPane; + private JTextField dashServerTextField; + private JTextField nickNameTextField; + private JPasswordField zTokenPassword; + + @Getter + private JTextField aiProxyTextField; + + @Getter + private JComboBox modelComboBox; + private JButton refreshButton; + + + private MutableBoolean modified; + + public ConfigUi(MutableBoolean modified) { + this.modified = modified; + setContentPane(contentPane); + setModal(true); + + + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + onCancel(); + } + }); + + contentPane.registerKeyboardAction(e -> onCancel(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + + addListener(); + + init(); + + this.setSize(this.getWidth() + 1, this.getHeight() + 1); + } + + private void addListener() { + dashServerTextField.getDocument().addDocumentListener(listener); + nickNameTextField.getDocument().addDocumentListener(listener); + this.zTokenPassword.getDocument().addDocumentListener(listener); + this.aiProxyTextField.getDocument().addDocumentListener(listener); + this.modelComboBox.addItemListener(itemEvent -> modified.setTrue()); + this.refreshButton.addActionListener(actionEvent -> { + ZAddrRes res = Prompt.zAddrRes(); + this.dashServerTextField.setText(res.getAthenaDashServer().trim()); + List list = res.getModels().stream().map(it -> it.getValue()).collect(Collectors.toList()); + ComboBoxModel model = new DefaultComboBoxModel<>(list.toArray(String[]::new)); + this.modelComboBox.setModel(model); + if (list.size() > 0) { + this.modelComboBox.setSelectedItem(list.get(0)); + } + modified.setTrue(); + }); + } + + + private DocumentListener listener = new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + modified.setTrue(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + modified.setTrue(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + modified.setTrue(); + } + }; + + + private void init() { + try { + TeslaPluginConfig config = ConfigUtils.getConfig(); + this.dashServerTextField.setText(config.getDashServer()); + this.nickNameTextField.setText(config.getNickName()); + this.zTokenPassword.setText(config.getzToken()); + this.aiProxyTextField.setText(config.getAiProxy()); + + List list = config.getModelList(); + String model = config.getModel(); + if (null != list && null != model) { + this.modelComboBox.setModel(new DefaultComboBoxModel(list.toArray(String[]::new))); + this.modelComboBox.setSelectedItem(model); + } + + } catch (Exception ignore) { + + } + } + + + private void onCancel() { + dispose(); + } + + @Override + public JPanel getContentPane() { + return contentPane; + } + + + public MutableBoolean getModified() { + return modified; + } + + + public JTextField getDashServerTextField() { + return dashServerTextField; + } + + public void setDashServerTextField(JTextField dashServerTextField) { + this.dashServerTextField = dashServerTextField; + } + + public JTextField getNickNameTextField() { + return nickNameTextField; + } + + public JPasswordField getzTokenPassword() { + return zTokenPassword; + } + + public void setzTokenPassword(JPasswordField zTokenPassword) { + this.zTokenPassword = zTokenPassword; + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/CreateClassUi.form b/athena-all/src/main/java/run/mone/m78/ip/ui/CreateClassUi.form new file mode 100644 index 000000000..a0f99da4f --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/CreateClassUi.form @@ -0,0 +1,135 @@ + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/CreateClassUi.java b/athena-all/src/main/java/run/mone/m78/ip/ui/CreateClassUi.java new file mode 100644 index 000000000..96a901e5c --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/CreateClassUi.java @@ -0,0 +1,96 @@ +package run.mone.m78.ip.ui; + +import com.google.common.collect.Lists; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import run.mone.m78.ip.bo.CreateClassRes; +import run.mone.m78.ip.util.PsiClassUtils; +import run.mone.m78.ip.util.ScreenSizeUtils; +import lombok.Getter; +import org.apache.commons.lang3.StringUtils; + +import javax.swing.*; +import java.awt.event.*; +import java.util.List; + +public class CreateClassUi extends JDialog { + private JPanel contentPane; + private JButton buttonOK; + private JComboBox comboBox1; + private JTextField textField1; + private JTextField textField2; + private JRadioButton buildRadioButton; + private JRadioButton dataRadioButton; + private JButton buttonCancel; + private Project project; + + @Getter + private CreateClassRes res = new CreateClassRes(); + + + public CreateClassUi(Project project, List moduleList, String currentModule, String packageStr) { + this.project = project; + setContentPane(contentPane); + setModal(true); + getRootPane().setDefaultButton(buttonOK); + + buttonOK.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + onOK(); + } + }); + + ComboBoxModel model = new DefaultComboBoxModel<>(moduleList.toArray(String[]::new)); + this.comboBox1.setModel(model); + if (StringUtils.isNotEmpty(currentModule)) { + this.comboBox1.setSelectedItem(currentModule); + } + + + // call onCancel() when cross is clicked + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + onCancel(); + } + }); + + // call onCancel() on ESCAPE + contentPane.registerKeyboardAction(new ActionListener() { + public void actionPerformed(ActionEvent e) { + onCancel(); + } + }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + + this.textField1.setText(packageStr); + + //控制大小 + this.setSize(ScreenSizeUtils.size()); + //居中显示 + this.setLocationRelativeTo(null); + } + + private void onOK() { + String module = this.comboBox1.getSelectedItem().toString(); + String packageName = this.textField1.getText().trim(); + String className = this.textField2.getText().trim(); + res.setModuleName(module); + res.setPackageStr(packageName); + res.setClassName(className); + res.setCode(DialogWrapper.OK_EXIT_CODE); + PsiClassUtils.createEmptyClass(project, module, packageName, className, false, false, null, false); + dispose(); + } + + private void onCancel() { + res.setCode(DialogWrapper.CANCEL_EXIT_CODE); + dispose(); + } + + public static void main(String[] args) { + CreateClassUi dialog = new CreateClassUi(null, Lists.newArrayList("a", "b"), "b", ""); + dialog.pack(); + dialog.setVisible(true); + System.exit(0); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/FilterUi.form b/athena-all/src/main/java/run/mone/m78/ip/ui/FilterUi.form new file mode 100644 index 000000000..e15e3e649 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/FilterUi.form @@ -0,0 +1,259 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/FilterUi.java b/athena-all/src/main/java/run/mone/m78/ip/ui/FilterUi.java new file mode 100644 index 000000000..665493066 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/FilterUi.java @@ -0,0 +1,196 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.ui; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import run.mone.m78.ip.generator.ClassGenerator; +import run.mone.m78.ip.generator.DirectoryGenerator; +import run.mone.m78.ip.generator.FileGenerator; +import run.mone.m78.ip.generator.PomGenerator; +import org.apache.commons.lang3.StringUtils; + +import javax.swing.*; +import java.awt.event.*; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +public class FilterUi extends JDialog { + private JPanel contentPane; + private JButton buttonOK; + private JButton buttonCancel; + + private JTextField projectPathField; + private JTextField projectNameField; + private JTextField groupIdField; + private JTextField packageField; + private JTextField filterOrderField; + private JTextField authorField; + private JTextField versionField; + private JTextField descField; + private JTextField gitAddressField; + private JTextField paramsField; + private JTextField cnameField; + private JTextField isSystemField; + + private Project project; + + public FilterUi(Project project) { + this.project = project; + setContentPane(contentPane); + setModal(true); + getRootPane().setDefaultButton(buttonOK); + + buttonOK.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + onOK(); + } + }); + + buttonCancel.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + onCancel(); + } + }); + + // call onCancel() when cross is clicked + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + onCancel(); + } + }); + + // call onCancel() on ESCAPE + contentPane.registerKeyboardAction(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + onCancel(); + } + }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + + this.setSize(this.getWidth()+1,this.getHeight()+1); + } + + private void onOK() { + + String projectPath = projectPathField.getText().trim(); + String projectName = projectNameField.getText().trim(); + String srcPath = "/src/main/java/"; + String groupId = groupIdField.getText().trim(); + String packageName = packageField.getText().trim(); + String author = authorField.getText().trim(); + if (!author.endsWith("@abc.com")) { + author = author + "@abc.com"; + } + String versionId = versionField.getText().trim(); + String filterOrder = filterOrderField.getText().trim(); + String desc = descField.getText().trim(); + String gitAddress = gitAddressField.getText().trim(); + String params = paramsField.getText().trim(); + String cname = cnameField.getText().trim(); + String isSystem = isSystemField.getText().trim(); + + String packagePath = packageName.replaceAll("\\.", "/"); + + //创建项目 + DirectoryGenerator directoryGenerator = new DirectoryGenerator(projectPath, projectName, "src/main/java/" + packagePath + "/filter"); + directoryGenerator.generator(); + + generageParentPom(projectPath, projectName, groupId, versionId); + generageGitignore(projectPath, projectName); + + //生成入口类 + generateFilter(projectPath, projectName, packageName, author, packagePath + "/filter", "src/main/java", filterOrder); + + //生成配置文件 + generateExtensions(projectPath, projectName, versionId, desc, author, packageName, gitAddress, params, cname, isSystem); + + if (null != project) { + Messages.showMessageDialog(project, "Success", "Generate Success", null); + } + + } + + private void generateExtensions(String projectPath, String projectName, String version, String desc, String author, String packageName, String gitAddress, String params, String cname, String system) { + if (!system.equals("0") && !system.equals("1")) { + system = "0"; + } + + //生成文件夹 + DirectoryGenerator directoryGenerator = new DirectoryGenerator(projectPath, projectName, "src/main/resources"); + directoryGenerator.generator(); + + //生成文件 + FileGenerator fileGenerator = new FileGenerator(projectPath, projectName, "src/main/resources/FilterDef", "filter_def.tml"); + Map m = new HashMap<>(9); + m.put("name", projectName); + m.put("filter", packageName + ".filter." + StringUtils.capitalize(projectName)); + m.put("date", new SimpleDateFormat("YYYY-MM-dd").format(new Date())); + m.put("version", version); + m.put("desc", desc); + m.put("author", author); + m.put("gitAddress", gitAddress); + m.put("params", params); + m.put("cname", cname); + m.put("system", system); + fileGenerator.generator(m); + } + + private void generateFilter(String projectPath, String projectName, String packageName, String author, String packagePath, String serviceSrcPath, String filterOrder) { + ClassGenerator classGenerator = new ClassGenerator(projectPath, projectName, serviceSrcPath, packagePath, StringUtils.capitalize(projectName), "filter_class.tml"); + Map m = new HashMap<>(4); + m.put("package", packageName + ".filter"); + m.put("author", author); + m.put("filterOrder", filterOrder); + m.put("project", StringUtils.capitalize(projectName)); + classGenerator.generator(m); + } + + private void generageParentPom(String projectPath, String projectName, String groupId, String versionId) { + //生成主项目的pom文件 + PomGenerator pomGenerator = new PomGenerator(projectPath, projectName, "filter_pom.tml"); + Map mpom = new HashMap<>(); + mpom.put("groupId", groupId); + mpom.put("artifactId", projectName); + mpom.put("version", versionId + "-SNAPSHOT"); + pomGenerator.generator(mpom); + } + + private void generageGitignore(String projectPath, String projectName) { + FileGenerator mdGenerator = new FileGenerator(projectPath, projectName, ".gitignore", "springboot_gitignore.tml"); + mdGenerator.generator(new HashMap<>()); + } + + private void onCancel() { + dispose(); + } + + public static void main(String[] args) { + FilterUi dialog = new FilterUi(null); + dialog.pack(); + // 设置对话框大小是否可改变 + dialog.setResizable(true); + dialog.setSize(800, 800); + dialog.setVisible(true); + System.exit(0); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/NaviUi.form b/athena-all/src/main/java/run/mone/m78/ip/ui/NaviUi.form new file mode 100644 index 000000000..1dd308bb3 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/NaviUi.form @@ -0,0 +1,144 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/NaviUi.java b/athena-all/src/main/java/run/mone/m78/ip/ui/NaviUi.java new file mode 100644 index 000000000..cd0e53ebd --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/NaviUi.java @@ -0,0 +1,166 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.ui; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.IntStream; + +public class NaviUi extends JDialog { + private JPanel contentPane; + private JButton buttonOK; + private JButton buttonCancel; + private JButton button1; + private JButton button2; + private JButton button3; + private JButton button4; + private JButton button5; + private JButton button6; + private JButton button7; + private JButton button8; + private JButton button9; + private JButton button10; + private JButton button11; + private JButton button12; + private JButton button13; + private JButton button14; + + + class DataButton { + public JButton button; + public String url; + + public DataButton(JButton button) { + this.button = button; + } + } + + + private List buttons = new ArrayList<>(); + + public NaviUi() { + setContentPane(contentPane); + setModal(true); + getRootPane().setDefaultButton(buttonOK); + + + // call onCancel() when cross is clicked + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + onCancel(); + } + }); + + // call onCancel() on ESCAPE + contentPane.registerKeyboardAction(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + onCancel(); + } + }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + + + this.buttons.add(new DataButton(button1)); + this.buttons.add(new DataButton(button2)); + this.buttons.add(new DataButton(button3)); + this.buttons.add(new DataButton(button4)); + this.buttons.add(new DataButton(button5)); + this.buttons.add(new DataButton(button6)); + this.buttons.add(new DataButton(button7)); + this.buttons.add(new DataButton(button8)); + this.buttons.add(new DataButton(button9)); + this.buttons.add(new DataButton(button10)); + this.buttons.add(new DataButton(button11)); + this.buttons.add(new DataButton(button12)); + this.buttons.add(new DataButton(button13)); + this.buttons.add(new DataButton(button14)); + + init(); + + this.setSize(this.getWidth()+1,this.getHeight()+1); + + } + + private void go(String url) { + boolean isSupported = Desktop.isDesktopSupported() + && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE); + System.out.println(isSupported); + if (isSupported) { + try { + Desktop.getDesktop().browse(new java.net.URI(url)); + } catch (IOException ex) { + ex.printStackTrace(); + } catch (URISyntaxException ex) { + ex.printStackTrace(); + } + } + } + + + private void init() { + String content = ""; + List array = new Gson().fromJson(content, new TypeToken>() { + }.getType()); + + + IntStream.range(0, 12).parallel().forEach(it -> { + buttons.get(it).button.setText(array.get(it).get("name").toString()); + SwingUtilities.invokeLater(() -> { + try { + String imgSrc = array.get(it).get("img").toString(); +// ImageIcon icon = new ImageIcon(new URL(imgSrc), "abc"); +// icon.setImage(icon.getImage().getScaledInstance(40, 40, Image.SCALE_DEFAULT)); +// buttons.get(it).button.setIcon(icon); + buttons.get(it).button.addActionListener((e) -> { + Map m = (Map) ((List) array.get(it).get("urls")).get(0); + go(m.get("url").toString()); + }); + buttons.get(it).button.setSize(1, 40); +// buttons.get(it).button.setVerticalTextPosition(SwingConstants.BOTTOM); +// buttons.get(it).button.setHorizontalTextPosition(SwingConstants.CENTER); + } catch (Exception ex) { + ex.printStackTrace(); + } + }); + + + }); + } + + + private void onCancel() { + dispose(); + } + + public static void main(String[] args) { + NaviUi dialog = new NaviUi(); + dialog.pack(); + dialog.setVisible(true); + System.exit(0); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/SelectUi.form b/athena-all/src/main/java/run/mone/m78/ip/ui/SelectUi.form new file mode 100644 index 000000000..88be74103 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/SelectUi.form @@ -0,0 +1,38 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/SelectUi.java b/athena-all/src/main/java/run/mone/m78/ip/ui/SelectUi.java new file mode 100644 index 000000000..a07ff7e60 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/SelectUi.java @@ -0,0 +1,61 @@ +package run.mone.m78.ip.ui; + +import com.intellij.openapi.ui.Messages; +import run.mone.m78.ip.util.ProjectUtils; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.List; + +public class SelectUi extends JDialog { + private JPanel contentPane; + private JButton buttonOK; + private JList list1; + + private DefaultListModel listModel = new DefaultListModel<>(); + + + public SelectUi(List list) { + setContentPane(contentPane); + setModal(true); + getRootPane().setDefaultButton(buttonOK); + list.forEach(it->{ + listModel.addElement(it); + }); + list1.setModel(listModel); + list1.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2) { + int selectedIndex = list1.locationToIndex(e.getPoint()); + String selectedItem = list1.getModel().getElementAt(selectedIndex).toString(); + dispose(); + Messages.showMessageDialog(ProjectUtils.projectFromManager(), "mone", selectedItem, Messages.getInformationIcon()); + } + } + }); + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + + // 计算对话框大小 + int width = screenSize.width / 3; + int height = screenSize.height / 3; + + // 设置对话框大小 + setSize(width, height); + + // 将对话框定位在屏幕中央 + setLocationRelativeTo(null); + + + } + + public static void main(String[] args) { + SelectUi dialog = new SelectUi(new ArrayList<>()); + dialog.pack(); + dialog.setVisible(true); + System.exit(0); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/SpringBootProGenerator.form b/athena-all/src/main/java/run/mone/m78/ip/ui/SpringBootProGenerator.form new file mode 100644 index 000000000..aeb5e2e35 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/SpringBootProGenerator.form @@ -0,0 +1,155 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/SpringBootProGenerator.java b/athena-all/src/main/java/run/mone/m78/ip/ui/SpringBootProGenerator.java new file mode 100644 index 000000000..d464e2d8a --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/SpringBootProGenerator.java @@ -0,0 +1,395 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.ui; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import org.apache.commons.lang3.StringUtils; +import run.mone.m78.ip.common.ColorEggUtils; +import run.mone.m78.ip.common.FileUtils; +import run.mone.m78.ip.generator.ClassGenerator; +import run.mone.m78.ip.generator.DirectoryGenerator; +import run.mone.m78.ip.generator.FileGenerator; +import run.mone.m78.ip.generator.PomGenerator; + +import javax.swing.*; +import java.awt.event.*; +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +public class SpringBootProGenerator extends JDialog { + private JPanel contentPane; + private JButton buttonOK; + private JButton buttonCancel; + + private JTextField projectPathField; + private JTextField projectNameField; + private JTextField groupIdField; + private JTextField packageField; + private JTextField versionField; + private JTextField authorField; + + private Project project; + + public SpringBootProGenerator(Project project) { + this.project = project; + setContentPane(contentPane); + setModal(true); + getRootPane().setDefaultButton(buttonOK); + + buttonOK.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + onOK(); + } + }); + + buttonCancel.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + onCancel(); + } + }); + + // call onCancel() when cross is clicked + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + onCancel(); + } + }); + + // call onCancel() on ESCAPE + contentPane.registerKeyboardAction(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + onCancel(); + } + }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + + this.setSize(this.getWidth()+1,this.getHeight()+1); + } + + private void onOK() { + + String projectPath = projectPathField.getText().trim(); + String projectName = projectNameField.getText().trim(); + String srcPath = "/src/main/java/"; + String testPath = "/src/test/java/"; + String deployPath = "/deploy/manifests"; + String groupId = groupIdField.getText().trim(); + String packageName = packageField.getText().trim(); + String author = authorField.getText().trim(); + String versionId = versionField.getText().trim(); + String catAppdatas = "/data/appdatas/cat"; + String catApplogs = "/data/applogs/cat"; + + String packagePath = packageName.replaceAll("\\.", "/"); + + //创建项目 + DirectoryGenerator directoryGenerator = new DirectoryGenerator(projectPath, projectName, ""); + directoryGenerator.generator(); + generageParentPom(projectPath, projectName, groupId, versionId); + generageReadMe(projectPath, projectName); + generageGitignore(projectPath, projectName); + + //创建module: api + DirectoryGenerator apiModule = new DirectoryGenerator(projectPath, projectName, projectName + "-api" + + File.separator + srcPath + File.separator + packagePath + File.separator + "api" + File.separator + "service"); + apiModule.generator(); + generateApiPom(projectPath, projectName, groupId, versionId); + generateDubboApi(projectPath, projectName, packageName, packagePath + File.separator + "api" + File.separator + "service", projectName + "-api" + File.separator + srcPath); + DirectoryGenerator apiTest = new DirectoryGenerator(projectPath, projectName, projectName + "-api" + + File.separator + testPath + File.separator + packagePath + File.separator + "test"); + apiTest.generator(); + + //创建module: common + DirectoryGenerator commonModule = new DirectoryGenerator(projectPath, projectName, projectName + "-common" + + File.separator + srcPath + ); + commonModule.generator(); + generateCommonPom(projectPath, projectName, groupId, versionId); + DirectoryGenerator commonTest = new DirectoryGenerator(projectPath, projectName, projectName + "-common" + + File.separator + testPath); + commonTest.generator(); + + //创建module: service + DirectoryGenerator serviceModule = new DirectoryGenerator(projectPath, projectName, projectName + "-service" + + File.separator + srcPath + File.separator + packagePath); + serviceModule.generator(); + generateServicePom(projectPath, projectName, groupId, author, versionId); + DirectoryGenerator serviceTest = new DirectoryGenerator(projectPath, projectName, projectName + "-service" + + File.separator + testPath + File.separator + packagePath); + serviceTest.generator(); + + //创建module: server + DirectoryGenerator serverModule = new DirectoryGenerator(projectPath, projectName, projectName + "-server" + + File.separator + srcPath + File.separator + packagePath + File.separator + "bootstrap"); + serverModule.generator(); + DirectoryGenerator serverModule1 = new DirectoryGenerator(projectPath, projectName, projectName + "-server" + + File.separator + srcPath + File.separator + packagePath + File.separator + "service"); + serverModule1.generator(); + DirectoryGenerator serverModule2 = new DirectoryGenerator(projectPath, projectName, projectName + "-server" + + File.separator + srcPath + File.separator + packagePath + File.separator + "config"); + serverModule2.generator(); + generateServerPom(projectPath, projectName, groupId, author, versionId); + DirectoryGenerator serverTest = new DirectoryGenerator(projectPath, projectName, projectName + "-server" + + File.separator + testPath + File.separator + packagePath); + serverTest.generator(); + //生成入口类 + generateBootstrap(projectPath, projectName, packageName, author, packagePath + File.separator + "bootstrap", projectName + "-server" + File.separator + srcPath); + //生成配置文件 + generateResources(projectPath, projectName); + generateLogback(projectPath, projectName); + //生成dubbo相关 + generateDubboProperties(projectPath, projectName); + generateDubboConfig(projectPath, projectName, packageName, packagePath + File.separator + "config", projectName + "-server" + File.separator + srcPath); + generateDubboApiImp(projectPath, projectName, packageName,packagePath + File.separator + "service", projectName + "-server" + File.separator + srcPath); + //生成nacos相关 + generateNacosConfig(projectPath, projectName, packageName, packagePath + File.separator + "config", projectName + "-server" + File.separator + srcPath); + //生成编译部署相关 + generateBuild(projectPath, projectName, versionId); + DirectoryGenerator deploy = new DirectoryGenerator(projectPath, projectName, projectName + "-server" + + File.separator + deployPath); + deploy.generator(); + generateDeploy(projectPath, projectName, versionId, deployPath); + //生成cat监控相关 + generateCatProperties(projectPath, projectName); + FileUtils.createDirectories(catAppdatas); + FileUtils.createDirectories(catApplogs); + String template = FileUtils.getTemplate("springboot_cat_client.tml"); + String str = FileUtils.renderTemplate(template, new HashMap<>()); + FileUtils.writeFile(catAppdatas + File.separator + "client.xml", str); + + colorEgg(projectPath, projectName, testPath, packagePath); + + if (null != project) { + Messages.showMessageDialog(project, "Success", "Generate Success", null); + } + + } + + private void generateResources(String projectPath, String projectName) { + //生成文件夹 + DirectoryGenerator directoryGenerator = new DirectoryGenerator(projectPath, projectName, projectName + "-server/src/main/resources/config"); + directoryGenerator.generator(); + + //生成文件 + FileGenerator fileGenerator = new FileGenerator(projectPath, projectName, projectName + "-server/src/main/resources/application.properties", "springboot_application_properties.tml"); + FileGenerator devGenerator = new FileGenerator(projectPath, projectName, projectName + "-server/src/main/resources/config/dev.properties", "springboot_application_properties_dev.tml"); + FileGenerator stagingGenerator = new FileGenerator(projectPath, projectName, projectName + "-server/src/main/resources/config/staging.properties", "springboot_application_properties_st.tml"); + FileGenerator c3Generator = new FileGenerator(projectPath, projectName, projectName + "-server/src/main/resources/config/c3.properties", "springboot_application_properties_c3.tml"); + FileGenerator c4Generator = new FileGenerator(projectPath, projectName, projectName + "-server/src/main/resources/config/c4.properties", "springboot_application_properties_c4.tml"); + FileGenerator previewGenerator = new FileGenerator(projectPath, projectName, projectName + "-server/src/main/resources/config/preview.properties", "springboot_application_properties_preview.tml"); + + Map m = new HashMap<>(1); + m.put("appName", projectName); + fileGenerator.generator(m); + devGenerator.generator(m); + stagingGenerator.generator(m); + c3Generator.generator(m); + c4Generator.generator(m); + previewGenerator.generator(m); + } + + private void generateLogback(String projectPath, String projectName) { + //生成文件夹 + DirectoryGenerator directoryGenerator = new DirectoryGenerator(projectPath, projectName, projectName + "-server/src/main/resources"); + directoryGenerator.generator(); + + //生成文件 + FileGenerator fileGenerator = new FileGenerator(projectPath, projectName, projectName + "-server/src/main/resources/logback.xml", "springboot_logback.tml"); + Map m = new HashMap<>(1); + m.put("project", projectName); + fileGenerator.generator(m); + } + + private void generateCatProperties(String projectPath, String projectName) { + //生成文件夹 + DirectoryGenerator directoryGenerator = new DirectoryGenerator(projectPath, projectName, projectName + "-server/src/main/resources/META-INF"); + directoryGenerator.generator(); + + //生成文件 + FileGenerator fileGenerator = new FileGenerator(projectPath, projectName, projectName + "-server/src/main/resources/META-INF/app.properties", "springboot_cat_properties.tml"); + Map m = new HashMap<>(1); + m.put("appName", projectName); + fileGenerator.generator(m); + } + + private void generateDubboProperties(String projectPath, String projectName) { + //生成文件夹 + DirectoryGenerator directoryGenerator = new DirectoryGenerator(projectPath, projectName, projectName + "-server/src/main/resources"); + directoryGenerator.generator(); + + //生成文件 + FileGenerator fileGenerator = new FileGenerator(projectPath, projectName, projectName + "-server/src/main/resources/dubbo.properties", "springboot_dubbo_properties.tml"); + Map m = new HashMap<>(1); + m.put("project", projectName); + fileGenerator.generator(m); + } + + private void generateBootstrap(String projectPath, String projectName, String packageName, String author, String packagePath, String serviceSrcPath) { + ClassGenerator classGenerator = new ClassGenerator(projectPath, projectName, serviceSrcPath, packagePath, StringUtils.capitalize(projectName) + "Bootstrap", "springboot_bootstrap_class.tml"); + Map m = new HashMap<>(3); + m.put("package", packageName); + m.put("author", author); + m.put("project", StringUtils.capitalize(projectName)); + classGenerator.generator(m); + } + + private void generateDubboApiImp(String projectPath, String projectName, String packageName, String packagePath, String serviceSrcPath) { + ClassGenerator classGenerator = new ClassGenerator(projectPath, projectName, serviceSrcPath, packagePath, "DubboTestServiceImpl", "springboot_dubbo_api_imp_class.tml"); + Map m = new HashMap<>(1); + m.put("package", packageName); + classGenerator.generator(m); + } + + private void generateDubboApi(String projectPath, String projectName, String packageName, String packagePath, String serviceSrcPath) { + ClassGenerator classGenerator = new ClassGenerator(projectPath, projectName, serviceSrcPath, packagePath, "DubboTestService", "springboot_dubbo_api_class.tml"); + Map m = new HashMap<>(2); + m.put("package", packageName); + m.put("project", projectName); + classGenerator.generator(m); + } + + private void generateDubboConfig(String projectPath, String projectName, String packageName, String packagePath, String serviceSrcPath) { + ClassGenerator classGenerator = new ClassGenerator(projectPath, projectName, serviceSrcPath, packagePath, "DubboConfiguration", "springboot_dubbo_config.tml"); + Map m = new HashMap<>(2); + m.put("package", packageName); + m.put("project", StringUtils.capitalize(projectName)); + classGenerator.generator(m); + } + + private void generateNacosConfig(String projectPath, String projectName, String packageName, String packagePath, String serviceSrcPath) { + ClassGenerator classGenerator = new ClassGenerator(projectPath, projectName, serviceSrcPath, packagePath, "NacosConfiguration", "springboot_nacos_config.tml"); + Map m = new HashMap<>(1); + m.put("package", packageName); + classGenerator.generator(m); + } + + private void generateApiPom(String projectPath, String projectName, String groupId, String versionId) { + //生成api module 下的pom文件 + PomGenerator apiPomGenerator = new PomGenerator(projectPath, projectName + File.separator + projectName + "-api", "springboot_pom_api.tml"); + Map ampom = new HashMap<>(); + ampom.put("groupId", groupId); + ampom.put("parent_artifactId", projectName); + ampom.put("artifactId", projectName + "-api"); + ampom.put("version", versionId + "-SNAPSHOT"); + ampom.put("version_id", versionId); + apiPomGenerator.generator(ampom); + } + + private void generateCommonPom(String projectPath, String projectName, String groupId, String versionId) { + //生成api module 下的pom文件 + PomGenerator commonPomGenerator = new PomGenerator(projectPath, projectName + File.separator + projectName + "-common", "springboot_pom_common.tml"); + Map cmpom = new HashMap<>(); + cmpom.put("groupId", groupId); + cmpom.put("parent_artifactId", projectName); + cmpom.put("artifactId", projectName + "-common"); + cmpom.put("version", versionId + "-SNAPSHOT"); + commonPomGenerator.generator(cmpom); + } + + private void generageParentPom(String projectPath, String projectName, String groupId, String versionId) { + //生成主项目的pom文件 + PomGenerator pomGenerator = new PomGenerator(projectPath, projectName, "springboot_pom.tml"); + Map mpom = new HashMap<>(); + mpom.put("groupId", groupId); + mpom.put("artifactId", projectName); + mpom.put("version", versionId + "-SNAPSHOT"); + mpom.put("api_module", projectName + "-api"); + mpom.put("common_module", projectName + "-common"); + mpom.put("service_module", projectName + "-service"); + mpom.put("server_module", projectName + "-server"); + pomGenerator.generator(mpom); + } + + private void generageReadMe(String projectPath, String projectName) { + FileGenerator mdGenerator = new FileGenerator(projectPath, projectName, "README.md", "springboot_readme.tml"); + mdGenerator.generator(new HashMap<>()); + } + + private void generageGitignore(String projectPath, String projectName) { + FileGenerator mdGenerator = new FileGenerator(projectPath, projectName, ".gitignore", "springboot_gitignore.tml"); + mdGenerator.generator(new HashMap<>()); + } + + private void generateServicePom(String projectPath, String projectName, String groupId, String author, String versionId) { + //生成service module 下的pom文件 + PomGenerator servicePomGenerator = new PomGenerator(projectPath, projectName + File.separator + projectName + "-service", "springboot_pom_service.tml"); + Map smpom = new HashMap<>(); + smpom.put("groupId", groupId); + smpom.put("parent_artifactId", projectName); + smpom.put("artifactId", projectName + "-service"); + smpom.put("version", versionId + "-SNAPSHOT"); + smpom.put("version_id", versionId); + smpom.put("author", author); + smpom.put("api_artifactId", projectName + "-api"); + smpom.put("common_artifactId", projectName + "-common"); + servicePomGenerator.generator(smpom); + } + + private void generateServerPom(String projectPath, String projectName, String groupId, String author, String versionId) { + //生成service module 下的pom文件 + PomGenerator servicePomGenerator = new PomGenerator(projectPath, projectName + File.separator + projectName + "-server", "springboot_pom_server.tml"); + Map smpom = new HashMap<>(); + smpom.put("groupId", groupId); + smpom.put("parent_artifactId", projectName); + smpom.put("artifactId", projectName + "-server"); + smpom.put("version", versionId + "-SNAPSHOT"); + smpom.put("bootstrap", StringUtils.capitalize(projectName) + "Bootstrap"); + smpom.put("service_artifactId", projectName + "-service"); + servicePomGenerator.generator(smpom); + } + + private void generateBuild(String projectPath, String projectName, String versionId) { + FileGenerator buildGenerator = new FileGenerator(projectPath, projectName + File.separator + projectName + "-server", "build.sh", "springboot_build.tml"); + Map smpom = new HashMap<>(); + smpom.put("project", projectName); + smpom.put("version", versionId + "-SNAPSHOT"); + buildGenerator.generator(smpom); + } + + private void generateDeploy(String projectPath, String projectName, String versionId, String deployPath) { + FileGenerator deployGenerator = new FileGenerator(projectPath, projectName + File.separator + projectName + "-server" + File.separator + deployPath, "config.pp.template", "springboot_deploy.tml"); + Map smpom = new HashMap<>(); + smpom.put("project", projectName); + smpom.put("version", versionId + "-SNAPSHOT"); + deployGenerator.generator(smpom); + } + + private void colorEgg(String projectPath, String projectName, String testPath, String packagePath) { + String data = ""; + + String str = ColorEggUtils.parseByte2HexStr(ColorEggUtils.encrypt(data, "xiaomiYP")); + + + FileGenerator mdGenerator = new FileGenerator(projectPath, projectName, projectName + "-api" + + File.separator + testPath + File.separator + packagePath + File.separator + "test" + File.separator + ".des", "springboot_color_egg.tml"); + Map smpom = new HashMap<>(); + smpom.put("data", str); + mdGenerator.generator(smpom); + } + + + private void onCancel() { + dispose(); + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/TaskCreateUi.form b/athena-all/src/main/java/run/mone/m78/ip/ui/TaskCreateUi.form new file mode 100644 index 000000000..f2e836a88 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/TaskCreateUi.form @@ -0,0 +1,86 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/TaskCreateUi.java b/athena-all/src/main/java/run/mone/m78/ip/ui/TaskCreateUi.java new file mode 100644 index 000000000..c70f457ad --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/TaskCreateUi.java @@ -0,0 +1,89 @@ +package run.mone.m78.ip.ui; + +import com.google.gson.Gson; +import run.mone.m78.ip.bo.UserBo; +import run.mone.m78.ip.common.ApiCall; +import run.mone.m78.ip.common.ConfigUtils; +import run.mone.m78.ip.service.UserService; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.HashMap; +import java.util.Map; + +/** + * @author goodjava@qq.com + */ +public class TaskCreateUi extends JDialog { + + private JPanel contentPane; + private JButton buttonOK; + private JButton buttonCancel; + private JTextArea contentTextArea; + private JComboBox comboBox1; + + private Gson gson = new Gson(); + + public TaskCreateUi() { + setContentPane(contentPane); + setModal(true); + getRootPane().setDefaultButton(buttonOK); + + buttonOK.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + ApiCall call = new ApiCall(); + Map m = new HashMap<>(); + m.put("cmd", "createTask"); + m.put("user", ConfigUtils.user()); + m.put("content", contentTextArea.getText()); + UserBo ub = (UserBo) comboBox1.getSelectedItem(); + m.put("executorName", ub.getEmail().split("@")[0]); + call.postCall(ApiCall.TASK_API, new Gson().toJson(m), 3000); + onCancel(); + } + }); + + UserService us = new UserService(); + us.userBoList().forEach(it -> { + this.comboBox1.addItem(it); + }); + + + // call onCancel() when cross is clicked + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + onCancel(); + } + }); + + // call onCancel() on ESCAPE + contentPane.registerKeyboardAction(new ActionListener() { + public void actionPerformed(ActionEvent e) { + onCancel(); + } + }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + } + + private void onOK() { + // add your code here + dispose(); + } + + private void onCancel() { + // add your code here if necessary + dispose(); + } + + public static void main(String[] args) { + TaskCreateUi dialog = new TaskCreateUi(); + dialog.pack(); + dialog.setVisible(true); + System.exit(0); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/TestUi.form b/athena-all/src/main/java/run/mone/m78/ip/ui/TestUi.form new file mode 100644 index 000000000..19237e4c8 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/TestUi.form @@ -0,0 +1,80 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/TestUi.java b/athena-all/src/main/java/run/mone/m78/ip/ui/TestUi.java new file mode 100644 index 000000000..29998009a --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/TestUi.java @@ -0,0 +1,207 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.ui; + + +import javax.swing.*; +import javax.swing.text.BadLocationException; +import javax.swing.text.Style; +import javax.swing.text.StyleConstants; +import javax.swing.text.StyledDocument; +import java.awt.*; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.event.*; +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; + +public class TestUi extends JDialog { + private JPanel contentPane; + private JButton buttonOK; + private JButton buttonCancel; + private JTextPane textPane1; + private JButton button1; + + public TestUi() { + setContentPane(contentPane); + setModal(true); + getRootPane().setDefaultButton(buttonOK); + + buttonOK.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + onOK(); + } + }); + + buttonCancel.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + onCancel(); + } + }); + + // call onCancel() when cross is clicked + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + onCancel(); + } + }); + + // call onCancel() on ESCAPE + contentPane.registerKeyboardAction(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + onCancel(); + } + }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + + + init(); + button1.addActionListener(e -> { + JFileChooser jfc = new JFileChooser(); + jfc.setFileSelectionMode(JFileChooser.FILES_ONLY); + jfc.showDialog(new JLabel(), "选择"); + File file = jfc.getSelectedFile(); + if (file.isDirectory()) { + System.out.println("文件夹:" + file.getAbsolutePath()); + } else if (file.isFile()) { + System.out.println("文件:" + file.getAbsolutePath()); + } + System.out.println(jfc.getSelectedFile().getName()); + URL url = uploadFile(bucketName, jfc.getSelectedFile()); + setClipboardString(url.toString()); + }); + } + + + public static void setClipboardString(String text) { + // 获取系统剪贴板 + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + // 封装文本内容 + Transferable trans = new StringSelection(text); + // 把文本内容设置到系统剪贴板 + clipboard.setContents(trans, null); + } + + + /** + * 从剪贴板中获取文本(粘贴) + */ + public static String getClipboardString() { + // 获取系统剪贴板 + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + + // 获取剪贴板中的内容 + Transferable trans = clipboard.getContents(null); + + if (trans != null) { + // 判断剪贴板中的内容是否支持文本 + if (trans.isDataFlavorSupported(DataFlavor.stringFlavor)) { + try { + // 获取剪贴板中的文本内容 + String text = (String) trans.getTransferData(DataFlavor.stringFlavor); + return text; + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + return null; + } + + + private void init() { + JTextPane textPane = textPane1; + textPane.setMaximumSize(new Dimension(100, 100)); + StyledDocument doc = (StyledDocument) textPane.getDocument(); + + Style style = doc.addStyle("StyleName", null); + try { + StyleConstants.setIcon(style, scaledImage("https://static.runoob.com/images/demo/demo1.jpg")); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + + try { + doc.insertString(doc.getLength(), "", style); + } catch (BadLocationException e) { + e.printStackTrace(); + } + + System.out.println(textPane1.getText()); + } + + + private ImageIcon scaledImage(String location) throws MalformedURLException { + Image image = Toolkit.getDefaultToolkit().getImage(new URL(location)); + image = image.getScaledInstance(120, 120, Image.SCALE_SMOOTH); + return new ImageIcon(image); + } + + private void onOK() { + + System.out.println(textPane1.getText()); +// fileMeta(); + +// getUrl(key); +// uploadFile(bucketName,new File("/Users/zhangzhiyong/Desktop/girl2.jpeg")); + listFile(); + } + + + String endpoint = "oss-cn-beijing.aliyuncs.com"; + String accessKeyId = ""; + String accessKeySecret = ""; + String bucketName = "datazzy"; + String key = "girl.jpeg"; + + public URL getUrl(String key) { + return null; + } + + + public void listFile() { + } + + + public URL uploadFile(String bucketName, File file) { + return null; + } + + + private void fileMeta() { + } + + + private void onCancel() { + // add your code here if necessary + dispose(); + } + + public static void main(String[] args) { + TestUi dialog = new TestUi(); + dialog.pack(); + dialog.setVisible(true); + System.exit(0); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanConsoleUi.form b/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanConsoleUi.form new file mode 100644 index 000000000..8e9b94cee --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanConsoleUi.form @@ -0,0 +1,26 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanConsoleUi.java b/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanConsoleUi.java new file mode 100644 index 000000000..fb405668c --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanConsoleUi.java @@ -0,0 +1,109 @@ +package run.mone.m78.ip.ui; + +import com.intellij.openapi.ui.popup.JBPopup; +import com.intellij.openapi.ui.popup.PopupChooserBuilder; +import com.intellij.ui.awt.RelativePoint; +import com.intellij.ui.components.JBList; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +public class UltramanConsoleUi extends JDialog { + private JPanel contentPane; + private JTextArea textArea1; + private JScrollPane jScrollPane; + private JButton buttonOK; + private JButton buttonCancel; + + public UltramanConsoleUi() { + setContentPane(contentPane); + setModal(true); + getRootPane().setDefaultButton(buttonOK); + + // call onCancel() when cross is clicked + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + onCancel(); + } + }); + + + // call onCancel() on ESCAPE + contentPane.registerKeyboardAction(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + onCancel(); + } + }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + + textArea1.setEditable(false); + textArea1.addMouseListener(new MouseAdapter() { + @Override + public void mouseEntered(MouseEvent mouseEvent) { + textArea1.setCursor(new Cursor(Cursor.TEXT_CURSOR)); //鼠标进入Text区后变为文本输入指针 + } + + @Override + public void mouseExited(MouseEvent mouseEvent) { + textArea1.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); //鼠标离开Text区后恢复默认形态 + } + }); + + textArea1.getCaret().addChangeListener(e -> textArea1.getCaret().setVisible(true)); + + + textArea1.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent mouseEvent) { + if (mouseEvent.getButton() == 3) { + JBList list = new JBList<>(); + String[] title = new String[2]; + title[0] = " Select All"; + title[1] = " Clear All"; + list.setListData(title); + JBPopup popup = new PopupChooserBuilder(list) + .setItemChoosenCallback(() -> { + String value = list.getSelectedValue(); + if (" Clear All".equals(value)) { + textArea1.setText(""); + } else if (" Select All".equals(value)) { + textArea1.selectAll(); + } + }).createPopup(); + Dimension dimension = popup.getContent().getPreferredSize(); + popup.setSize(new Dimension(150, dimension.height)); + popup.show(new RelativePoint(mouseEvent)); + } + } + }); + + + + } + + + private void onCancel() { + dispose(); + } + + public static void main(String[] args) { + UltramanConsoleUi dialog = new UltramanConsoleUi(); + dialog.pack(); + dialog.setVisible(true); + System.exit(0); + } + + + public JPanel jpanel() { + return this.contentPane; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanTreeUi.form b/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanTreeUi.form new file mode 100644 index 000000000..8aad5a470 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanTreeUi.form @@ -0,0 +1,56 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanTreeUi.java b/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanTreeUi.java new file mode 100644 index 000000000..73e5bb301 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanTreeUi.java @@ -0,0 +1,112 @@ +package run.mone.m78.ip.ui; + +import com.google.gson.Gson; +import com.intellij.openapi.project.Project; +import run.mone.m78.ip.bo.TbTask; +import run.mone.m78.ip.common.ApiCall; +import run.mone.m78.ip.common.ConfigUtils; +import run.mone.m78.ip.listener.TreeMouseClickedListener; +import run.mone.m78.ip.listener.UltrmanTreeKeyAdapter; +import run.mone.m78.ip.util.ScreenSizeUtils; +import run.mone.ultraman.AthenaContext; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.HashMap; +import java.util.Map; + +public class UltramanTreeUi extends JDialog { + + private JPanel contentPane; + private JTree tree1; + private JTextField textField1 = new JTextField(); + private JScrollPane scrollPane; + private JPanel webPannel; + private JPanel treePannel; + + private Project project; + + + private Gson gson = new Gson(); + + public UltramanTreeUi(Project project) { + this.project = project; + setContentPane(contentPane); + setModal(true); + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + onCancel(); + } + }); + tree1.setModel(new DefaultTreeModel(null)); + tree1.setRootVisible(false); + + final JPopupMenu popupMenu = new JPopupMenu(); + JMenuItem item = new JMenuItem("done"); + popupMenu.add(item); + + item.addActionListener(e -> { + //完成任务 + TreePath path = tree1.getSelectionPath(); + DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); + TbTask task = (TbTask) node.getUserObject(); + ApiCall call = new ApiCall(); + Map m = new HashMap<>(); + m.put("user", ConfigUtils.user()); + m.put("cmd", "closeTask"); + m.put("taskId", task.getTaskId()); + String res = call.postCall(ApiCall.TASK_API, gson.toJson(m), 3000); + System.out.println("done:" + res); + DefaultTreeModel dt = (DefaultTreeModel) tree1.getModel(); + dt.removeNodeFromParent(node); + } + ); + + JMenuItem item1 = new JMenuItem("new"); + popupMenu.add(item1); + + item1.addActionListener(e -> { + TaskCreateUi ui = new TaskCreateUi(); + ui.setSize(ScreenSizeUtils.size()); + ui.setLocationRelativeTo(null); + ui.setVisible(true); + ui.setResizable(false); + ui.requestFocus(); + }); + + tree1.addMouseListener(new TreeMouseClickedListener(tree1, textField1, popupMenu)); + UltrmanTreeKeyAdapter adapter = new UltrmanTreeKeyAdapter(this.project, textField1, tree1, this.webPannel, this.treePannel); + AthenaContext.ins().setAthenaTreeKeyAdapter(adapter); + textField1.addKeyListener(adapter); + this.webPannel.setVisible(false); + textField1.setText("mone"); + String apiUrl = ConfigUtils.getConfig().getDashServer(); + adapter.loadMone(apiUrl, "mone"); + } + + + public static void main(String[] args) { + UltramanTreeUi dialog = new UltramanTreeUi(null); + dialog.pack(); + dialog.setVisible(true); + System.exit(0); + } + + public JPanel jpanel() { + return this.contentPane; + } + + private void onCancel() { + dispose(); + } + + public JPanel webPannel() { + return this.webPannel; + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanUi.form b/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanUi.form new file mode 100644 index 000000000..42d80ecbf --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanUi.form @@ -0,0 +1,99 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanUi.java b/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanUi.java new file mode 100644 index 000000000..cf20e17b7 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanUi.java @@ -0,0 +1,68 @@ +package run.mone.m78.ip.ui; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +public class UltramanUi extends JDialog { + + private JPanel contentPane; + private JButton buttonOK; + + private JPanel panel1; + private JLabel imageLabel; + private JLabel descLabel; + + + public UltramanUi() { + setContentPane(contentPane); + setModal(true); + getRootPane().setDefaultButton(buttonOK); + + buttonOK.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + onOK(); + } + }); + + // call onCancel() when cross is clicked + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + onOK(); + } + }); + + // call onCancel() on ESCAPE + contentPane.registerKeyboardAction(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + onOK(); + } + }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + + + ImageIcon img = new ImageIcon("/tmp/a.jpeg"); + imageLabel.setIcon(img); + imageLabel.setText(""); + this.descLabel.setText("就算化成灰,我的bug也不会放过你;所以,请相信你自己,然后,也请给我发红包"); + + } + + private void onOK() { + // add your code here + dispose(); + } + + public static void main(String[] args) { + UltramanUi dialog = new UltramanUi(); + dialog.pack(); + dialog.setVisible(true); + System.exit(0); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/VersionUi.form b/athena-all/src/main/java/run/mone/m78/ip/ui/VersionUi.form new file mode 100644 index 000000000..fb591a721 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/VersionUi.form @@ -0,0 +1,41 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/VersionUi.java b/athena-all/src/main/java/run/mone/m78/ip/ui/VersionUi.java new file mode 100644 index 000000000..2ca8886e7 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/ui/VersionUi.java @@ -0,0 +1,79 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.ui; + +import run.mone.m78.ip.util.ScreenSizeUtils; + +import javax.swing.*; +import java.awt.event.*; + +/** + * @author goodjava@qq.com + */ +public class VersionUi extends JDialog { + private JPanel contentPane; + private JTextArea ta; + + public VersionUi() { + setContentPane(contentPane); + setModal(true); + + + // call onCancel() when cross is clicked + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + onCancel(); + } + }); + + // call onCancel() on ESCAPE + contentPane.registerKeyboardAction(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + onCancel(); + } + }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + ta.addKeyListener(new KeyAdapter() { + @Override + public void keyReleased(KeyEvent e) { + if (e.getModifiers() == 2 && e.getKeyCode() == 10) { + } + } + }); + + //控制大小 + this.setSize(ScreenSizeUtils.size()); + //居中显示 + this.setLocationRelativeTo(null); + } + + private void onOK() { + dispose(); + } + + private void onCancel() { + dispose(); + } + + public static void main(String[] args) { + VersionUi dialog = new VersionUi(); + dialog.pack(); + dialog.setVisible(true); + System.exit(0); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/AnnoUtils.java b/athena-all/src/main/java/run/mone/m78/ip/util/AnnoUtils.java new file mode 100644 index 000000000..3344bee48 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/util/AnnoUtils.java @@ -0,0 +1,57 @@ +package run.mone.m78.ip.util; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.psi.JavaPsiFacade; +import com.intellij.psi.PsiClass; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.searches.AnnotatedElementsSearch; +import run.mone.m78.ip.bo.ClassInfo; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/4/25 18:01 + */ +public class AnnoUtils { + + + /** + * Multiple names can be passed at once, separated by commas. + * + * @param project + * @param name + * @return + */ + public static List findClassWithAnno(Project project, String name, String moduleName) { + List result = new ArrayList<>(); + // 获取 JavaPsiFacade 实例 + JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project); + GlobalSearchScope scope = StringUtils.isNotEmpty(moduleName) ? GlobalSearchScope.moduleScope(ProjectUtils.getModuleWithName(project, moduleName)) : GlobalSearchScope.projectScope(project); + // Find the specified annotation using JavaPsiFacade. + + String[] names = new String[]{name}; + if (name.contains(",")) { + names = name.split(","); + } + @NotNull GlobalSearchScope annoScope = GlobalSearchScope.allScope(project); + Arrays.stream(names).forEach(it -> { + PsiClass annotationClass = javaPsiFacade.findClass(it, annoScope); + if (annotationClass != null && annotationClass.isAnnotationType()) { + AnnotatedElementsSearch.searchPsiClasses(annotationClass, scope).forEach(psiClass -> { + Module module = PsiClassUtils.getModule(project, psiClass); + ClassInfo classInfo = ClassInfo.builder().className(psiClass.getQualifiedName()).moduleName(module.getName()).build(); + result.add(classInfo); + }); + } + }); + return result; + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/EditorUtils.java b/athena-all/src/main/java/run/mone/m78/ip/util/EditorUtils.java new file mode 100644 index 000000000..99a4c6896 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/util/EditorUtils.java @@ -0,0 +1,149 @@ +package run.mone.m78.ip.util; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.editor.SelectionModel; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.search.FilenameIndex; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.testFramework.LightVirtualFile; +import run.mone.m78.ip.common.Const; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; + +/** + * @author goodjava@qq.com + * @date 2023/4/18 00:13 + */ +public class EditorUtils { + + public static void scroll(Project project) { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + editor.getScrollingModel().scrollToCaret(ScrollType.CENTER_DOWN); // 翻到下一页 + } + + public static String getSelectContent(Editor editor) { + return getSelectContent(editor, true); + } + + public static String getSelectContent(Editor editor, boolean selectLine) { + try { + Document document = editor.getDocument(); + final SelectionModel selectionModel = editor.getSelectionModel(); + final int start = selectionModel.getSelectionStart(); + final int end = selectionModel.getSelectionEnd(); + TextRange range = new TextRange(start, end); + String selectTxt = document.getText(range); + + //没有选中任何东西,则选中那一行 + if (StringUtils.isEmpty(selectTxt) && selectLine) { + selectionModel.selectLineAtCaret(); + final int start1 = selectionModel.getSelectionStart(); + final int end1 = selectionModel.getSelectionEnd(); + TextRange range1 = new TextRange(start1, end1); + selectTxt = document.getText(range1); + if (null != selectTxt) { + selectTxt = selectTxt.trim(); + } + } + return selectTxt; + } catch (Throwable ignore) { + return ""; + } + } + + public static Editor getEditorFromPsiClass(Project project, PsiClass psiClass) { + PsiFile psiFile = psiClass.getContainingFile(); + if (psiFile != null) { + String fileName = psiFile.getName(); + PsiFile[] files = FilenameIndex.getFilesByName(project, fileName, GlobalSearchScope.allScope(project)); + for (PsiFile file : files) { + VirtualFile virtualFile = file.getVirtualFile(); + if (virtualFile != null) { + FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); + return fileEditorManager.openTextEditor(new OpenFileDescriptor(project, virtualFile), true); + } + } + } + return null; + } + + /** + * 移动到最后一个方法的最后部 + * + * @param psiClass + * @param editor + */ + public static void moveToLastMethodEnd(PsiClass psiClass, Editor editor) { + PsiMethod @NotNull [] methods = psiClass.getMethods(); + int offset = 0; + if (methods.length == 0) { + offset = psiClass.getTextRange().getEndOffset() - 1; + } else { + PsiMethod psiMethod = methods[methods.length - 1]; + offset = psiMethod.getTextRange().getEndOffset(); + } + editor.getCaretModel().moveToOffset(offset); + } + + public static void closeEditor(Project project) { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + if (null != editor) { + FileEditorManager manager = FileEditorManager.getInstance(project); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + manager.closeFile(psiFile.getVirtualFile()); + } + } + + public static void openEditor(Project project, String content, String name) { + VirtualFile virtualFile = new LightVirtualFile(name, content); + virtualFile.putUserData(Const.T_KEY, name); + ApplicationManager.getApplication().runWriteAction((Computable) () -> { + Document document = FileDocumentManager.getInstance().getDocument(virtualFile); + if (document != null) { + document.setText(content); + } + return FileEditorManager.getInstance(project).openFile(virtualFile, true); + }); + } + + public static Editor getEditor(Project project) { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + return editor; + } + + + /** + * 获取或打开指定名称和内容的编辑器。 + * 如果已经存在打开的编辑器,则返回该编辑器,否则打开一个新的编辑器。 + * 如果打开的文件扩展名为"md",则返回该编辑器。 + * + * @param project 项目对象 + * @param name 文件名称 + * @param content 文件内容 + * @return 编辑器对象 + */ + public static Editor getOrOpenEditor(Project project, String name, String content) { + Editor editor = getEditor(project); + if (null == editor || !FileDocumentManager.getInstance().getFile(editor.getDocument()).equals("md")) { + openEditor(project, content, name); + } else { + return editor; + } + return getEditor(project); + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/FileUtils.java b/athena-all/src/main/java/run/mone/m78/ip/util/FileUtils.java new file mode 100644 index 000000000..88d005ac7 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/util/FileUtils.java @@ -0,0 +1,58 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.util; + +import lombok.SneakyThrows; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/11 13:53 + */ +public class FileUtils { + + private static String serverUrl = ""; + + public static void upload(String name, String path) throws IOException { + System.out.println("upload:" + name); + String token = ""; + File file = new File(path); + } + + + public static void download(String name, String path) { + System.out.println("download:" + name); + File file = new File(path + name); + String token = ""; + } + + @SneakyThrows + public static void writeConfig(String content, String fileName) { + String userHome = System.getProperty("user.home"); + String path = System.getProperty("user.home") + File.separator + ".athena.json"; + if (!new File(path).exists()) { + com.google.common.io.Files.touch(new File(path)); + } + Files.write(Paths.get(path), content.getBytes()); + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/GitUtils.java b/athena-all/src/main/java/run/mone/m78/ip/util/GitUtils.java new file mode 100644 index 000000000..a3e304c15 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/util/GitUtils.java @@ -0,0 +1,54 @@ +package run.mone.m78.ip.util; + +import com.google.common.base.Joiner; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.changes.ChangeListManager; +import lombok.SneakyThrows; + +import java.io.BufferedReader; +import java.io.File; +import java.io.InputStreamReader; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2023/7/8 23:19 + */ +public class GitUtils { + + + /** + * 获取项目中受影响的文件名列表。 + * + * @param project 项目对象 + * @return 受影响的文件名列表 + */ + public static List getAffectedFileNames(Project project) { + ChangeListManager changeListManager = ChangeListManager.getInstance(project); + return changeListManager.getAffectedFiles().stream().map(it -> it.toString()).collect(Collectors.toList()); + } + + public static String getAffectedFileNamesStr(Project project) { + ChangeListManager changeListManager = ChangeListManager.getInstance(project); + List list = changeListManager.getAffectedFiles().stream().map(it -> it.toString()).collect(Collectors.toList()); + return list.stream().collect(Collectors.joining("\n")); + } + + + //获取git地址 + @SneakyThrows + public static String getGitAddress(Project project) { + return null; + } + + //获取最后一条commit记录 + @SneakyThrows + public static List getLastCommit(Project project) { + return null; + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/HintUtils.java b/athena-all/src/main/java/run/mone/m78/ip/util/HintUtils.java new file mode 100644 index 000000000..6c9a5aca7 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/util/HintUtils.java @@ -0,0 +1,66 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.util; + +import com.google.gson.Gson; +import com.intellij.codeInsight.hint.HintManager; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Editor; +import run.mone.m78.ip.bo.Result; +import run.mone.m78.ip.common.ChromeUtils; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/7 13:11 + */ +public class HintUtils { + + public static void show(final Editor editor, Result result) { + Gson gson = new Gson(); + String notify = gson.toJson(result); + ApplicationManager.getApplication().invokeLater(() -> { + HintManager.getInstance().showInformationHint(editor, notify); + ChromeUtils.call(editor.getProject().getName(), "showErrorCode", notify, false); + }); + } + + public static void show(final Editor editor, String message) { + show(editor, message, false); + } + + public static void show(final Editor editor, String message, boolean notifyChrome) { + ApplicationManager.getApplication().invokeLater(() -> { + if (null != editor) { + HintManager.getInstance().showInformationHint(editor, message); + if (notifyChrome) { + ChromeUtils.call(editor.getProject().getName(), "showErrorCode", message, true); + } + } + }); + } + + + + public static void show(String projectName, String message, boolean notifyChrome) { + ApplicationManager.getApplication().invokeLater(() -> { + if (notifyChrome) { + ChromeUtils.call(projectName, "showErrorCode", message, true); + } + }); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/ImportUtils.java b/athena-all/src/main/java/run/mone/m78/ip/util/ImportUtils.java new file mode 100644 index 000000000..a2cb51720 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/util/ImportUtils.java @@ -0,0 +1,52 @@ +package run.mone.m78.ip.util; + +import com.google.common.base.Splitter; +import com.intellij.codeInsight.actions.OptimizeImportsAction; +import com.intellij.codeInspection.unusedImport.UnusedImportInspection; +import com.intellij.openapi.actionSystem.ActionPlaces; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.PsiJavaFileImpl; +import com.intellij.psi.util.PsiTreeUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2023/6/22 21:41 + */ +@Slf4j +public abstract class ImportUtils { + + public static void removeInvalidImports(Project project, Editor editor) { + } + + public static void optimizeImports(Project project, Editor editor) { + + } + + + public static void addImport(Project project, Editor editor, List importStrList) { + + } + + public static PsiClass createPsiClass(PsiElementFactory factory, String className) { + return null; + } + + + public static String junitVersion(PsiClass psiClass) { + return ""; + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/LabelUtils.java b/athena-all/src/main/java/run/mone/m78/ip/util/LabelUtils.java new file mode 100644 index 000000000..9f0961916 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/util/LabelUtils.java @@ -0,0 +1,62 @@ +package run.mone.m78.ip.util; + +import com.google.common.base.Joiner; +import com.google.common.collect.Maps; +import com.intellij.openapi.project.Project; +import run.mone.m78.ip.bo.ParamDialogReq; +import run.mone.m78.ip.dialog.ParamTableDialog; +import run.mone.m78.ip.bo.PromptInfo; + +import java.util.Map; + +/** + * @author goodjava@qq.com + * @date 2023/6/17 09:22 + */ +public class LabelUtils { + + + public static String getLabelValue(Project project, PromptInfo promptInfo, String key, String defaultValue) { + Map map = ResourceUtils.getAthenaConfig(project); + String rkey = Joiner.on("@").join(promptInfo.getPromptName(), key); + if (map.containsKey(rkey)) { + return map.get(rkey); + } + return promptInfo.getLabels().getOrDefault(key, defaultValue); + } + + public static boolean isOpen(Project project, PromptInfo promptInfo, String key) { + return getLabelValue(project, promptInfo, key, "false").equals("true"); + } + + + public static String getLabelValue(Project project, String key, String defaultValue) { + //用户配置的优先级最高 + Map map = ResourceUtils.getAthenaConfig(project); + return map.getOrDefault(key, defaultValue); + } + + public static boolean open(Project project, String key) { + return open(project, key, "false"); + } + + public static boolean open(Project project, String key, String defaultValue) { + //用户配置的优先级最高 + Map map = ResourceUtils.getAthenaConfig(project); + String value = map.getOrDefault(key, defaultValue); + return value.equals("true"); + } + + public static boolean open(String key) { + return open(null, key); + } + + public static void showLabelConfigUi(Project project) { + Map map = ResourceUtils.getAthenaConfig(project); + ParamTableDialog paramTable = new ParamTableDialog(ParamDialogReq.builder().title("config").build(), project, map, Maps.newHashMap(), null); + paramTable.show(); + + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/LockUtils.java b/athena-all/src/main/java/run/mone/m78/ip/util/LockUtils.java new file mode 100644 index 000000000..4b76fe0a9 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/util/LockUtils.java @@ -0,0 +1,16 @@ +package run.mone.m78.ip.util; + +import com.intellij.openapi.editor.Editor; + +/** + * @author goodjava@qq.com + * @date 2023/6/23 09:07 + */ +public abstract class LockUtils { + + public static void lockDocument(Editor editor) { + editor.getDocument().setReadOnly(true); + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/Notify.java b/athena-all/src/main/java/run/mone/m78/ip/util/Notify.java new file mode 100644 index 000000000..5af8e5c61 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/util/Notify.java @@ -0,0 +1,53 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.util; + + +import com.intellij.notification.*; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class Notify { + + + /** + * Shows {@link Notification}. + * + * @param project current project + * @param title notification title + * @param group notification group + * @param content notification text + * @param type notification type + * @param listener optional listener + */ + public static void show(@NotNull Project project, @NotNull String title, @NotNull String content, + @NotNull NotificationGroup group, @NotNull NotificationType type, + @Nullable NotificationListener listener) { + } + + public static void show(@NotNull Project project, + @NotNull String groupId, @NotNull String content, @NotNull NotificationType type) { + NotificationGroupManager.getInstance() + // plugin.xml里配置的id + .getNotificationGroup(groupId) + .createNotification(content, type) + .notify(project); + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/PackageUtils.java b/athena-all/src/main/java/run/mone/m78/ip/util/PackageUtils.java new file mode 100644 index 000000000..a03c0b06e --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/util/PackageUtils.java @@ -0,0 +1,37 @@ +package run.mone.m78.ip.util; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.JavaPsiFacade; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiPackage; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/6/15 13:52 + */ +public class PackageUtils { + + + public static List getClassList(Project project, String packageName) { + PsiPackage psiPackage = JavaPsiFacade.getInstance(project).findPackage(packageName); + List result = new ArrayList<>(); + if (psiPackage != null) { + PsiClass[] psiClasses = psiPackage.getClasses(); + for (PsiClass psiClass : psiClasses) { + String className = psiClass.getQualifiedName(); + result.add(className); + } + } + return result; + } + + public static PsiPackage findPackageByName(Project project, String packageName) { + JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project); + PsiPackage psiPackage = javaPsiFacade.findPackage(packageName); + return psiPackage; + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/ProjectUtils.java b/athena-all/src/main/java/run/mone/m78/ip/util/ProjectUtils.java new file mode 100644 index 000000000..2629d93c4 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/util/ProjectUtils.java @@ -0,0 +1,216 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.util; + +import com.google.common.collect.Lists; +import com.intellij.ide.DataManager; +import com.intellij.ide.RecentProjectsManager; +import com.intellij.ide.RecentProjectsManagerBase; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.fileEditor.TextEditor; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.ModuleUtilCore; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.projectRoots.JavaSdkVersion; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.util.PsiUtilBase; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/6 17:51 + */ +public class ProjectUtils { + + + public static Project project() { + DataContext dataContext = DataManager.getInstance().getDataContext(); + return (Project) dataContext.getData(DataConstants.PROJECT); + } + + + public static Project projectFromManager() { + Project project = ProjectManager.getInstance().getOpenProjects()[0]; + return project; + } + + public static Project projectFromManager(String name) { + return null; + } + + /** + * 最近打开的项目 + * + * @return + */ + public static List recentProjects() { + RecentProjectsManager recentProjectsManager = RecentProjectsManager.getInstance(); + List v = ((RecentProjectsManagerBase) recentProjectsManager).getRecentPaths(); + return v; + } + + /** + * 已经打开的project 列表 + * + * @return + */ + public static List listOpenProjects() { + ProjectManager projectManager = ProjectManager.getInstance(); + Project[] openProjects = projectManager.getOpenProjects(); + return Arrays.stream(openProjects).map(it -> it.getName()).collect(Collectors.toList()); + } + + /** + * 列出所有module + * + * @param project + * @return + */ + public static List listAllModules(Project project) { + try { + ModuleManager moduleManager = ModuleManager.getInstance(project); + Module[] modules = moduleManager.getModules(); + return Arrays.stream(modules).map(it -> it.getName()).collect(Collectors.toList()); + } catch (Throwable ex) { + return Lists.newArrayList(); + } + } + + public static Module getModuleWithName(Project project, String name) { + ModuleManager moduleManager = ModuleManager.getInstance(project); + Module[] modules = moduleManager.getModules(); + return Arrays.stream(modules).filter(it -> it.getName().equals(name)).findFirst().get(); + } + + public static List listEditors(Project project) { + List result = new ArrayList<>(); + FileEditorManager editorManager = FileEditorManager.getInstance(project); + for (FileEditor editor : editorManager.getAllEditors()) { + if (editor instanceof TextEditor) { + TextEditor textEditor = ((TextEditor) editor); + result.add(textEditor.getFile().getName()); + } + } + return result; + } + + public static Module getCurrentModule(Project project) { + try { + @Nullable Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + if (null == editor) { + //如果没有打开的文件,尝试打开第一个module + ModuleManager moduleManager = ModuleManager.getInstance(project); + Module[] modules = moduleManager.getModules(); + if (modules.length > 0) { + + List list = Arrays.stream(modules).sorted((a, b) -> { + String ap = a.getModuleFilePath(); + String bp = b.getModuleFilePath(); + return bp.length() - ap.length(); + }).collect(Collectors.toList()); + + return list.get(0); + } + return null; + } + PsiFile psiFile = PsiUtilBase.getPsiFileInEditor(Objects.requireNonNull(editor), project); + if (psiFile != null) { + VirtualFile virtualFile = psiFile.getVirtualFile(); + if (virtualFile != null) { + return ModuleUtilCore.findModuleForFile(virtualFile, project); + } + } + return null; + } catch (Throwable ex) { + return null; + } + } + + public static String getCurrentModudleName(Project project) { + Module module = getCurrentModule(project); + if (null == module) { + return ""; + } + return module.getName(); + } + + + public static void openFileByPath(Project project, String filePath) { + VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByPath(filePath); + OpenFileDescriptor descriptor = new OpenFileDescriptor(project, virtualFile); + descriptor.navigate(true); + PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile); + if (psiFile != null) { + CodeStyleManager.getInstance(project).reformat(psiFile); + } + } + + public static VirtualFile getSourceRoot(Project project, String moduleName) { + Module currentModule = ProjectUtils.getModuleWithName(project, moduleName); + if (Objects.isNull(currentModule)) { + return null; + } + VirtualFile[] sourceRoots = ModuleRootManager.getInstance(currentModule).getSourceRoots(false); + return sourceRoots[0]; + } + + + public static JavaSdkVersion getJdkVersion(Project project) { + Sdk projectSdk = ProjectRootManager.getInstance(project).getProjectSdk(); + if (projectSdk != null) { + return JavaSdkVersion.fromVersionString(projectSdk.getVersionString()); + } + return null; + } + + + public static List getResourceImport(Project project) { + JavaSdkVersion version = getJdkVersion(project); + if (null != version && version.ordinal() <= 8) { + return Lists.newArrayList("import javax.annotation.Resource"); + } + return Lists.newArrayList("import jakarta.annotation.Resource"); + } + + public static String getModulePath(Project project, String moduleName) { + Module module = getModuleWithName(project, moduleName); + return new File(module.getModuleFilePath()).getParent(); + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/PromptUtils.java b/athena-all/src/main/java/run/mone/m78/ip/util/PromptUtils.java new file mode 100644 index 000000000..e25a9fa58 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/util/PromptUtils.java @@ -0,0 +1,257 @@ +package run.mone.m78.ip.util; + +import com.google.common.collect.Maps; +import com.google.gson.Gson; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiClass; +import run.mone.m78.ip.bo.GenerateCodeReq; +import run.mone.m78.ip.common.Prompt; +import run.mone.m78.ip.dialog.DialogResult; +import run.mone.m78.ip.service.CodeService; +import run.mone.m78.ip.bo.CreateClassMeta; +import run.mone.m78.ip.bo.PromptInfo; +import run.mone.m78.ip.common.ConfigUtils; +import run.mone.m78.ip.dialog.ChromeDialog; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.net.URLEncoder; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2023/5/29 10:09 + */ +@Slf4j +public class PromptUtils { + + + private static final Gson gson = new Gson(); + + + public static Map getParamsFromAiProxy(String promptName, String metaStr) { + return getParamsFromAiProxy(promptName, metaStr, false); + } + + public static Map getParamsFromAiProxy(String promptName, String metaStr, boolean useSelect) { + return Maps.newHashMap(); + } + + + /** + * 创建类(class enum) + * + * @param project + * @param modelName + * @param promptName + */ + public static void createClass(Project project, final String modelName, String promptName) { + + } + + private static String getModelName(String modelName, Map values) { + if (StringUtils.isEmpty(modelName)) { + modelName = values.getOrDefault("module", "").toString(); + } + return modelName; + } + + @Nullable + private static String[] getParams(CreateClassMeta createClassMeta, Editor editor) { + String[] params = null; + if (ObjectUtils.notEqual(null, createClassMeta) && createClassMeta.isUseSelect()) { + params = new String[]{EditorUtils.getSelectContent(editor)}; + } + return params; + } + + + public static void createClass2(Project project, String promptName, String showDialog, Map param) { + String isShowDialog = StringUtils.isEmpty(showDialog) ? "true" : showDialog; + PromptInfo promptInfo = Prompt.getPromptInfo(promptName); + Map v = getParamsFromAiProxy(promptName, promptInfo.getMeta()); + if ("true".equals(isShowDialog)) { + String url = buildDialogUrl(project, v, promptInfo); + ChromeDialog chromeDialog = new ChromeDialog(url, project); + chromeDialog.show(); + return; + } + + String packageStr = param.get("package").toString(); + String className = param.get("class").toString(); + String modelName = param.get("modelName").toString(); + + CodeService.createEmptyClass(project, modelName, packageStr, className); + + PsiClass psiClass = CodeService.getPsiClass2(project); + TextRange textRange = psiClass.getTextRange(); + CodeService.deleteTextRange(project, psiClass.getTextRange()); + Editor codeEditor = CodeService.getEditor(project); + codeEditor.getCaretModel().moveToOffset(textRange.getStartOffset()); + + Map pm = param.entrySet().stream().collect(Collectors.toMap(en -> en.getKey(), en -> en.getValue().toString())); + CodeService.generateCodeWithAi3(project, promptName, new String[]{}, pm, (p, code) -> CodeService.writeCode2(p, codeEditor, code)); + + } + + + /** + * $$->隐藏 + * $@$->选择框 + * + * @param project + * @param param + * @param promptInfo + * @return + */ + private static String buildDialogUrl(Project project, Map param, PromptInfo promptInfo) { + if (!param.containsKey("model")) { + param.put("$@$model", ProjectUtils.listAllModules(project)); + } + if (!param.containsKey("package")) { + param.put("package", ""); + } + if (param.containsKey("class")) { + param.put("class", ""); + } + param.put("$$showDialog", "false"); + param.put("$$prompt", promptInfo.getPromptName()); + param.put("$$desc", promptInfo.getDesc()); + return ConfigUtils.getConfig().getChatServer() + "/code-form" + "?param=" + URLEncoder.encode(gson.toJson(param)); + } + + /** + * 给方法添加注释 + * + * @param req + */ + public static void addComment(GenerateCodeReq req) { + + } + + + /** + * 修改class + * + * @param project + * @param promptName + */ + public static void modifyClass(Project project, String promptName) { + PsiClass psiClass = CodeService.getPsiClass2(project); + String codeStr = psiClass.getText(); + CodeService.deletePsiClass(project, psiClass); + Editor codeEditor = CodeService.getEditor(project); + CodeService.generateCodeWithAi2(project, promptName, new String[]{codeStr}, (p, code) -> CodeService.writeCode2(p, codeEditor, code)); + } + + + /** + * 创建一个文件 + * + * @param req + */ + public static void createFile(String promptName, String fileName, GenerateCodeReq req) { + + } + + /** + * @param req + */ + public static void updateClass(GenerateCodeReq req) { + PsiClass psiClass = CodeService.getPsiClass(req.getProject()); + String classCode = psiClass.getText(); + TextRange textRange = psiClass.getTextRange(); + CodeService.deleteTextRange(req.getProject(), textRange); + Editor editor = CodeService.getEditor(req.getProject()); + CodeService.generateCodeWithAi2(req.getProject(), req.getPromptName(), new String[]{classCode}, (p, code) -> CodeService.writeCode2(p, editor, code)); + } + + /** + * 更新方法 + * + * @param req + */ + public static void updateMethod(GenerateCodeReq req) { + + } + + /** + * 给一个方法添加逐行注释,或者代码 + * + * @param promptName + * @param req + */ + public static void lineByLineCommentOrCode(String promptName, GenerateCodeReq req) { + + } + + private static String filterAnnoCode(String codeStr, PromptInfo promptInfo) { + return codeStr; + } + + private static void addImportList(Project project, Map map) { + + } + + public static List getImportList(PromptInfo promptInfo) { + return null; + } + + /** + * @param req + * @param map + * @return + */ + @NotNull + private static String getCode(GenerateCodeReq req, Map map) { + return ""; + } + + @NotNull + private static String getScope(GenerateCodeReq req, Map map) { + return ""; + } + + + private static Pair getPackageAndClass(DialogResult result) { + return null; + } + + private static DialogResult showDialog(Project project, Module module, String data) { + return null; + } + + /** + * 生成接口 + * + * @param req + */ + public static void generateInterface(GenerateCodeReq req) { + + + } + + /** + * 用来生成测试方法 + */ + public static void select(GenerateCodeReq req, Project project, Module module, PromptInfo promptInfo) { + + } + + public static void checkPomVersion(GenerateCodeReq req) { + } + + public static void generateAnnoForBootStrap(String promptName, Project project) { + + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/PsiClassUtils.java b/athena-all/src/main/java/run/mone/m78/ip/util/PsiClassUtils.java new file mode 100644 index 000000000..9085f1cec --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/util/PsiClassUtils.java @@ -0,0 +1,393 @@ +package run.mone.m78.ip.util; + +import com.google.common.collect.ImmutableList; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.ModuleUtilCore; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiShortNamesCache; +import run.mone.m78.ip.bo.AddMethodConfig; +import run.mone.m78.ip.bo.ParamInfo; +import run.mone.m78.ip.common.JavaClassUtils; +import run.mone.m78.ip.service.CodeService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.CollectionUtils; +import org.jetbrains.annotations.NotNull; +import run.mone.ultraman.bo.AthenaClassInfo; +import run.mone.ultraman.service.AthenaCodeService; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2023/5/13 10:18 + */ +@Slf4j +public class PsiClassUtils { + + + /** + * 获取方法列表 + * + * @param psiClass + * @return + */ + public static List getMethodList(PsiClass psiClass) { + return Arrays.stream(psiClass.getAllMethods()).map(it -> it.getName()).collect(Collectors.toList()); + } + + /** + * 根据类名查找这个类 + * + * @param project + * @param className + * @return + */ + public static PsiClass findClassByName(Project project, String className) { + JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project); + GlobalSearchScope scope = GlobalSearchScope.allScope(project); + PsiClass psiClass = javaPsiFacade.findClass(className, scope); + return psiClass; + } + + + /** + * 添加字段 + * 如果里边有同名字段则不添加 + * + * @param project + * @param psiClass + * @param name + * @param type + */ + public static void addField(Project project, PsiClass psiClass, String name, PsiType type) { + PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project); + boolean find = Arrays.stream(psiClass.getFields()).filter(it -> it.getName().equals(name)).findAny().isPresent(); + if (!find) { + PsiField field = elementFactory.createField(name, type); + psiClass.add(field); + } + } + + public static PsiClass getInterface(PsiClass psiClass) { + return Arrays.stream(psiClass.getInterfaces()).findAny().orElse(null); + } + + /** + * 添加方法(支持向类中或者interface中添加) + * + * @param project + * @param psiClass + * @param paramInfoList + */ + public static void addMethod(Project project, PsiClass psiClass, AddMethodConfig config, List paramInfoList) { + PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project); + String name = config.getName(); + PsiType returnType = config.getReturnType(); + @NotNull PsiMethod method = elementFactory.createMethod(name, returnType, psiClass); + paramInfoList.stream().forEach(it -> { + PsiParameter param = elementFactory.createParameter(it.getName(), it.getPsiType()); + method.getParameterList().add(param); + }); + if (config.isInterface()) { + PsiElement replacement = elementFactory.createStatementFromText(";", psiClass); + method.getBody().replace(replacement); + } + psiClass.add(method); + } + + public static void addImport(PsiClass psiClass, String className) { + PsiElementFactory factory = JavaPsiFacade.getElementFactory(psiClass.getProject()); + PsiClass pc = CodeService.createPsiClass(factory, className); + PsiImportStatement importStatement = factory.createImportStatement(pc); + PsiJavaFile javaFile = (PsiJavaFile) psiClass.getContainingFile(); + boolean has = Arrays.stream(javaFile.getImportList().getImportStatements()).filter(it -> it.getQualifiedName().equals(className)).findAny().isPresent(); + if (!has) { + javaFile.getImportList().add(importStatement); + } + } + + public static PsiClass findApplicationRunClass(Project project) { + PsiShortNamesCache shortNamesCache = PsiShortNamesCache.getInstance(project); + PsiClassType mainClassType = JavaPsiFacade.getInstance(project).getElementFactory().createTypeByFQClassName("java.lang.Object", GlobalSearchScope.allScope(project)); + PsiClass resolvedMainClassType = Objects.requireNonNull(mainClassType.resolve()); + PsiMethod[] methods = shortNamesCache.getMethodsByName("main", GlobalSearchScope.allScope(project)); + for (PsiMethod method : methods) { + PsiClass containingClass = method.getContainingClass(); + if (containingClass != null && containingClass.isInheritor(resolvedMainClassType, true)) { + PsiParameterList parameterList = method.getParameterList(); + if (parameterList.getParametersCount() == 1) { + PsiParameter[] parameters = parameterList.getParameters(); + PsiType parameterType = parameters[0].getType(); + boolean isStringArrayType = parameterType instanceof PsiArrayType && ((PsiArrayType) parameterType).getComponentType().equalsToText("java.lang.String"); + PsiModifierList modifierList = containingClass.getModifierList(); + if (isStringArrayType && (modifierList != null && modifierList.hasAnnotation("org.springframework.boot.autoconfigure.SpringBootApplication"))) { + return containingClass; + } + PsiAnnotation[] annotations = containingClass.getAnnotations(); + for (PsiAnnotation annotation : annotations) { + if ("org.springframework.boot.autoconfigure.SpringBootApplication".equals(annotation.getQualifiedName())) { + return containingClass; + } + if ("org.springframework.boot.autoconfigure.EnableAutoConfiguration".equals(annotation.getQualifiedName())) { + return containingClass; + } + } + } + } + } + return null; + } + + + public static PsiDirectory getSourceDirectory(Project project, String moduleName, boolean testPath) { + return getSourceDirectory(project, moduleName, testPath, "java"); + } + + public static void createEmptyClass(Project project, String moduleName, String packageName, String className, boolean testPath) { + createEmptyClass(project, moduleName, packageName, className, testPath, true, null, false); + } + + public static void createEmptyClass(Project project, String moduleName, String packageName, String className, boolean testPath, List annoList) { + createEmptyClass(project, moduleName, packageName, className, testPath, true, annoList, false); + + } + + public static void createEmptyClass(Project project, String moduleName, String packageName, String className, boolean testPath, boolean isInterface) { + createEmptyClass(project, moduleName, packageName, className, testPath, false, null, isInterface); + } + + + public static void createEmptyClass(Project project, String moduleName, String packageName, String className, boolean testPath, boolean openClass, List annoList, boolean isInterface) { + + } + + //创建一个类,并打开 + public static void createClass(Project project, String packageStr, String className, String code) { + WriteCommandAction.runWriteCommandAction(project, () -> { + PsiFileFactory psiFileFactory = PsiFileFactory.getInstance(project); + PsiFile psiFile = psiFileFactory.createFileFromText(className + ".java", code); + PsiDirectory directory = getDirectoryFromPackage(project, packageStr); + directory.add(psiFile); + //打开这个类 + JavaClassUtils.openClass(project, className); + //格式化代码 + CodeService.formatCode(project); + }); + } + + public static PsiDirectory getDirectoryFromPackage(Project project, String packagePath) { + PsiManager psiManager = PsiManager.getInstance(project); + JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project); + PsiPackage psiPackage = javaPsiFacade.findPackage(packagePath); + if (psiPackage != null) { + PsiDirectory[] directories = psiPackage.getDirectories(); + if (directories.length > 0) { + return directories[0]; + } + } + return null; + } + + + private static String buildEmptyClassInfo(Project project, String className, boolean testPath, List annoList) { + String classText = testPath ? + String.format("public class %s{\n\n}", className) + : String.format("import java.io.Serializable;\nimport lombok.Builder;\nimport lombok.Data;\n\n@Data\n@Builder\npublic class %s implements Serializable{\n\n}", className); + if (CollectionUtils.isNotEmpty(annoList)) { + StringBuilder sb = new StringBuilder(); + annoList.forEach(a -> { + if ("@SpringBootTest".equals(a)) { + PsiClass applicationRunClass = findApplicationRunClass(project); + sb.append(String.format("import %s;", applicationRunClass.getQualifiedName())); + a = String.format(a + "(classes = %s.class)", applicationRunClass.getName()); + } + sb.append(a).append("\n"); + }); + sb.append(classText); + return sb.toString(); + } + return classText; + } + + public static String buildEmptyInterfaceInfo(String className) { + return String.format("public interface %s{\n\n}", className); + } + + public static PsiDirectory getSourceDirectory(Project project, String moduleName, boolean testPath, String sourceFolderPath) { + Module[] modules = ModuleManager.getInstance(project).getModules(); + for (Module module : modules) { + ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); + if (!module.getName().equals(moduleName)) { + continue; + } + for (VirtualFile sourceFolder : moduleRootManager.getSourceRoots(testPath)) { + //包含/test/目录才是测试代码路径 + if (testPath && !sourceFolder.getPath().contains("/src/test/java")) { + continue; + } + if (sourceFolder.getName().equals(sourceFolderPath)) { + return PsiManager.getInstance(project).findDirectory(sourceFolder); + } + } + } + return null; + } + + + public static PsiDirectory getSourceDirectory(Project project, String moduleName) { + return getSourceDirectory(project, moduleName, "/src/main/java"); + } + + public static PsiDirectory getSourceDirectory(Project project, String moduleName, String containsPath) { + Module[] modules = ModuleManager.getInstance(project).getModules(); + for (Module module : modules) { + ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); + if (!module.getName().equals(moduleName)) { + continue; + } + for (VirtualFile sourceFolder : moduleRootManager.getSourceRoots(false)) { + //包含/test/目录才是测试代码路径 + if (sourceFolder.getPath().contains(containsPath)) { + return PsiManager.getInstance(project).findDirectory(sourceFolder).getParent(); + } + } + } + return null; + } + + public static PsiDirectory getDirectory(Project project, String moduleName, String containsPath) { + Module[] modules = ModuleManager.getInstance(project).getModules(); + for (Module module : modules) { + ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); + if (!module.getName().equals(moduleName)) { + continue; + } + for (VirtualFile sourceFolder : moduleRootManager.getSourceRoots(false)) { + //包含/test/目录才是测试代码路径 + if (sourceFolder.getPath().contains(containsPath)) { + return PsiManager.getInstance(project).findDirectory(sourceFolder); + } + } + } + return null; + } + + + public static PsiDirectory getSourceDirectory(Project project, boolean testPath, String packagePath) { + return null; + } + + public static Module getModule(Project project, PsiClass psiClass) { + VirtualFile virtualFile = psiClass.getContainingFile().getVirtualFile(); + Module module = ModuleUtilCore.findModuleForFile(virtualFile, project); + return module; + } + + private static List list = ImmutableList.of("javax.annotation.Resource", "jakarta.annotation.Resource" + , "org.springframework.beans.factory.annotation.Autowired", "org.apache.dubbo.config.annotation.Reference" + , "org.apache.dubbo.config.annotation.DubboReference" + ); + + + public static List findFieldsWithResourceAnnotation(@NotNull PsiClass psiClass) { + return Arrays.stream(psiClass.getFields()).filter(it -> hasAnno(it, list)).collect(Collectors.toList()); + } + + + private static boolean hasAnno(PsiField field, List annoList) { + if (null == field || null == annoList) { + return false; + } + try { + return annoList.stream().filter(it -> field.getAnnotation(it) != null).findAny().isPresent(); + } catch (Throwable ex) { + return false; + } + } + + public static List getClassText(Project project, List fields) { + return fields.stream().map(it -> { + PsiClass psiClass = PsiClassUtils.findClassByName(project, it.getType().getCanonicalText()); + if (null != psiClass) { + if (psiClass.isInterface()) { + return psiClass.getText(); + } else { + return PsiClassUtils.getInterfaceText(project, psiClass); + } + } + return null; + }).filter(it -> null != it).collect(Collectors.toList()); + } + + public static String getClassText(Project project, String text) { + PsiClass psiClass = PsiClassUtils.findClassByName(project, text); + if (null != psiClass) { + if (psiClass.isInterface()) { + return psiClass.getText(); + } else { + return PsiClassUtils.getInterfaceText(project, psiClass); + } + } + return ""; + } + + + public static String getInterfaceText(Project project, PsiClass originalClass) { + //直接先分析下代码,如果加了@Data注解,则直接自己分析了 + try { + String code = originalClass.getText(); + AthenaClassInfo info = AthenaCodeService.classInfo(code); + return info.getClassCode(); + } catch (Throwable ex) { + log.error(ex.getMessage()); + } + + + PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); + PsiClass newInterface = factory.createInterface(originalClass.getName()); + PsiMethod[] methods = originalClass.getMethods(); + for (PsiMethod method : methods) { + try { + if (method.hasModifierProperty(PsiModifier.PUBLIC)) { + + if (method.getClass().getName().equals("de.plushnikov.intellij.plugin.psi.LombokLightMethodBuilder")) { + continue; + } + + PsiMethod newMethod = factory.createMethod(method.getName(), method.getReturnType()); + for (PsiParameter parameter : method.getParameterList().getParameters()) { + newMethod.getParameterList().add(parameter); + } + + for (PsiElement child : method.getChildren()) { + if (child instanceof PsiComment) { + newMethod.addBefore(child, newMethod.getFirstChild()); + } + } + + @NotNull PsiElement newLine = PsiParserFacade.getInstance(project).createWhiteSpaceFromText("\n\n"); + newMethod.addBefore(newLine, newMethod.getFirstChild()); + + newInterface.add(newLine); + newInterface.add(newMethod); + } + } catch (Throwable ignore) { + + } + + } + return newInterface.getText(); + + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/PsiFieldUtils.java b/athena-all/src/main/java/run/mone/m78/ip/util/PsiFieldUtils.java new file mode 100644 index 000000000..8420fd73a --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/util/PsiFieldUtils.java @@ -0,0 +1,57 @@ +package run.mone.m78.ip.util; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.JavaPsiFacade; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElementFactory; +import com.intellij.psi.PsiField; +import run.mone.m78.ip.bo.AnnoInfo; +import run.mone.m78.ip.bo.AnnoMember; +import run.mone.m78.ip.bo.FieldInfo; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2023/6/21 16:25 + */ +public class PsiFieldUtils { + + + //根据PsiClass获取字段信息列表 + public static List list(PsiClass psiClass) { + return Arrays.stream(psiClass.getFields()).map(it -> { + FieldInfo info = new FieldInfo(); + info.setName(it.getName()); + info.setClassType(it.getType().getCanonicalText()); + List annoList = Arrays.stream(it.getAnnotations()).map(it2 -> { + AnnoInfo annoInfo = new AnnoInfo(); + annoInfo.setName(it2.getQualifiedName()); + Map m = it2.getAttributes().stream().map(it3 -> { + String key = it3.getAttributeName(); + String value = it2.findAttributeValue(key).getText(); + return AnnoMember.builder().key(key).value(value).build(); + }).collect(Collectors.toMap(key -> key.getKey(), value -> value)); + annoInfo.setMembers(m); + return annoInfo; + }).collect(Collectors.toList()); + info.setAnnoList(annoList); + return info; + }).collect(Collectors.toList()); + } + + + //重命名项目中的指定字段 + public static void rename(Project project, PsiField field, String newName) { + PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); + PsiField newField = factory.createField(newName, field.getType()); + newField.setInitializer(field.getInitializer()); + newField.getModifierList().replace(field.getModifierList()); + field.replace(newField); + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/ResourceUtils.java b/athena-all/src/main/java/run/mone/m78/ip/util/ResourceUtils.java new file mode 100644 index 000000000..80afdaf5f --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/util/ResourceUtils.java @@ -0,0 +1,128 @@ +package run.mone.m78.ip.util; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import run.mone.m78.ip.common.Const; +import lombok.SneakyThrows; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Type; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author goodjava@qq.com + * @date 2023/6/15 17:35 + */ +public class ResourceUtils { + + private static Gson gson = new Gson(); + + public static final String USER_HOME_ATHENA_FILE_NAME = ".athena.json"; + + public static String readResources(Project project, Module module) { + try { + StringBuilder stringBuilder = new StringBuilder(); + PsiDirectory directory = PsiClassUtils.getSourceDirectory(project, module.getName(), false, "resources"); + VirtualFile resourcesFolder = directory.getVirtualFile(); + if (resourcesFolder != null) { + for (VirtualFile file : resourcesFolder.getChildren()) { + if (!file.isDirectory() && file.getName().startsWith("athena_")) { + String text = FileDocumentManager.getInstance().getDocument(file).getText(); + stringBuilder.append(text); + stringBuilder.append("\n"); + } + } + } + return stringBuilder.toString(); + } catch (Throwable ignore) { + + } + return ""; + } + + + private static ConcurrentHashMap config = new ConcurrentHashMap<>(); + + + /** + * 获取用户的雅典娜配置 + * + * @param project + * @return + */ + @SneakyThrows + public static Map getAthenaConfig(Project project, boolean refresh) { + if (!config.isEmpty() && !refresh) { + return config; + } + config.clear(); + String str = ""; + if (null != project) { + str = project.getBasePath() + File.separator + "athena.json"; + getConfig(str); + } + str = System.getProperty("user.home") + File.separator + USER_HOME_ATHENA_FILE_NAME; + config.putAll(defaultConfig); + getConfig(str); + return config; + } + + + private static Map defaultConfig = new HashMap<>() { + { + put(Const.VISION, "false"); + put(Const.DEBUG, "false"); + put(Const.OPEN_GUIDE, "false"); + put(Const.DISABLE_ACTION_GROUP, "false"); + put(Const.BIZ_WRITE, "false"); + put(Const.OPEN_AI_KEY, ""); + put(Const.OPEN_AI_PROXY, ""); + put(Const.OPEN_AI_LOCAL, "true"); + put(Const.OPEN_AI_TEST, "false"); + put(Const.OPEN_SELECT_TEXT, "true"); + put(Const.OPEN_AI_MODEL, "gpt-4-1106-preview");//gpt-3.5-turbo + put(Const.DISABLE_SEARCH, "false"); + put(Const.AI_PROXY_CHAT, "true"); + put(Const.ENABLE_ATHENA_STATUS_BAR, "false"); + } + }; + + + private static void getConfig(String str) throws IOException { + if (new File(str).exists()) { + String s = Files.readString(Paths.get(str)); + Type typeOfT = new TypeToken>() { + }.getType(); + Map m = gson.fromJson(s, typeOfT); + if (null != m && m.size() > 0) { + config.putAll(m); + } + } + } + + + public static Map getAthenaConfig(Project project) { + return getAthenaConfig(project, false); + } + + + public static Map getAthenaConfig() { + return getAthenaConfig(null, false); + } + + + public static void putConfigIfAbsent(String key, String value) { + config.putIfAbsent(key, value); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/RunUntil.java b/athena-all/src/main/java/run/mone/m78/ip/util/RunUntil.java new file mode 100644 index 000000000..2e7fbf574 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/util/RunUntil.java @@ -0,0 +1,27 @@ +package run.mone.m78.ip.util; + +import com.intellij.execution.RunManager; +import com.intellij.execution.RunnerAndConfigurationSettings; +import com.intellij.execution.executors.DefaultDebugExecutor; +import com.intellij.execution.runners.ExecutionUtil; +import com.intellij.openapi.project.Project; + +/** + * @author goodjava@qq.com + * @date 2023/4/17 23:50 + */ +public class RunUntil { + + + public static void run(Project project) { + RunnerAndConfigurationSettings runConfig = RunManager.getInstance(project).getSelectedConfiguration(); + ExecutionUtil.runConfiguration(runConfig, new DefaultDebugExecutor()); + } + + public static void run2(Project project) { + RunnerAndConfigurationSettings runConfig = RunManager.getInstance(project).getSelectedConfiguration(); + ExecutionUtil.runConfiguration(runConfig, new DefaultDebugExecutor()); + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/ScreenSizeUtils.java b/athena-all/src/main/java/run/mone/m78/ip/util/ScreenSizeUtils.java new file mode 100644 index 000000000..0023e8cdc --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/util/ScreenSizeUtils.java @@ -0,0 +1,35 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.util; + +import java.awt.*; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/11 13:37 + */ +public class ScreenSizeUtils { + + + public static Dimension size() { + Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize(); + Dimension dimension = new Dimension(); + dimension.setSize(screensize.width / 3, screensize.height / 3); + return dimension; + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/SpringUtils.java b/athena-all/src/main/java/run/mone/m78/ip/util/SpringUtils.java new file mode 100644 index 000000000..063c30532 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/util/SpringUtils.java @@ -0,0 +1,23 @@ +package run.mone.m78.ip.util; + +import com.intellij.psi.PsiAnnotation; +import com.intellij.psi.PsiClass; +import org.jetbrains.annotations.Nullable; + +/** + * @author goodjava@qq.com + * @date 2023/8/10 10:39 + */ +public class SpringUtils { + + + public static boolean isSpringClass(PsiClass pc) { + @Nullable PsiAnnotation anno = pc.getAnnotation("org.springframework.stereotype.Service"); + if (null != anno) { + return true; + } + return false; + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/TerminalUtils.java b/athena-all/src/main/java/run/mone/m78/ip/util/TerminalUtils.java new file mode 100644 index 000000000..88701e92f --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/util/TerminalUtils.java @@ -0,0 +1,86 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.util; + +import com.intellij.execution.ExecutionException; +import com.intellij.execution.configurations.GeneralCommandLine; +import com.intellij.execution.process.OSProcessHandler; +import com.intellij.execution.process.ProcessAdapter; +import com.intellij.execution.process.ProcessEvent; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowAnchor; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.wm.ex.ToolWindowManagerEx; +import com.intellij.terminal.JBTerminalPanel; +import com.jediterm.terminal.TerminalOutputStream; +import lombok.SneakyThrows; + +import javax.swing.*; +import java.util.concurrent.TimeUnit; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/7 11:21 + */ +public class TerminalUtils { + + @SneakyThrows + public static void show(Project project) { + ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(project); + ToolWindow terminal = toolWindowManager.getToolWindow("Terminal"); + if (terminal != null) { + terminal.show(null); + if (!terminal.isActive()) { + TimeUnit.SECONDS.sleep(1); + } + } + } + + + public static void send(Project project, String message) { + + } + + public static ToolWindow getTerminalToolWindow(Project project) { + return null; + } + + + public static void runCommandOnTerminal(Project project, String command) { + + + } + + + private static Object getPannel(Object root) { + if (root instanceof JBTerminalPanel) { + return root; + } + if (root instanceof JPanel) { + return getPannel(((JPanel) root).getComponent(0)); + } + if (root instanceof JLayeredPane) { + return getPannel(((JLayeredPane) root).getComponent(0)); + } + return null; + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/TestUtils.java b/athena-all/src/main/java/run/mone/m78/ip/util/TestUtils.java new file mode 100644 index 000000000..17010eea2 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/util/TestUtils.java @@ -0,0 +1,52 @@ +package run.mone.m78.ip.util; + +import com.google.common.collect.Lists; + +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/8/11 09:46 + */ +public class TestUtils { + + + public static List junitImportList = Lists.newArrayList("import org.junit.Test", "import org.junit.Assert"); + + public static List jupiterImportList = Lists.newArrayList("import org.junit.jupiter.api.Test", "import static org.junit.jupiter.api.Assertions.assertEquals", "import static org.junit.jupiter.api.Assertions.assertNotNull"); + + + public static boolean isJupiter() { + if (isClassPresent("org.junit.Test")) { + return false; + } else if (isClassPresent("org.junit.jupiter.api.Test")) { + return true; + } else { + return false; + } + } + + public static List getImportList(String version) { + if (version.equals("unknow")) { + return Lists.newArrayList(); + } + if (version.equals("junit")) { + return junitImportList; + } + if (version.equals("jupiter")) { + return junitImportList; + } + return Lists.newArrayList(); + } + + + private static boolean isClassPresent(String className) { + try { + Class.forName(className); + return true; + } catch (ClassNotFoundException e) { + return false; + } + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/UltramanConsole.java b/athena-all/src/main/java/run/mone/m78/ip/util/UltramanConsole.java new file mode 100644 index 000000000..9933160d0 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/util/UltramanConsole.java @@ -0,0 +1,56 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.util; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowManager; +import run.mone.m78.ip.common.Safe; +import run.mone.ultraman.common.SafeRun; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/9 17:13 + */ +public class UltramanConsole { + + + public static void append(String message) { + append(ProjectUtils.project(), message, true); + } + + public static void append(String projectName, String messsage) { + SafeRun.run(()-> append(ProjectUtils.projectFromManager(projectName), messsage)); + } + + + public static void append(Project project, String message) { + append(project, message, true); + } + + public static void append(Project project, String message, boolean enableAutoWrap) { + + } + + public static void show() { + Safe.run(() -> { + ToolWindow toolWindow = ToolWindowManager.getInstance(ProjectUtils.project()).getToolWindow("AthenaConsole"); + toolWindow.show(); + }); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/WindowUtils.java b/athena-all/src/main/java/run/mone/m78/ip/util/WindowUtils.java new file mode 100644 index 000000000..71721bd92 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/util/WindowUtils.java @@ -0,0 +1,20 @@ +package run.mone.m78.ip.util; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowManager; + +/** + * @author goodjava@qq.com + * @date 2023/4/18 00:08 + */ +public class WindowUtils { + + + public static void actionPerformed(Project project) { + ToolWindow toolWindow = ToolWindowManager.getInstance(project).getToolWindow("Project"); + toolWindow.hide(); + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/XmlUtils.java b/athena-all/src/main/java/run/mone/m78/ip/util/XmlUtils.java new file mode 100644 index 000000000..639998347 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/util/XmlUtils.java @@ -0,0 +1,98 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.util; + +import com.google.common.collect.Maps; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; +import lombok.SneakyThrows; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import run.mone.ultraman.AthenaContext; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.util.HashMap; +import java.util.Map; + +/** + * @author goodjava@qq.com + */ +public class XmlUtils { + + + + public static Map getKV(String filePath, String tagName) { + Map res = new HashMap<>(5); + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document document = db.parse(filePath); + + NodeList l = document.getElementsByTagName(tagName); + + for (int i = 0; i < l.getLength(); i++) { + Node node = l.item(i); + NodeList c = node.getChildNodes(); + for (i = 0; i < c.getLength(); i++) { + Node n = c.item(i); + res.put(n.getNodeName(), n.getTextContent()); + } + } + } catch (Throwable ex) { + ex.printStackTrace(); + } + return res; + } + + + /** + * 获取mybatis 配置文件的位置 + * + * @param projectName + * @param moduleName + * @return + */ + public static String getGeneratorConfigPath(String projectName, String moduleName) { + return ApplicationManager.getApplication().runReadAction((Computable) () -> { + Project project = AthenaContext.ins().getProjectMap().get(projectName); + PsiDirectory directory = PsiClassUtils.getDirectory(project, moduleName, "/src/main/resources"); + @Nullable PsiFile file = directory.findFile("generatorConfig.xml"); + System.out.println(directory.getName() + file); + return file.getVirtualFile().getPath(); + }); + } + + + @SneakyThrows + public static Map getMysqlConfigFromMybatisConfig(String path) { + return Maps.newHashMap(); + + } + + + public static void updateGeneratorConfig(String path, String newName) { + + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/window/UltramanConsoleWindowFactory.java b/athena-all/src/main/java/run/mone/m78/ip/window/UltramanConsoleWindowFactory.java new file mode 100644 index 000000000..71d6acb7b --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/window/UltramanConsoleWindowFactory.java @@ -0,0 +1,43 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.window; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowFactory; +import com.intellij.ui.content.Content; +import com.intellij.ui.content.ContentFactory; +import run.mone.m78.ip.ui.UltramanConsoleUi; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/8 20:55 + */ +public class UltramanConsoleWindowFactory implements ToolWindowFactory { + + @Override + public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) { + ContentFactory contentFactory = ContentFactory.SERVICE.getInstance(); + JPanel pannel = new UltramanConsoleUi().jpanel(); + Content content = contentFactory.createContent(pannel, "", false); + toolWindow.getContentManager().addContent(content); + + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/window/UltramanWindowFactory.java b/athena-all/src/main/java/run/mone/m78/ip/window/UltramanWindowFactory.java new file mode 100644 index 000000000..cc72bfb50 --- /dev/null +++ b/athena-all/src/main/java/run/mone/m78/ip/window/UltramanWindowFactory.java @@ -0,0 +1,43 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 + * + * http://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. + */ + +package run.mone.m78.ip.window; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowFactory; +import com.intellij.ui.content.Content; +import com.intellij.ui.content.ContentFactory; +import run.mone.m78.ip.ui.UltramanTreeUi; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/8 20:55 + */ +public class UltramanWindowFactory implements ToolWindowFactory { + + @Override + public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) { + ContentFactory contentFactory = ContentFactory.getInstance(); + JPanel pannel = new UltramanTreeUi(project).jpanel(); + Content content = contentFactory.createContent(pannel, "", false); + toolWindow.getContentManager().addContent(content); + + } +} diff --git a/athena-all/src/main/java/run/mone/mone/ultraman/grpc/CommonUtils.java b/athena-all/src/main/java/run/mone/mone/ultraman/grpc/CommonUtils.java new file mode 100644 index 000000000..08671b6db --- /dev/null +++ b/athena-all/src/main/java/run/mone/mone/ultraman/grpc/CommonUtils.java @@ -0,0 +1,19 @@ +package run.mone.mone.ultraman.grpc; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2023/8/1 15:10 + */ +public class CommonUtils { + + + //ai:给你两个List,帮我计算交集 + public List getIntersection(List list1, List list2) { + return list1.stream().filter(list2::contains).collect(Collectors.toList()); + } + + +} diff --git a/athena-all/src/main/java/run/mone/mone/ultraman/grpc/Service.java b/athena-all/src/main/java/run/mone/mone/ultraman/grpc/Service.java new file mode 100644 index 000000000..c9e9c2279 --- /dev/null +++ b/athena-all/src/main/java/run/mone/mone/ultraman/grpc/Service.java @@ -0,0 +1,87 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: service.proto + +package run.mone.mone.ultraman.grpc; + +public final class Service { + private Service() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistryLite registry) { + } + + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + registerAllExtensions( + (com.google.protobuf.ExtensionRegistryLite) registry); + } + static final com.google.protobuf.Descriptors.Descriptor + internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_ParamMapEntry_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_ParamMapEntry_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_ResMapEntry_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_ResMapEntry_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + String[] descriptorData = { + + }; + com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = + new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() { + public com.google.protobuf.ExtensionRegistry assignDescriptors( + com.google.protobuf.Descriptors.FileDescriptor root) { + descriptor = root; + return null; + } + }; + com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + }, assigner); + internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_descriptor, + new String[] { "Id", "Cmd", "Params", "ParamMap", }); + internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_ParamMapEntry_descriptor = + internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_descriptor.getNestedTypes().get(0); + internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_ParamMapEntry_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_ParamMapEntry_descriptor, + new String[] { "Key", "Value", }); + internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_descriptor, + new String[] { "Id", "Data", "Code", "Cmd", "ResMap", }); + internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_ResMapEntry_descriptor = + internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_descriptor.getNestedTypes().get(0); + internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_ResMapEntry_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_ResMapEntry_descriptor, + new String[] { "Key", "Value", }); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanRequest.java b/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanRequest.java new file mode 100644 index 000000000..83bff749e --- /dev/null +++ b/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanRequest.java @@ -0,0 +1,1073 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: service.proto + +package run.mone.mone.ultraman.grpc; + +/** + * Protobuf type {@code com.xiaomi.mone.ultraman.grpc.UltramanRequest} + */ +public final class UltramanRequest extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:com.xiaomi.mone.ultraman.grpc.UltramanRequest) + UltramanRequestOrBuilder { +private static final long serialVersionUID = 0L; + // Use UltramanRequest.newBuilder() to construct. + private UltramanRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private UltramanRequest() { + id_ = ""; + cmd_ = ""; + params_ = ""; + } + + @Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private UltramanRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + String s = input.readStringRequireUtf8(); + + id_ = s; + break; + } + case 18: { + String s = input.readStringRequireUtf8(); + + cmd_ = s; + break; + } + case 26: { + String s = input.readStringRequireUtf8(); + + params_ = s; + break; + } + case 34: { + if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) { + paramMap_ = com.google.protobuf.MapField.newMapField( + ParamMapDefaultEntryHolder.defaultEntry); + mutable_bitField0_ |= 0x00000008; + } + com.google.protobuf.MapEntry + paramMap__ = input.readMessage( + ParamMapDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry); + paramMap_.getMutableMap().put( + paramMap__.getKey(), paramMap__.getValue()); + break; + } + default: { + if (!parseUnknownFieldProto3( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return Service.internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_descriptor; + } + + @SuppressWarnings({"rawtypes"}) + @Override + protected com.google.protobuf.MapField internalGetMapField( + int number) { + switch (number) { + case 4: + return internalGetParamMap(); + default: + throw new RuntimeException( + "Invalid map field number: " + number); + } + } + @Override + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return Service.internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + UltramanRequest.class, Builder.class); + } + + private int bitField0_; + public static final int ID_FIELD_NUMBER = 1; + private volatile Object id_; + /** + * string id = 1; + */ + public String getId() { + Object ref = id_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + id_ = s; + return s; + } + } + /** + * string id = 1; + */ + public com.google.protobuf.ByteString + getIdBytes() { + Object ref = id_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + id_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int CMD_FIELD_NUMBER = 2; + private volatile Object cmd_; + /** + * string cmd = 2; + */ + public String getCmd() { + Object ref = cmd_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + cmd_ = s; + return s; + } + } + /** + * string cmd = 2; + */ + public com.google.protobuf.ByteString + getCmdBytes() { + Object ref = cmd_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + cmd_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int PARAMS_FIELD_NUMBER = 3; + private volatile Object params_; + /** + * string params = 3; + */ + public String getParams() { + Object ref = params_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + params_ = s; + return s; + } + } + /** + * string params = 3; + */ + public com.google.protobuf.ByteString + getParamsBytes() { + Object ref = params_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + params_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int PARAMMAP_FIELD_NUMBER = 4; + private static final class ParamMapDefaultEntryHolder { + static final com.google.protobuf.MapEntry< + String, String> defaultEntry = + com.google.protobuf.MapEntry + .newDefaultInstance( + Service.internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_ParamMapEntry_descriptor, + com.google.protobuf.WireFormat.FieldType.STRING, + "", + com.google.protobuf.WireFormat.FieldType.STRING, + ""); + } + private com.google.protobuf.MapField< + String, String> paramMap_; + private com.google.protobuf.MapField + internalGetParamMap() { + if (paramMap_ == null) { + return com.google.protobuf.MapField.emptyMapField( + ParamMapDefaultEntryHolder.defaultEntry); + } + return paramMap_; + } + + public int getParamMapCount() { + return internalGetParamMap().getMap().size(); + } + /** + * map<string, string> paramMap = 4; + */ + + public boolean containsParamMap( + String key) { + if (key == null) { throw new NullPointerException(); } + return internalGetParamMap().getMap().containsKey(key); + } + /** + * Use {@link #getParamMapMap()} instead. + */ + @Deprecated + public java.util.Map getParamMap() { + return getParamMapMap(); + } + /** + * map<string, string> paramMap = 4; + */ + + public java.util.Map getParamMapMap() { + return internalGetParamMap().getMap(); + } + /** + * map<string, string> paramMap = 4; + */ + + public String getParamMapOrDefault( + String key, + String defaultValue) { + if (key == null) { throw new NullPointerException(); } + java.util.Map map = + internalGetParamMap().getMap(); + return map.containsKey(key) ? map.get(key) : defaultValue; + } + /** + * map<string, string> paramMap = 4; + */ + + public String getParamMapOrThrow( + String key) { + if (key == null) { throw new NullPointerException(); } + java.util.Map map = + internalGetParamMap().getMap(); + if (!map.containsKey(key)) { + throw new IllegalArgumentException(); + } + return map.get(key); + } + + private byte memoizedIsInitialized = -1; + @Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!getIdBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, id_); + } + if (!getCmdBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, cmd_); + } + if (!getParamsBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 3, params_); + } + com.google.protobuf.GeneratedMessageV3 + .serializeStringMapTo( + output, + internalGetParamMap(), + ParamMapDefaultEntryHolder.defaultEntry, + 4); + unknownFields.writeTo(output); + } + + @Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!getIdBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, id_); + } + if (!getCmdBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, cmd_); + } + if (!getParamsBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, params_); + } + for (java.util.Map.Entry entry + : internalGetParamMap().getMap().entrySet()) { + com.google.protobuf.MapEntry + paramMap__ = ParamMapDefaultEntryHolder.defaultEntry.newBuilderForType() + .setKey(entry.getKey()) + .setValue(entry.getValue()) + .build(); + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(4, paramMap__); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof UltramanRequest)) { + return super.equals(obj); + } + UltramanRequest other = (UltramanRequest) obj; + + boolean result = true; + result = result && getId() + .equals(other.getId()); + result = result && getCmd() + .equals(other.getCmd()); + result = result && getParams() + .equals(other.getParams()); + result = result && internalGetParamMap().equals( + other.internalGetParamMap()); + result = result && unknownFields.equals(other.unknownFields); + return result; + } + + @Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + ID_FIELD_NUMBER; + hash = (53 * hash) + getId().hashCode(); + hash = (37 * hash) + CMD_FIELD_NUMBER; + hash = (53 * hash) + getCmd().hashCode(); + hash = (37 * hash) + PARAMS_FIELD_NUMBER; + hash = (53 * hash) + getParams().hashCode(); + if (!internalGetParamMap().getMap().isEmpty()) { + hash = (37 * hash) + PARAMMAP_FIELD_NUMBER; + hash = (53 * hash) + internalGetParamMap().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static UltramanRequest parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static UltramanRequest parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static UltramanRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static UltramanRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static UltramanRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static UltramanRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static UltramanRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static UltramanRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static UltramanRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static UltramanRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static UltramanRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static UltramanRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(UltramanRequest prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @Override + protected Builder newBuilderForType( + BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code com.xiaomi.mone.ultraman.grpc.UltramanRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:com.xiaomi.mone.ultraman.grpc.UltramanRequest) + UltramanRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return Service.internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_descriptor; + } + + @SuppressWarnings({"rawtypes"}) + protected com.google.protobuf.MapField internalGetMapField( + int number) { + switch (number) { + case 4: + return internalGetParamMap(); + default: + throw new RuntimeException( + "Invalid map field number: " + number); + } + } + @SuppressWarnings({"rawtypes"}) + protected com.google.protobuf.MapField internalGetMutableMapField( + int number) { + switch (number) { + case 4: + return internalGetMutableParamMap(); + default: + throw new RuntimeException( + "Invalid map field number: " + number); + } + } + @Override + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return Service.internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + UltramanRequest.class, Builder.class); + } + + // Construct using com.xiaomi.mone.ultraman.grpc.UltramanRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @Override + public Builder clear() { + super.clear(); + id_ = ""; + + cmd_ = ""; + + params_ = ""; + + internalGetMutableParamMap().clear(); + return this; + } + + @Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return Service.internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_descriptor; + } + + @Override + public UltramanRequest getDefaultInstanceForType() { + return UltramanRequest.getDefaultInstance(); + } + + @Override + public UltramanRequest build() { + UltramanRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @Override + public UltramanRequest buildPartial() { + UltramanRequest result = new UltramanRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + result.id_ = id_; + result.cmd_ = cmd_; + result.params_ = params_; + result.paramMap_ = internalGetParamMap(); + result.paramMap_.makeImmutable(); + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @Override + public Builder clone() { + return (Builder) super.clone(); + } + @Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.setField(field, value); + } + @Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return (Builder) super.clearField(field); + } + @Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return (Builder) super.clearOneof(oneof); + } + @Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, Object value) { + return (Builder) super.setRepeatedField(field, index, value); + } + @Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.addRepeatedField(field, value); + } + @Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof UltramanRequest) { + return mergeFrom((UltramanRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(UltramanRequest other) { + if (other == UltramanRequest.getDefaultInstance()) return this; + if (!other.getId().isEmpty()) { + id_ = other.id_; + onChanged(); + } + if (!other.getCmd().isEmpty()) { + cmd_ = other.cmd_; + onChanged(); + } + if (!other.getParams().isEmpty()) { + params_ = other.params_; + onChanged(); + } + internalGetMutableParamMap().mergeFrom( + other.internalGetParamMap()); + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @Override + public final boolean isInitialized() { + return true; + } + + @Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + UltramanRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (UltramanRequest) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private Object id_ = ""; + /** + * string id = 1; + */ + public String getId() { + Object ref = id_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + id_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string id = 1; + */ + public com.google.protobuf.ByteString + getIdBytes() { + Object ref = id_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + id_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string id = 1; + */ + public Builder setId( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + id_ = value; + onChanged(); + return this; + } + /** + * string id = 1; + */ + public Builder clearId() { + + id_ = getDefaultInstance().getId(); + onChanged(); + return this; + } + /** + * string id = 1; + */ + public Builder setIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + id_ = value; + onChanged(); + return this; + } + + private Object cmd_ = ""; + /** + * string cmd = 2; + */ + public String getCmd() { + Object ref = cmd_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + cmd_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string cmd = 2; + */ + public com.google.protobuf.ByteString + getCmdBytes() { + Object ref = cmd_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + cmd_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string cmd = 2; + */ + public Builder setCmd( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + cmd_ = value; + onChanged(); + return this; + } + /** + * string cmd = 2; + */ + public Builder clearCmd() { + + cmd_ = getDefaultInstance().getCmd(); + onChanged(); + return this; + } + /** + * string cmd = 2; + */ + public Builder setCmdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + cmd_ = value; + onChanged(); + return this; + } + + private Object params_ = ""; + /** + * string params = 3; + */ + public String getParams() { + Object ref = params_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + params_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string params = 3; + */ + public com.google.protobuf.ByteString + getParamsBytes() { + Object ref = params_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + params_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string params = 3; + */ + public Builder setParams( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + params_ = value; + onChanged(); + return this; + } + /** + * string params = 3; + */ + public Builder clearParams() { + + params_ = getDefaultInstance().getParams(); + onChanged(); + return this; + } + /** + * string params = 3; + */ + public Builder setParamsBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + params_ = value; + onChanged(); + return this; + } + + private com.google.protobuf.MapField< + String, String> paramMap_; + private com.google.protobuf.MapField + internalGetParamMap() { + if (paramMap_ == null) { + return com.google.protobuf.MapField.emptyMapField( + ParamMapDefaultEntryHolder.defaultEntry); + } + return paramMap_; + } + private com.google.protobuf.MapField + internalGetMutableParamMap() { + onChanged();; + if (paramMap_ == null) { + paramMap_ = com.google.protobuf.MapField.newMapField( + ParamMapDefaultEntryHolder.defaultEntry); + } + if (!paramMap_.isMutable()) { + paramMap_ = paramMap_.copy(); + } + return paramMap_; + } + + public int getParamMapCount() { + return internalGetParamMap().getMap().size(); + } + /** + * map<string, string> paramMap = 4; + */ + + public boolean containsParamMap( + String key) { + if (key == null) { throw new NullPointerException(); } + return internalGetParamMap().getMap().containsKey(key); + } + /** + * Use {@link #getParamMapMap()} instead. + */ + @Deprecated + public java.util.Map getParamMap() { + return getParamMapMap(); + } + /** + * map<string, string> paramMap = 4; + */ + + public java.util.Map getParamMapMap() { + return internalGetParamMap().getMap(); + } + /** + * map<string, string> paramMap = 4; + */ + + public String getParamMapOrDefault( + String key, + String defaultValue) { + if (key == null) { throw new NullPointerException(); } + java.util.Map map = + internalGetParamMap().getMap(); + return map.containsKey(key) ? map.get(key) : defaultValue; + } + /** + * map<string, string> paramMap = 4; + */ + + public String getParamMapOrThrow( + String key) { + if (key == null) { throw new NullPointerException(); } + java.util.Map map = + internalGetParamMap().getMap(); + if (!map.containsKey(key)) { + throw new IllegalArgumentException(); + } + return map.get(key); + } + + public Builder clearParamMap() { + internalGetMutableParamMap().getMutableMap() + .clear(); + return this; + } + /** + * map<string, string> paramMap = 4; + */ + + public Builder removeParamMap( + String key) { + if (key == null) { throw new NullPointerException(); } + internalGetMutableParamMap().getMutableMap() + .remove(key); + return this; + } + /** + * Use alternate mutation accessors instead. + */ + @Deprecated + public java.util.Map + getMutableParamMap() { + return internalGetMutableParamMap().getMutableMap(); + } + /** + * map<string, string> paramMap = 4; + */ + public Builder putParamMap( + String key, + String value) { + if (key == null) { throw new NullPointerException(); } + if (value == null) { throw new NullPointerException(); } + internalGetMutableParamMap().getMutableMap() + .put(key, value); + return this; + } + /** + * map<string, string> paramMap = 4; + */ + + public Builder putAllParamMap( + java.util.Map values) { + internalGetMutableParamMap().getMutableMap() + .putAll(values); + return this; + } + @Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFieldsProto3(unknownFields); + } + + @Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:com.xiaomi.mone.ultraman.grpc.UltramanRequest) + } + + // @@protoc_insertion_point(class_scope:com.xiaomi.mone.ultraman.grpc.UltramanRequest) + private static final UltramanRequest DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new UltramanRequest(); + } + + public static UltramanRequest getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @Override + public UltramanRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new UltramanRequest(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @Override + public UltramanRequest getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanRequestOrBuilder.java b/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanRequestOrBuilder.java new file mode 100644 index 000000000..521ac7441 --- /dev/null +++ b/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanRequestOrBuilder.java @@ -0,0 +1,73 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: service.proto + +package run.mone.mone.ultraman.grpc; + +public interface UltramanRequestOrBuilder extends + // @@protoc_insertion_point(interface_extends:com.xiaomi.mone.ultraman.grpc.UltramanRequest) + com.google.protobuf.MessageOrBuilder { + + /** + * string id = 1; + */ + String getId(); + /** + * string id = 1; + */ + com.google.protobuf.ByteString + getIdBytes(); + + /** + * string cmd = 2; + */ + String getCmd(); + /** + * string cmd = 2; + */ + com.google.protobuf.ByteString + getCmdBytes(); + + /** + * string params = 3; + */ + String getParams(); + /** + * string params = 3; + */ + com.google.protobuf.ByteString + getParamsBytes(); + + /** + * map<string, string> paramMap = 4; + */ + int getParamMapCount(); + /** + * map<string, string> paramMap = 4; + */ + boolean containsParamMap( + String key); + /** + * Use {@link #getParamMapMap()} instead. + */ + @Deprecated + java.util.Map + getParamMap(); + /** + * map<string, string> paramMap = 4; + */ + java.util.Map + getParamMapMap(); + /** + * map<string, string> paramMap = 4; + */ + + String getParamMapOrDefault( + String key, + String defaultValue); + /** + * map<string, string> paramMap = 4; + */ + + String getParamMapOrThrow( + String key); +} diff --git a/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanResponse.java b/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanResponse.java new file mode 100644 index 000000000..003facbf1 --- /dev/null +++ b/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanResponse.java @@ -0,0 +1,1131 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: service.proto + +package run.mone.mone.ultraman.grpc; + +/** + * Protobuf type {@code com.xiaomi.mone.ultraman.grpc.UltramanResponse} + */ +public final class UltramanResponse extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:com.xiaomi.mone.ultraman.grpc.UltramanResponse) + UltramanResponseOrBuilder { +private static final long serialVersionUID = 0L; + // Use UltramanResponse.newBuilder() to construct. + private UltramanResponse(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private UltramanResponse() { + id_ = ""; + data_ = ""; + code_ = 0; + cmd_ = ""; + } + + @Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private UltramanResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + String s = input.readStringRequireUtf8(); + + id_ = s; + break; + } + case 18: { + String s = input.readStringRequireUtf8(); + + data_ = s; + break; + } + case 24: { + + code_ = input.readInt32(); + break; + } + case 34: { + String s = input.readStringRequireUtf8(); + + cmd_ = s; + break; + } + case 42: { + if (!((mutable_bitField0_ & 0x00000010) == 0x00000010)) { + resMap_ = com.google.protobuf.MapField.newMapField( + ResMapDefaultEntryHolder.defaultEntry); + mutable_bitField0_ |= 0x00000010; + } + com.google.protobuf.MapEntry + resMap__ = input.readMessage( + ResMapDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry); + resMap_.getMutableMap().put( + resMap__.getKey(), resMap__.getValue()); + break; + } + default: { + if (!parseUnknownFieldProto3( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return Service.internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_descriptor; + } + + @SuppressWarnings({"rawtypes"}) + @Override + protected com.google.protobuf.MapField internalGetMapField( + int number) { + switch (number) { + case 5: + return internalGetResMap(); + default: + throw new RuntimeException( + "Invalid map field number: " + number); + } + } + @Override + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return Service.internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + UltramanResponse.class, Builder.class); + } + + private int bitField0_; + public static final int ID_FIELD_NUMBER = 1; + private volatile Object id_; + /** + * string id = 1; + */ + public String getId() { + Object ref = id_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + id_ = s; + return s; + } + } + /** + * string id = 1; + */ + public com.google.protobuf.ByteString + getIdBytes() { + Object ref = id_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + id_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int DATA_FIELD_NUMBER = 2; + private volatile Object data_; + /** + * string data = 2; + */ + public String getData() { + Object ref = data_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + data_ = s; + return s; + } + } + /** + * string data = 2; + */ + public com.google.protobuf.ByteString + getDataBytes() { + Object ref = data_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + data_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int CODE_FIELD_NUMBER = 3; + private int code_; + /** + * int32 code = 3; + */ + public int getCode() { + return code_; + } + + public static final int CMD_FIELD_NUMBER = 4; + private volatile Object cmd_; + /** + * string cmd = 4; + */ + public String getCmd() { + Object ref = cmd_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + cmd_ = s; + return s; + } + } + /** + * string cmd = 4; + */ + public com.google.protobuf.ByteString + getCmdBytes() { + Object ref = cmd_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + cmd_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int RESMAP_FIELD_NUMBER = 5; + private static final class ResMapDefaultEntryHolder { + static final com.google.protobuf.MapEntry< + String, String> defaultEntry = + com.google.protobuf.MapEntry + .newDefaultInstance( + Service.internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_ResMapEntry_descriptor, + com.google.protobuf.WireFormat.FieldType.STRING, + "", + com.google.protobuf.WireFormat.FieldType.STRING, + ""); + } + private com.google.protobuf.MapField< + String, String> resMap_; + private com.google.protobuf.MapField + internalGetResMap() { + if (resMap_ == null) { + return com.google.protobuf.MapField.emptyMapField( + ResMapDefaultEntryHolder.defaultEntry); + } + return resMap_; + } + + public int getResMapCount() { + return internalGetResMap().getMap().size(); + } + /** + * map<string, string> resMap = 5; + */ + + public boolean containsResMap( + String key) { + if (key == null) { throw new NullPointerException(); } + return internalGetResMap().getMap().containsKey(key); + } + /** + * Use {@link #getResMapMap()} instead. + */ + @Deprecated + public java.util.Map getResMap() { + return getResMapMap(); + } + /** + * map<string, string> resMap = 5; + */ + + public java.util.Map getResMapMap() { + return internalGetResMap().getMap(); + } + /** + * map<string, string> resMap = 5; + */ + + public String getResMapOrDefault( + String key, + String defaultValue) { + if (key == null) { throw new NullPointerException(); } + java.util.Map map = + internalGetResMap().getMap(); + return map.containsKey(key) ? map.get(key) : defaultValue; + } + /** + * map<string, string> resMap = 5; + */ + + public String getResMapOrThrow( + String key) { + if (key == null) { throw new NullPointerException(); } + java.util.Map map = + internalGetResMap().getMap(); + if (!map.containsKey(key)) { + throw new IllegalArgumentException(); + } + return map.get(key); + } + + private byte memoizedIsInitialized = -1; + @Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!getIdBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, id_); + } + if (!getDataBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, data_); + } + if (code_ != 0) { + output.writeInt32(3, code_); + } + if (!getCmdBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 4, cmd_); + } + com.google.protobuf.GeneratedMessageV3 + .serializeStringMapTo( + output, + internalGetResMap(), + ResMapDefaultEntryHolder.defaultEntry, + 5); + unknownFields.writeTo(output); + } + + @Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!getIdBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, id_); + } + if (!getDataBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, data_); + } + if (code_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(3, code_); + } + if (!getCmdBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, cmd_); + } + for (java.util.Map.Entry entry + : internalGetResMap().getMap().entrySet()) { + com.google.protobuf.MapEntry + resMap__ = ResMapDefaultEntryHolder.defaultEntry.newBuilderForType() + .setKey(entry.getKey()) + .setValue(entry.getValue()) + .build(); + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(5, resMap__); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof UltramanResponse)) { + return super.equals(obj); + } + UltramanResponse other = (UltramanResponse) obj; + + boolean result = true; + result = result && getId() + .equals(other.getId()); + result = result && getData() + .equals(other.getData()); + result = result && (getCode() + == other.getCode()); + result = result && getCmd() + .equals(other.getCmd()); + result = result && internalGetResMap().equals( + other.internalGetResMap()); + result = result && unknownFields.equals(other.unknownFields); + return result; + } + + @Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + ID_FIELD_NUMBER; + hash = (53 * hash) + getId().hashCode(); + hash = (37 * hash) + DATA_FIELD_NUMBER; + hash = (53 * hash) + getData().hashCode(); + hash = (37 * hash) + CODE_FIELD_NUMBER; + hash = (53 * hash) + getCode(); + hash = (37 * hash) + CMD_FIELD_NUMBER; + hash = (53 * hash) + getCmd().hashCode(); + if (!internalGetResMap().getMap().isEmpty()) { + hash = (37 * hash) + RESMAP_FIELD_NUMBER; + hash = (53 * hash) + internalGetResMap().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static UltramanResponse parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static UltramanResponse parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static UltramanResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static UltramanResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static UltramanResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static UltramanResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static UltramanResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static UltramanResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static UltramanResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static UltramanResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static UltramanResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static UltramanResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(UltramanResponse prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @Override + protected Builder newBuilderForType( + BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code com.xiaomi.mone.ultraman.grpc.UltramanResponse} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:com.xiaomi.mone.ultraman.grpc.UltramanResponse) + UltramanResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return Service.internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_descriptor; + } + + @SuppressWarnings({"rawtypes"}) + protected com.google.protobuf.MapField internalGetMapField( + int number) { + switch (number) { + case 5: + return internalGetResMap(); + default: + throw new RuntimeException( + "Invalid map field number: " + number); + } + } + @SuppressWarnings({"rawtypes"}) + protected com.google.protobuf.MapField internalGetMutableMapField( + int number) { + switch (number) { + case 5: + return internalGetMutableResMap(); + default: + throw new RuntimeException( + "Invalid map field number: " + number); + } + } + @Override + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return Service.internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + UltramanResponse.class, Builder.class); + } + + // Construct using com.xiaomi.mone.ultraman.grpc.UltramanResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @Override + public Builder clear() { + super.clear(); + id_ = ""; + + data_ = ""; + + code_ = 0; + + cmd_ = ""; + + internalGetMutableResMap().clear(); + return this; + } + + @Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return Service.internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_descriptor; + } + + @Override + public UltramanResponse getDefaultInstanceForType() { + return UltramanResponse.getDefaultInstance(); + } + + @Override + public UltramanResponse build() { + UltramanResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @Override + public UltramanResponse buildPartial() { + UltramanResponse result = new UltramanResponse(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + result.id_ = id_; + result.data_ = data_; + result.code_ = code_; + result.cmd_ = cmd_; + result.resMap_ = internalGetResMap(); + result.resMap_.makeImmutable(); + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @Override + public Builder clone() { + return (Builder) super.clone(); + } + @Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.setField(field, value); + } + @Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return (Builder) super.clearField(field); + } + @Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return (Builder) super.clearOneof(oneof); + } + @Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, Object value) { + return (Builder) super.setRepeatedField(field, index, value); + } + @Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.addRepeatedField(field, value); + } + @Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof UltramanResponse) { + return mergeFrom((UltramanResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(UltramanResponse other) { + if (other == UltramanResponse.getDefaultInstance()) return this; + if (!other.getId().isEmpty()) { + id_ = other.id_; + onChanged(); + } + if (!other.getData().isEmpty()) { + data_ = other.data_; + onChanged(); + } + if (other.getCode() != 0) { + setCode(other.getCode()); + } + if (!other.getCmd().isEmpty()) { + cmd_ = other.cmd_; + onChanged(); + } + internalGetMutableResMap().mergeFrom( + other.internalGetResMap()); + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @Override + public final boolean isInitialized() { + return true; + } + + @Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + UltramanResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (UltramanResponse) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private Object id_ = ""; + /** + * string id = 1; + */ + public String getId() { + Object ref = id_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + id_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string id = 1; + */ + public com.google.protobuf.ByteString + getIdBytes() { + Object ref = id_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + id_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string id = 1; + */ + public Builder setId( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + id_ = value; + onChanged(); + return this; + } + /** + * string id = 1; + */ + public Builder clearId() { + + id_ = getDefaultInstance().getId(); + onChanged(); + return this; + } + /** + * string id = 1; + */ + public Builder setIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + id_ = value; + onChanged(); + return this; + } + + private Object data_ = ""; + /** + * string data = 2; + */ + public String getData() { + Object ref = data_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + data_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string data = 2; + */ + public com.google.protobuf.ByteString + getDataBytes() { + Object ref = data_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + data_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string data = 2; + */ + public Builder setData( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + data_ = value; + onChanged(); + return this; + } + /** + * string data = 2; + */ + public Builder clearData() { + + data_ = getDefaultInstance().getData(); + onChanged(); + return this; + } + /** + * string data = 2; + */ + public Builder setDataBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + data_ = value; + onChanged(); + return this; + } + + private int code_ ; + /** + * int32 code = 3; + */ + public int getCode() { + return code_; + } + /** + * int32 code = 3; + */ + public Builder setCode(int value) { + + code_ = value; + onChanged(); + return this; + } + /** + * int32 code = 3; + */ + public Builder clearCode() { + + code_ = 0; + onChanged(); + return this; + } + + private Object cmd_ = ""; + /** + * string cmd = 4; + */ + public String getCmd() { + Object ref = cmd_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + cmd_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string cmd = 4; + */ + public com.google.protobuf.ByteString + getCmdBytes() { + Object ref = cmd_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + cmd_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string cmd = 4; + */ + public Builder setCmd( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + cmd_ = value; + onChanged(); + return this; + } + /** + * string cmd = 4; + */ + public Builder clearCmd() { + + cmd_ = getDefaultInstance().getCmd(); + onChanged(); + return this; + } + /** + * string cmd = 4; + */ + public Builder setCmdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + cmd_ = value; + onChanged(); + return this; + } + + private com.google.protobuf.MapField< + String, String> resMap_; + private com.google.protobuf.MapField + internalGetResMap() { + if (resMap_ == null) { + return com.google.protobuf.MapField.emptyMapField( + ResMapDefaultEntryHolder.defaultEntry); + } + return resMap_; + } + private com.google.protobuf.MapField + internalGetMutableResMap() { + onChanged();; + if (resMap_ == null) { + resMap_ = com.google.protobuf.MapField.newMapField( + ResMapDefaultEntryHolder.defaultEntry); + } + if (!resMap_.isMutable()) { + resMap_ = resMap_.copy(); + } + return resMap_; + } + + public int getResMapCount() { + return internalGetResMap().getMap().size(); + } + /** + * map<string, string> resMap = 5; + */ + + public boolean containsResMap( + String key) { + if (key == null) { throw new NullPointerException(); } + return internalGetResMap().getMap().containsKey(key); + } + /** + * Use {@link #getResMapMap()} instead. + */ + @Deprecated + public java.util.Map getResMap() { + return getResMapMap(); + } + /** + * map<string, string> resMap = 5; + */ + + public java.util.Map getResMapMap() { + return internalGetResMap().getMap(); + } + /** + * map<string, string> resMap = 5; + */ + + public String getResMapOrDefault( + String key, + String defaultValue) { + if (key == null) { throw new NullPointerException(); } + java.util.Map map = + internalGetResMap().getMap(); + return map.containsKey(key) ? map.get(key) : defaultValue; + } + /** + * map<string, string> resMap = 5; + */ + + public String getResMapOrThrow( + String key) { + if (key == null) { throw new NullPointerException(); } + java.util.Map map = + internalGetResMap().getMap(); + if (!map.containsKey(key)) { + throw new IllegalArgumentException(); + } + return map.get(key); + } + + public Builder clearResMap() { + internalGetMutableResMap().getMutableMap() + .clear(); + return this; + } + /** + * map<string, string> resMap = 5; + */ + + public Builder removeResMap( + String key) { + if (key == null) { throw new NullPointerException(); } + internalGetMutableResMap().getMutableMap() + .remove(key); + return this; + } + /** + * Use alternate mutation accessors instead. + */ + @Deprecated + public java.util.Map + getMutableResMap() { + return internalGetMutableResMap().getMutableMap(); + } + /** + * map<string, string> resMap = 5; + */ + public Builder putResMap( + String key, + String value) { + if (key == null) { throw new NullPointerException(); } + if (value == null) { throw new NullPointerException(); } + internalGetMutableResMap().getMutableMap() + .put(key, value); + return this; + } + /** + * map<string, string> resMap = 5; + */ + + public Builder putAllResMap( + java.util.Map values) { + internalGetMutableResMap().getMutableMap() + .putAll(values); + return this; + } + @Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFieldsProto3(unknownFields); + } + + @Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:com.xiaomi.mone.ultraman.grpc.UltramanResponse) + } + + // @@protoc_insertion_point(class_scope:com.xiaomi.mone.ultraman.grpc.UltramanResponse) + private static final UltramanResponse DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new UltramanResponse(); + } + + public static UltramanResponse getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @Override + public UltramanResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new UltramanResponse(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @Override + public UltramanResponse getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanResponseOrBuilder.java b/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanResponseOrBuilder.java new file mode 100644 index 000000000..0c098e04c --- /dev/null +++ b/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanResponseOrBuilder.java @@ -0,0 +1,78 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: service.proto + +package run.mone.mone.ultraman.grpc; + +public interface UltramanResponseOrBuilder extends + // @@protoc_insertion_point(interface_extends:com.xiaomi.mone.ultraman.grpc.UltramanResponse) + com.google.protobuf.MessageOrBuilder { + + /** + * string id = 1; + */ + String getId(); + /** + * string id = 1; + */ + com.google.protobuf.ByteString + getIdBytes(); + + /** + * string data = 2; + */ + String getData(); + /** + * string data = 2; + */ + com.google.protobuf.ByteString + getDataBytes(); + + /** + * int32 code = 3; + */ + int getCode(); + + /** + * string cmd = 4; + */ + String getCmd(); + /** + * string cmd = 4; + */ + com.google.protobuf.ByteString + getCmdBytes(); + + /** + * map<string, string> resMap = 5; + */ + int getResMapCount(); + /** + * map<string, string> resMap = 5; + */ + boolean containsResMap( + String key); + /** + * Use {@link #getResMapMap()} instead. + */ + @Deprecated + java.util.Map + getResMap(); + /** + * map<string, string> resMap = 5; + */ + java.util.Map + getResMapMap(); + /** + * map<string, string> resMap = 5; + */ + + String getResMapOrDefault( + String key, + String defaultValue); + /** + * map<string, string> resMap = 5; + */ + + String getResMapOrThrow( + String key); +} diff --git a/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanServiceGrpc.java b/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanServiceGrpc.java new file mode 100644 index 000000000..c46af6dc9 --- /dev/null +++ b/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanServiceGrpc.java @@ -0,0 +1,401 @@ +package run.mone.mone.ultraman.grpc; + +import static io.grpc.MethodDescriptor.generateFullMethodName; +import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall; +import static io.grpc.stub.ClientCalls.asyncClientStreamingCall; +import static io.grpc.stub.ClientCalls.asyncUnaryCall; +import static io.grpc.stub.ClientCalls.blockingUnaryCall; +import static io.grpc.stub.ClientCalls.futureUnaryCall; +import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall; +import static io.grpc.stub.ServerCalls.asyncClientStreamingCall; +import static io.grpc.stub.ServerCalls.asyncUnaryCall; +import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall; +import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall; + +/** + */ +@javax.annotation.Generated( + value = "by gRPC proto compiler (version 1.34.1)", + comments = "Source: service.proto") +public final class UltramanServiceGrpc { + + private UltramanServiceGrpc() {} + + public static final String SERVICE_NAME = "com.xiaomi.mone.ultraman.grpc.UltramanService"; + + // Static method descriptors that strictly reflect the proto. + private static volatile io.grpc.MethodDescriptor getHelloMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "hello", + requestType = UltramanRequest.class, + responseType = UltramanResponse.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getHelloMethod() { + io.grpc.MethodDescriptor getHelloMethod; + if ((getHelloMethod = UltramanServiceGrpc.getHelloMethod) == null) { + synchronized (UltramanServiceGrpc.class) { + if ((getHelloMethod = UltramanServiceGrpc.getHelloMethod) == null) { + UltramanServiceGrpc.getHelloMethod = getHelloMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "hello")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + UltramanRequest.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + UltramanResponse.getDefaultInstance())) + .setSchemaDescriptor(new UltramanServiceMethodDescriptorSupplier("hello")) + .build(); + } + } + } + return getHelloMethod; + } + + private static volatile io.grpc.MethodDescriptor getStreamMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "stream", + requestType = UltramanRequest.class, + responseType = UltramanResponse.class, + methodType = io.grpc.MethodDescriptor.MethodType.BIDI_STREAMING) + public static io.grpc.MethodDescriptor getStreamMethod() { + io.grpc.MethodDescriptor getStreamMethod; + if ((getStreamMethod = UltramanServiceGrpc.getStreamMethod) == null) { + synchronized (UltramanServiceGrpc.class) { + if ((getStreamMethod = UltramanServiceGrpc.getStreamMethod) == null) { + UltramanServiceGrpc.getStreamMethod = getStreamMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.BIDI_STREAMING) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "stream")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + UltramanRequest.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + UltramanResponse.getDefaultInstance())) + .setSchemaDescriptor(new UltramanServiceMethodDescriptorSupplier("stream")) + .build(); + } + } + } + return getStreamMethod; + } + + private static volatile io.grpc.MethodDescriptor getCallMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "call", + requestType = UltramanRequest.class, + responseType = UltramanResponse.class, + methodType = io.grpc.MethodDescriptor.MethodType.CLIENT_STREAMING) + public static io.grpc.MethodDescriptor getCallMethod() { + io.grpc.MethodDescriptor getCallMethod; + if ((getCallMethod = UltramanServiceGrpc.getCallMethod) == null) { + synchronized (UltramanServiceGrpc.class) { + if ((getCallMethod = UltramanServiceGrpc.getCallMethod) == null) { + UltramanServiceGrpc.getCallMethod = getCallMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.CLIENT_STREAMING) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "call")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + UltramanRequest.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + UltramanResponse.getDefaultInstance())) + .setSchemaDescriptor(new UltramanServiceMethodDescriptorSupplier("call")) + .build(); + } + } + } + return getCallMethod; + } + + /** + * Creates a new async stub that supports all call types for the service + */ + public static UltramanServiceStub newStub(io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @Override + public UltramanServiceStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new UltramanServiceStub(channel, callOptions); + } + }; + return UltramanServiceStub.newStub(factory, channel); + } + + /** + * Creates a new blocking-style stub that supports unary and streaming output calls on the service + */ + public static UltramanServiceBlockingStub newBlockingStub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @Override + public UltramanServiceBlockingStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new UltramanServiceBlockingStub(channel, callOptions); + } + }; + return UltramanServiceBlockingStub.newStub(factory, channel); + } + + /** + * Creates a new ListenableFuture-style stub that supports unary calls on the service + */ + public static UltramanServiceFutureStub newFutureStub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @Override + public UltramanServiceFutureStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new UltramanServiceFutureStub(channel, callOptions); + } + }; + return UltramanServiceFutureStub.newStub(factory, channel); + } + + /** + */ + public static abstract class UltramanServiceImplBase implements io.grpc.BindableService { + + /** + */ + public void hello(UltramanRequest request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnimplementedUnaryCall(getHelloMethod(), responseObserver); + } + + /** + */ + public io.grpc.stub.StreamObserver stream( + io.grpc.stub.StreamObserver responseObserver) { + return asyncUnimplementedStreamingCall(getStreamMethod(), responseObserver); + } + + /** + */ + public io.grpc.stub.StreamObserver call( + io.grpc.stub.StreamObserver responseObserver) { + return asyncUnimplementedStreamingCall(getCallMethod(), responseObserver); + } + + @Override public final io.grpc.ServerServiceDefinition bindService() { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + getHelloMethod(), + asyncUnaryCall( + new MethodHandlers< + UltramanRequest, + UltramanResponse>( + this, METHODID_HELLO))) + .addMethod( + getStreamMethod(), + asyncBidiStreamingCall( + new MethodHandlers< + UltramanRequest, + UltramanResponse>( + this, METHODID_STREAM))) + .addMethod( + getCallMethod(), + asyncClientStreamingCall( + new MethodHandlers< + UltramanRequest, + UltramanResponse>( + this, METHODID_CALL))) + .build(); + } + } + + /** + */ + public static final class UltramanServiceStub extends io.grpc.stub.AbstractAsyncStub { + private UltramanServiceStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @Override + protected UltramanServiceStub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new UltramanServiceStub(channel, callOptions); + } + + /** + */ + public void hello(UltramanRequest request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnaryCall( + getChannel().newCall(getHelloMethod(), getCallOptions()), request, responseObserver); + } + + /** + */ + public io.grpc.stub.StreamObserver stream( + io.grpc.stub.StreamObserver responseObserver) { + return asyncBidiStreamingCall( + getChannel().newCall(getStreamMethod(), getCallOptions()), responseObserver); + } + + /** + */ + public io.grpc.stub.StreamObserver call( + io.grpc.stub.StreamObserver responseObserver) { + return asyncClientStreamingCall( + getChannel().newCall(getCallMethod(), getCallOptions()), responseObserver); + } + } + + /** + */ + public static final class UltramanServiceBlockingStub extends io.grpc.stub.AbstractBlockingStub { + private UltramanServiceBlockingStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @Override + protected UltramanServiceBlockingStub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new UltramanServiceBlockingStub(channel, callOptions); + } + + /** + */ + public UltramanResponse hello(UltramanRequest request) { + return blockingUnaryCall( + getChannel(), getHelloMethod(), getCallOptions(), request); + } + } + + /** + */ + public static final class UltramanServiceFutureStub extends io.grpc.stub.AbstractFutureStub { + private UltramanServiceFutureStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @Override + protected UltramanServiceFutureStub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new UltramanServiceFutureStub(channel, callOptions); + } + + /** + */ + public com.google.common.util.concurrent.ListenableFuture hello( + UltramanRequest request) { + return futureUnaryCall( + getChannel().newCall(getHelloMethod(), getCallOptions()), request); + } + } + + private static final int METHODID_HELLO = 0; + private static final int METHODID_STREAM = 1; + private static final int METHODID_CALL = 2; + + private static final class MethodHandlers implements + io.grpc.stub.ServerCalls.UnaryMethod, + io.grpc.stub.ServerCalls.ServerStreamingMethod, + io.grpc.stub.ServerCalls.ClientStreamingMethod, + io.grpc.stub.ServerCalls.BidiStreamingMethod { + private final UltramanServiceImplBase serviceImpl; + private final int methodId; + + MethodHandlers(UltramanServiceImplBase serviceImpl, int methodId) { + this.serviceImpl = serviceImpl; + this.methodId = methodId; + } + + @Override + @SuppressWarnings("unchecked") + public void invoke(Req request, io.grpc.stub.StreamObserver responseObserver) { + switch (methodId) { + case METHODID_HELLO: + serviceImpl.hello((UltramanRequest) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + default: + throw new AssertionError(); + } + } + + @Override + @SuppressWarnings("unchecked") + public io.grpc.stub.StreamObserver invoke( + io.grpc.stub.StreamObserver responseObserver) { + switch (methodId) { + case METHODID_STREAM: + return (io.grpc.stub.StreamObserver) serviceImpl.stream( + (io.grpc.stub.StreamObserver) responseObserver); + case METHODID_CALL: + return (io.grpc.stub.StreamObserver) serviceImpl.call( + (io.grpc.stub.StreamObserver) responseObserver); + default: + throw new AssertionError(); + } + } + } + + private static abstract class UltramanServiceBaseDescriptorSupplier + implements io.grpc.protobuf.ProtoFileDescriptorSupplier, io.grpc.protobuf.ProtoServiceDescriptorSupplier { + UltramanServiceBaseDescriptorSupplier() {} + + @Override + public com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() { + return Service.getDescriptor(); + } + + @Override + public com.google.protobuf.Descriptors.ServiceDescriptor getServiceDescriptor() { + return getFileDescriptor().findServiceByName("UltramanService"); + } + } + + private static final class UltramanServiceFileDescriptorSupplier + extends UltramanServiceBaseDescriptorSupplier { + UltramanServiceFileDescriptorSupplier() {} + } + + private static final class UltramanServiceMethodDescriptorSupplier + extends UltramanServiceBaseDescriptorSupplier + implements io.grpc.protobuf.ProtoMethodDescriptorSupplier { + private final String methodName; + + UltramanServiceMethodDescriptorSupplier(String methodName) { + this.methodName = methodName; + } + + @Override + public com.google.protobuf.Descriptors.MethodDescriptor getMethodDescriptor() { + return getServiceDescriptor().findMethodByName(methodName); + } + } + + private static volatile io.grpc.ServiceDescriptor serviceDescriptor; + + public static io.grpc.ServiceDescriptor getServiceDescriptor() { + io.grpc.ServiceDescriptor result = serviceDescriptor; + if (result == null) { + synchronized (UltramanServiceGrpc.class) { + result = serviceDescriptor; + if (result == null) { + serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME) + .setSchemaDescriptor(new UltramanServiceFileDescriptorSupplier()) + .addMethod(getHelloMethod()) + .addMethod(getStreamMethod()) + .addMethod(getCallMethod()) + .build(); + } + } + } + return result; + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/AthenaContext.java b/athena-all/src/main/java/run/mone/ultraman/AthenaContext.java new file mode 100644 index 000000000..57250c706 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/AthenaContext.java @@ -0,0 +1,95 @@ +package run.mone.ultraman; + +import com.intellij.openapi.project.Project; +import run.mone.m78.ip.bo.ModelRes; +import run.mone.m78.ip.listener.UltrmanTreeKeyAdapter; +import lombok.Data; +import org.apache.commons.lang3.StringUtils; +import run.mone.ultraman.bo.ClientData; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2023/6/28 08:03 + */ +@Data +public class AthenaContext { + + private ConcurrentHashMap projectMap = new ConcurrentHashMap<>(); + + private UltrmanTreeKeyAdapter athenaTreeKeyAdapter; + + private int jdkVersion; + + private String zAddr; + + private List models; + + private Map modelMap; + + + //models 直接 转换为 modelMap,key是 ModelRes中的 value(class) + public void convertModelsToModelMap() { + if (models != null) { + modelMap = models.stream().collect(Collectors.toMap(ModelRes::getValue, Function.identity(), (existing, replacement) -> existing)); + } + } + + + public ModelRes getModel(String name) { + return modelMap.get(name); + } + + //客户端的数据 + private ConcurrentHashMap clientDataMap = new ConcurrentHashMap<>(); + + + //获取范围 + public ClientData getClientData(String projectName) { + ClientData data = clientDataMap.get(projectName); + if (null == data) { + return ClientData.builder().scope("method").build(); + } + return data; + } + + /** + * chatgpt的模型 + */ + private String gptModel = ""; + + public int getMaxTokenNum() { + return getModel(gptModel).getMaxToken(); + } + + public ModelRes gptModel() { + if (StringUtils.isEmpty(this.gptModel)) { + return null; + } + return getModel(this.gptModel); + } + + private List modelList = new ArrayList<>(); + + private String token; + + + + + private boolean debugAiProxy; + + private static final class LazyHolder { + private static final AthenaContext ins = new AthenaContext(); + } + + public static AthenaContext ins() { + return LazyHolder.ins; + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/AthenaInspection.java b/athena-all/src/main/java/run/mone/ultraman/AthenaInspection.java new file mode 100644 index 000000000..81c3551fb --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/AthenaInspection.java @@ -0,0 +1,131 @@ +package run.mone.ultraman; + +import com.intellij.codeInspection.*; +import com.intellij.codeInspection.util.IntentionFamilyName; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import run.mone.m78.ip.bo.GenerateCodeReq; +import run.mone.m78.ip.bo.PromptInfo; +import run.mone.m78.ip.common.Prompt; +import run.mone.m78.ip.common.PromptType; +import run.mone.m78.ip.service.PromptService; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * 对方法进行重命名 + * @date 2022/5/2 09:19 + */ +public class AthenaInspection extends AbstractBaseJavaLocalInspectionTool { + + @NotNull + @Override + public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) { + return new JavaElementVisitor() { + + + @Override + public void visitClass(PsiClass aClass) { + + holder.registerProblem(aClass, "", ProblemHighlightType.INFORMATION, new LocalQuickFix() { + @Override + public @IntentionFamilyName @NotNull String getFamilyName() { + return "Athena(类分析)"; + } + + //类分析 + @Override + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + String promptName = "analyse_class"; + invokePrompt(project,promptName); + } + }); + + } + + // rename_method(方法重命名) comment_2(方法添加注释) suggest_sidecar(方法review+建议) + @Override + public void visitMethod(PsiMethod method) { + List> list = Prompt.getPromptInfoByTag("method_inspection").stream() + .filter(it -> it.isCollected() || Prompt.containsTag(it.getTags(), "system")) + .map(it -> Pair.of(it.getDesc(), it.getPromptName())) + .collect(Collectors.toList()); + list.forEach(it -> holder.registerProblem(method, "", ProblemHighlightType.INFORMATION, new LocalQuickFix() { + @Override + public @IntentionFamilyName @NotNull String getFamilyName() { + return it.getKey(); + } + + @Override + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + String promptName = it.getValue(); + invokePrompt(project,promptName); + } + })); + + } + + + @Override + //访问注释 + public void visitComment(@NotNull PsiComment comment) { + //直接生成代码 + if (comment.getText().startsWith("//")) { + final String content = comment.getText().substring(2); + holder.registerProblem(comment, "", ProblemHighlightType.INFORMATION, new LocalQuickFix() { + @Override + //获取修复的家族名称 + public @IntentionFamilyName @NotNull String getFamilyName() { + return "Athena(生成方法)"; + } + + @Override + //应用修复 + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + //根据注释生成代码 + PromptService.generateMethod(project, content); + } + }); + } + } + + + /** + * 给字段起新名字 + */ + @Override + public void visitField(PsiField field) { + holder.registerProblem(field, "", ProblemHighlightType.INFORMATION, new LocalQuickFix() { + @Override + public @IntentionFamilyName @NotNull String getFamilyName() { + return "Athena(字段重命名)"; + } + + @Override + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + String promptName = "rename_field"; + invokePrompt(project, promptName); + } + }); + } + }; + } + + + public static void invokePrompt(Project project, String promptName) { + PromptInfo promptInfo = Prompt.getPromptInfo(promptName); + PromptType promptType = Prompt.getPromptType(promptInfo); + PromptService.dynamicInvoke(GenerateCodeReq.builder() + .project(project) + .promptType(promptType) + .promptName(promptName) + .promptInfo(promptInfo) + .build()); + } + + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/AthenaSuggestionInspection.java b/athena-all/src/main/java/run/mone/ultraman/AthenaSuggestionInspection.java new file mode 100644 index 000000000..eba5aa615 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/AthenaSuggestionInspection.java @@ -0,0 +1,61 @@ +package run.mone.ultraman; + +import com.intellij.codeInspection.*; +import com.intellij.codeInspection.util.IntentionFamilyName; +import com.intellij.openapi.project.Project; +import com.intellij.psi.JavaElementVisitor; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiMethod; +import run.mone.m78.ip.bo.GenerateCodeReq; +import run.mone.m78.ip.bo.Message; +import run.mone.m78.ip.bo.PromptInfo; +import run.mone.m78.ip.common.Prompt; +import run.mone.m78.ip.common.PromptType; +import run.mone.m78.ip.service.PromptService; +import org.jetbrains.annotations.NotNull; + +/** + * @author goodjava@qq.com + * 用来提出建议代码 + */ +public class AthenaSuggestionInspection extends AbstractBaseJavaLocalInspectionTool { + + private static final String promptName = "hi2"; + + @NotNull + @Override + public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) { + return new JavaElementVisitor() { + + @Override + public void visitMethod(PsiMethod method) { + if (true) { + return; + } + super.visitMethod(method); + holder.registerProblem(method, "", ProblemHighlightType.INFORMATION, new LocalQuickFix() { + + @Override + public @IntentionFamilyName @NotNull String getFamilyName() { + return Message.suggestion; + } + + @Override + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + PromptInfo promptInfo = Prompt.getPromptInfo(promptName); + PromptType promptType = Prompt.getPromptType(promptInfo); + PromptService.inlayHint(GenerateCodeReq.builder() + .promptName(promptName) + .promptInfo(promptInfo) + .promptType(promptType) + .project(project) + .projectName(project.getName()).build()); + } + }); + } + + }; + } + + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/DemoService.java b/athena-all/src/main/java/run/mone/ultraman/DemoService.java new file mode 100644 index 000000000..f1dd49a07 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/DemoService.java @@ -0,0 +1,12 @@ +package run.mone.ultraman; + + +/** + * @author goodjava@qq.com + * @date 2023/6/7 18:20 + */ +public class DemoService { + + + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/FileUploadFile.java b/athena-all/src/main/java/run/mone/ultraman/FileUploadFile.java new file mode 100644 index 000000000..d32e24530 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/FileUploadFile.java @@ -0,0 +1,55 @@ +package run.mone.ultraman; + +import java.io.File; +import java.io.Serializable; + +public class FileUploadFile implements Serializable { + + + private static final long serialVersionUID = 1L; + private File file;// 文件 + private String file_md5;// 文件名 + private int starPos;// 开始位置 + private byte[] bytes;// 文件字节数组 + private int endPos;// 结尾位置 + + public int getStarPos() { + return starPos; + } + + public void setStarPos(int starPos) { + this.starPos = starPos; + } + + public int getEndPos() { + return endPos; + } + + public void setEndPos(int endPos) { + this.endPos = endPos; + } + + public byte[] getBytes() { + return bytes; + } + + public void setBytes(byte[] bytes) { + this.bytes = bytes; + } + + public File getFile() { + return file; + } + + public void setFile(File file) { + this.file = file; + } + + public String getFile_md5() { + return file_md5; + } + + public void setFile_md5(String file_md5) { + this.file_md5 = file_md5; + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/FileUploadServerHandler.java b/athena-all/src/main/java/run/mone/ultraman/FileUploadServerHandler.java new file mode 100644 index 000000000..7b04f7352 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/FileUploadServerHandler.java @@ -0,0 +1,119 @@ +package run.mone.ultraman; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.handler.codec.http.HttpContent; +import io.netty.handler.codec.http.HttpObject; +import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.multipart.*; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class FileUploadServerHandler extends SimpleChannelInboundHandler { + + private static final Logger logger = Logger.getLogger(FileUploadServerHandler.class.getName()); + //浏览器发来的request请求,转化为了这个对象 + private HttpRequest request; + + private boolean readingChunks; + + private final StringBuilder responseContent = new StringBuilder(); + + private static final HttpDataFactory factory = + new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE); // Disk if size exceed + //发文件需要post请求,过来数据之后需要解码post + private HttpPostRequestDecoder decoder; + + static { + //这是存储上传文件和属性的位置的配置,如果不存在该文件夹会报错。 + DiskFileUpload.deleteOnExitTemporaryFile = true; //当文件出现重名的时候是否删除 + DiskFileUpload.baseDirectory = "D:" + File.separatorChar + "aa"; // 系统存储文件的位置 + DiskAttribute.deleteOnExitTemporaryFile = true; //如果属性出现重复选择删掉 + DiskAttribute.baseDirectory = "D:" + File.separatorChar + "aa"; // 属性文件存储目录。 + } + + /** + * 当通道断开的时候,触发此事件,置空decoder + * @param ctx + * @throws Exception + */ + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + if (decoder != null) { + decoder.cleanFiles(); + } + } + + /** + * 当收到数据的时候,触发的方法,类似channelRead + * @param ctx + * @param msg + * @throws Exception + */ + @Override + public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception { + if (msg instanceof HttpRequest) { + HttpRequest request = this.request = (HttpRequest) msg; + URI uri = new URI(request.uri()); + if (uri.getPath().startsWith("/audio")) { + decoder = new HttpPostRequestDecoder(factory, request); + readHttpDataChunkByLoacl(); + return; + } else { + ctx.fireChannelRead(msg); + } + } else if (msg instanceof HttpContent) { + decoder.offer((HttpContent) msg); + readHttpDataChunkByLoacl(); + } + } + + private void readHttpDataChunkByLoacl() throws IOException { + while (null != decoder && decoder.hasNext()) { + InterfaceHttpData data = decoder.next(); + if (data != null) { + if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.FileUpload) { + FileUpload fileUpload = (FileUpload) data; + if (fileUpload.isCompleted()) { + fileUpload.isInMemory(); + + // 获取文件 + // File file = fileUpload.getFile(); +// FileInputStream fileInputStream = new FileInputStream(file); + + String filename = fileUpload.getFilename(); + // 截取后缀名 + String suffixName = ""; + if (filename.contains(".")) { + suffixName = filename.substring(filename.lastIndexOf(".")); + } else { + suffixName = filename; + } +// //TODO 重命名文件名称 +// fileUpload.setFilename(new Random().nextInt(9999) + "" + suffixName); +// // 将重命名后的文件存放于 saveFilePath 路径下 +// fileUpload.renameTo(new File(saveFilePath + File.separator + fileUpload.getFilename())); +// decoder.removeHttpDataFromClean(fileUpload); + } + } + } + } + } + + /** + * 功能描述: 连接出现异常会调用此方法,一般就是记录日志,关闭连接。 + * + * @auther: 李泽 + * @date: 2019/3/17 11:47 + */ + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + logger.log(Level.WARNING, responseContent.toString(), cause); + ctx.channel().close(); + } +} + diff --git a/athena-all/src/main/java/run/mone/ultraman/HttpServerHandler.java b/athena-all/src/main/java/run/mone/ultraman/HttpServerHandler.java new file mode 100644 index 000000000..6db1c2640 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/HttpServerHandler.java @@ -0,0 +1,40 @@ +package run.mone.ultraman; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.FullHttpResponse; +import io.netty.handler.codec.http.HttpHeaderNames; +import io.netty.handler.codec.http.HttpResponseStatus; +import org.jetbrains.annotations.NotNull; +import run.mone.ultraman.http.HttpResponseUtils; + +public class HttpServerHandler extends SimpleChannelInboundHandler { + + private Gson gson = new Gson(); + + @Override + protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception { + // 创建http响应 + sendRes(ctx, new JsonObject()); + } + + private void sendRes(ChannelHandlerContext ctx, JsonObject obj) { + FullHttpResponse response = HttpResponseUtils.createResponse(HttpResponseStatus.OK, gson.toJson(obj)); + response.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/json; charset=UTF-8"); + ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); + } + + @NotNull + private static JsonObject getObj(String data, String message) { + JsonObject obj = new JsonObject(); + obj.addProperty("code", 0); + obj.addProperty("message", message); + obj.addProperty("data", data); + return obj; + } + +} \ No newline at end of file diff --git a/athena-all/src/main/java/run/mone/ultraman/UltramanCompletionContributor.java b/athena-all/src/main/java/run/mone/ultraman/UltramanCompletionContributor.java new file mode 100644 index 000000000..ca96f86dd --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/UltramanCompletionContributor.java @@ -0,0 +1,32 @@ +package run.mone.ultraman; + +import com.intellij.codeInsight.completion.*; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.patterns.PlatformPatterns; +import com.intellij.util.ProcessingContext; +import org.jetbrains.annotations.NotNull; + +/** + * @author goodjava@qq.com + * @date 2022/5/2 09:57 + */ +public class UltramanCompletionContributor extends CompletionContributor { + +// public UltramanCompletionContributor() { +// extend(CompletionType.BASIC, PlatformPatterns.psiElement(Field), +// new CompletionProvider<>() { +// public void addCompletions(@NotNull CompletionParameters parameters, +// @NotNull ProcessingContext context, +// @NotNull CompletionResultSet resultSet) { +// resultSet.addElement(LookupElementBuilder.create("Hello")); +// } +// } +// ); +// } + + + @Override + public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) { + result.addElement(LookupElementBuilder.create("Hello")); + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/UltramanHttpServer.java b/athena-all/src/main/java/run/mone/ultraman/UltramanHttpServer.java new file mode 100644 index 000000000..553113843 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/UltramanHttpServer.java @@ -0,0 +1,60 @@ +package run.mone.ultraman; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.codec.http.HttpMethod; +import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpRequestDecoder; +import io.netty.handler.codec.http.HttpResponseEncoder; +import io.netty.handler.codec.http.cors.CorsConfig; +import io.netty.handler.codec.http.cors.CorsConfigBuilder; +import io.netty.handler.codec.http.cors.CorsHandler; +import io.netty.handler.stream.ChunkedWriteHandler; + +public class UltramanHttpServer { + + private int port; + + public UltramanHttpServer(int port) { + this.port = port; + } + + public void run() throws Exception { + EventLoopGroup bossGroup = new NioEventLoopGroup(); + EventLoopGroup workerGroup = new NioEventLoopGroup(); + try { + ServerBootstrap b = new ServerBootstrap(); + b.group(bossGroup, workerGroup) + .channel(NioServerSocketChannel.class) + .childHandler(new ChannelInitializer() { + public void initChannel(SocketChannel ch) throws Exception { + ch.pipeline().addLast("http-decoder", new HttpRequestDecoder()); + ch.pipeline().addLast("http-aggregator", new HttpObjectAggregator(65535)); + ch.pipeline().addLast("http-encoder", new HttpResponseEncoder()); + ch.pipeline().addLast("http-chunked", new ChunkedWriteHandler()); + // Configure CORS + CorsConfig corsConfig = CorsConfigBuilder.forAnyOrigin() + .allowedRequestHeaders("X-Requested-With", "Content-Type", "Accept", "Origin", "Authorization", "Referer", "sec-ch-ua", "sec-ch-ua-mobile", "sec-ch-ua-platform") + .allowedRequestMethods(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT, HttpMethod.DELETE, HttpMethod.OPTIONS) + .build(); + ch.pipeline().addLast("http-cors", new CorsHandler(corsConfig)); + ch.pipeline().addLast("http-server", new HttpServerHandler()); + } + }) + .option(ChannelOption.SO_BACKLOG, 128) + .childOption(ChannelOption.SO_KEEPALIVE, true); + ChannelFuture f = b.bind("0.0.0.0", port).sync(); + f.channel().closeFuture().sync(); + } finally { + bossGroup.shutdownGracefully(); + workerGroup.shutdownGracefully(); + } + } + +} \ No newline at end of file diff --git a/athena-all/src/main/java/run/mone/ultraman/ai/MyCompletionContributor.java b/athena-all/src/main/java/run/mone/ultraman/ai/MyCompletionContributor.java new file mode 100644 index 000000000..c3eee7b75 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/ai/MyCompletionContributor.java @@ -0,0 +1,83 @@ +package run.mone.ultraman.ai; + +import com.intellij.codeInsight.completion.*; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.patterns.PlatformPatterns; +import com.intellij.psi.*; +import com.intellij.util.ProcessingContext; +import run.mone.m78.ip.common.ProjectCache; +import run.mone.m78.ip.service.CodeService; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * goodjava@qq.com + * 目前不好用...后边想想办法 + */ +public class MyCompletionContributor extends CompletionContributor { + + public MyCompletionContributor() { + extend(CompletionType.BASIC, PlatformPatterns.psiElement(), + new CompletionProvider() { + public void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet resultSet) { + + Editor editor = parameters.getEditor(); + Project project = editor.getProject(); + + try { + PsiElement position = parameters.getPosition(); + PsiElement prevSibling = position.getPrevSibling(); + + if (prevSibling instanceof PsiReferenceParameterList) { + prevSibling = prevSibling.getPrevSibling(); + if (prevSibling instanceof PsiJavaToken && ((PsiJavaToken) prevSibling).getTokenType().equals(JavaTokenType.DOT)) { + prevSibling = prevSibling.getPrevSibling(); + if (prevSibling.getReference().resolve() instanceof PsiField) { + PsiField psiField = (PsiField) prevSibling.getReference().resolve(); + String str = psiField.getType().getCanonicalText(); + if (str.equals("com.xiaomi.sautumn.serverless.api.Context")) { + System.out.println(1); + generateCodeSuggestion(project, resultSet, "System", str); + } + } + if (prevSibling.getReference().resolve() instanceof PsiVariable) { + PsiVariable psiVariable = (PsiVariable) prevSibling.getReference().resolve(); + String str = psiVariable.getType().getCanonicalText(); + if (str.equals("com.xiaomi.sautumn.serverless.api.Context")) { + System.out.println(2); + generateCodeSuggestion(project, resultSet, "System", str); + } + + } + } + } + + } catch (Throwable ex) { + ex.printStackTrace(); + throw ex; + } + + } + } + ); + } + + private void generateCodeSuggestion(Project project, CompletionResultSet resultSet, String str, String clazz) { + List list = null; + Object v = ProjectCache.get(project, str); + if (null != v) { + list = (List) v; + } else { + list = CodeService.listMethodInfo(clazz); + ProjectCache.put(project, str, list); + } + list.forEach(it -> { + resultSet.addElement(LookupElementBuilder.create(it).withTypeText("mone support").withBoldness(true)); + }); + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/background/AiCode.java b/athena-all/src/main/java/run/mone/ultraman/background/AiCode.java new file mode 100644 index 000000000..522d483a3 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/background/AiCode.java @@ -0,0 +1,167 @@ +package run.mone.ultraman.background; + +import com.google.gson.Gson; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.project.Project; +import run.mone.m78.ip.bo.AiMessage; +import run.mone.m78.ip.bo.MessageConsumer; +import run.mone.m78.ip.common.ChromeUtils; +import run.mone.m78.ip.common.Safe; +import run.mone.m78.ip.util.UltramanConsole; +import lombok.Data; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +import java.time.Duration; +import java.time.Instant; +import java.util.Date; +import java.util.UUID; +import java.util.concurrent.CountDownLatch; +import java.util.function.Consumer; + +/** + * @author goodjava@qq.com + * @date 2023/6/25 14:27 + */ +@Slf4j +public class AiCode extends MessageConsumer { + + private static Gson gson = new Gson(); + + private ProgressIndicator progressIndicator; + + private CountDownLatch countDownLatch; + + private Date beginTime; + + private float totalTime = 5.0f; + + protected StringBuilder sb = new StringBuilder(); + + @Setter + private Project project; + + + private Consumer consumer; + + + private String messageId = UUID.randomUUID().toString(); + + + public String getMessageId() { + return this.messageId; + } + + + + public AiCode(ProgressIndicator progressIndicator, CountDownLatch countDownLatch) { + this.progressIndicator = progressIndicator; + this.countDownLatch = countDownLatch; + } + + public AiCode(ProgressIndicator progressIndicator, CountDownLatch countDownLatch, Project project) { + this.progressIndicator = progressIndicator; + this.countDownLatch = countDownLatch; + this.project = project; + } + + public AiCode(ProgressIndicator progressIndicator, CountDownLatch countDownLatch, Project project, Consumer consumer) { + this.progressIndicator = progressIndicator; + this.countDownLatch = countDownLatch; + this.project = project; + this.consumer = consumer; + } + + @Override + public void begin(AiMessage message) { + String str = gson.toJson(message); + log.info(str); + beginTime = new Date(); + messageId = message.getId(); + if (null != this.project) { + UltramanConsole.append(project, "\ncode generate begin \n"); + } + if (null != consumer) { + consumer.accept(message); + } + Safe.run(() -> ChromeUtils.call(message.getProjectName(), "setResultCode", str)); + } + + @Override + public void onEvent(AiMessage message) { + sb.append(message.getText()); + String str = gson.toJson(message); + log.info(str); + if (!progressIndicator.isCanceled()) { + long sencodes = getSecondsBetween(this.beginTime.toInstant(), Instant.now()); + progressIndicator.setFraction(Math.min(sencodes / totalTime, 0.99)); + if (null != this.project) { + UltramanConsole.append(project, deocde(str), false); + } + if (null != consumer) { + this.consumer.accept(message); + } + Safe.run(() -> ChromeUtils.call(message.getProjectName(), "setResultCode", str)); + } + } + + + @Data + class T { + private String text; + } + + + private String deocde(String str) { + try { + T t = gson.fromJson(str, T.class); + return t.getText(); + } catch (Throwable ex) { + return ""; + } + } + + public long getSecondsBetween(Instant past, Instant present) { + return Duration.between(past, present).getSeconds(); + } + + @Override + public void end(AiMessage message) { + String str = gson.toJson(message); + log.info(str); + if (!progressIndicator.isCanceled()) { + Safe.run(() -> ChromeUtils.call(message.getProjectName(), "setResultCode", str)); + progressIndicator.setFraction(1); + } + Safe.run(() -> { + if (progressIndicator.isRunning()) { + progressIndicator.stop(); + } + }); + if (null != this.project) { + UltramanConsole.append(project, "\n\ncode generate end\n\n"); + } + countDownLatch.countDown(); + } + + @Override + public void failure(AiMessage message) { + Safe.run(() -> { + if (progressIndicator.isRunning()) { + progressIndicator.stop(); + } + }); + countDownLatch.countDown(); + } + + + public String getText() { + return sb.toString(); + } + + public String getMarkDownText() { + return "```\n" + sb.toString() + "\n```"; + } + + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/background/AthenaEditorTask.java b/athena-all/src/main/java/run/mone/ultraman/background/AthenaEditorTask.java new file mode 100644 index 000000000..6f76fb1fd --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/background/AthenaEditorTask.java @@ -0,0 +1,83 @@ +package run.mone.ultraman.background; + +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.Task; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.NlsContexts; +import run.mone.m78.ip.bo.GenerateCodeReq; +import run.mone.m78.ip.bo.MessageConsumer; +import run.mone.m78.ip.bo.PromptContext; +import run.mone.m78.ip.service.CodeService; +import run.mone.m78.ip.service.PromptService; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; + +import java.util.Map; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + + +/** + * @author goodjava@qq.com + */ +@Slf4j +public class AthenaEditorTask extends Task.Backgroundable { + + /** + * 是否是确定的(有时间进度) + */ + private boolean indeterminate = false; + + private Project project; + + private String promptName; + + private String text; + + private Map params; + + private MessageConsumer consumer; + + private GenerateCodeReq req; + + + public AthenaEditorTask(GenerateCodeReq req, @NlsContexts.ProgressTitle @NotNull String title, Map params, MessageConsumer consumer) { + this(req, title, null, params, consumer); + } + + public AthenaEditorTask(GenerateCodeReq req, @NlsContexts.ProgressTitle @NotNull String title, String code, Map params, MessageConsumer consumer) { + super(req.getProject(), title); + this.project = req.getProject(); + this.promptName = req.getPromptName(); + if (StringUtils.isEmpty(code)) { + this.text = PromptService.getCode(req, new PromptContext()); + } else { + this.text = code; + } + this.params = params; + this.consumer = consumer; + this.req = req; + } + + + @SneakyThrows + @Override + public void run(@NotNull ProgressIndicator progressIndicator) { + progressIndicator.setIndeterminate(this.indeterminate); + progressIndicator.setFraction(0.0); + CountDownLatch countDownLatch = new CountDownLatch(1); + CodeService.generateCodeWithAi5(this.req, project, promptName, new String[]{text}, params, (p, code) -> { + }, new EditorAiCode(progressIndicator, countDownLatch, consumer)); + //最多等30秒 + countDownLatch.await(30, TimeUnit.SECONDS); + } + + + public static void start(AthenaEditorTask task) { + ProgressManager.getInstance().run(task); + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/background/AthenaTask.java b/athena-all/src/main/java/run/mone/ultraman/background/AthenaTask.java new file mode 100644 index 000000000..6cb86f1fe --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/background/AthenaTask.java @@ -0,0 +1,176 @@ +package run.mone.ultraman.background; + +import com.google.common.base.Function; +import com.google.common.base.Splitter; +import com.google.common.base.Stopwatch; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.Task; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.NlsContexts; +import run.mone.m78.ip.bo.GenerateCodeReq; +import run.mone.m78.ip.bo.ModelRes; +import run.mone.m78.ip.bo.PromptContext; +import run.mone.m78.ip.bo.ZAddrRes; +import run.mone.m78.ip.bo.robot.AiChatMessage; +import run.mone.m78.ip.bo.robot.ProjectAiMessageManager; +import run.mone.m78.ip.bo.robot.Role; +import run.mone.m78.ip.common.Prompt; +import run.mone.m78.ip.service.CodeService; +import run.mone.m78.ip.util.UltramanConsole; +import lombok.Setter; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.CollectionUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + + +/** + * @author goodjava@qq.com + * @date 2023/6/23 08:10 + * 底边栏会显示进度,避免用户不知道当前的ai执行状态 + * 以后再chat 和 editor的都会再这里处理 + */ +@Slf4j +public class AthenaTask extends Task.Backgroundable { + + /** + * 是否是确定的(有时间进度) + */ + private boolean indeterminate = false; + + private Project project; + + private String promptName; + + private String text; + + private Map params; + + @Setter + private boolean format = true; + + @Setter + private PromptContext promptContext; + + private static final String METHOD_CONTEXT = "method_context"; + + private static final String MODULE_CONTEXT = "module_context"; + + private static final String RESOURCE_CONTEXT = "resource_context"; + + private static final String CONTEXT = "context"; + + //chat(聊天窗口) editor(ide中) + @Setter + private String type = "chat"; + + @Setter + private Runnable initRunnable; + + + public AthenaTask(@Nullable Project project, @NlsContexts.ProgressTitle @NotNull String title, String promptName, String text, Map params) { + super(project, title); + this.project = project; + this.promptName = promptName; + this.text = text; + this.params = params; + } + + @SneakyThrows + @Override + public void run(@NotNull ProgressIndicator progressIndicator) { + if (null != this.initRunnable) { + initRunnable.run(); + } + + String scope = ""; + if (null != this.promptContext) { + callResourceContext(); + callMethodContext(); + callModuleContext(); + scope = this.promptContext.getScope(); + } + + callContextSize(); + + ZAddrRes zAddrRes = Prompt.zAddrRes(); + if (CollectionUtils.isNotEmpty(zAddrRes.getModels())) { + Long userCredits = 0L; + // Hint: the first model carries the user credit info + ModelRes modelRes = zAddrRes.getModels().get(0); + if (modelRes != null) { + userCredits = modelRes.getPoints(); + } + String progressIndicatorText = "Athena Running, User Credits: " + userCredits; + progressIndicator.setText(progressIndicatorText); + progressIndicator.setText2(progressIndicatorText); + } + + progressIndicator.setIndeterminate(this.indeterminate); + progressIndicator.setFraction(0.0); + CountDownLatch countDownLatch = new CountDownLatch(1); + UltramanConsole.append(project, "\ncall prompt begin:" + promptName + " scope:" + scope); + AiCode aiCode = getAiCode(progressIndicator, countDownLatch); + Stopwatch sw = Stopwatch.createStarted(); + //一点一点的生成代码 + CodeService.generateCodeWithAi5(GenerateCodeReq.builder().format(format).promptName(promptName).project(project).build(), project, promptName, new String[]{text}, params, (p, code) -> { + }, aiCode); + //最多等1分钟 + countDownLatch.await(3, TimeUnit.MINUTES); + String text = aiCode.getMarkDownText(); + UltramanConsole.append(project, "call prompt finish:" + promptName + " use time:" + sw.elapsed(TimeUnit.SECONDS) + "s\n"); + ProjectAiMessageManager.getInstance().appendMsg(project, AiChatMessage.builder().id(aiCode.getMessageId()).role(Role.assistant).message(text).data(text).build()); + } + + + /** + * 无论如何都会在chat里显示信息 + * + * @param progressIndicator + * @param countDownLatch + * @return + */ + @NotNull + private AiCode getAiCode(@NotNull ProgressIndicator progressIndicator, CountDownLatch countDownLatch) { + return null; + } + + //计算请求的size,有写大小需要优化(最终大小需要低于3500) + private void callContextSize() { + + } + + + private static Function f = str -> { + List l = Splitter.on(".").splitToList(str); + if (l.size() > 0) { + return l.get(l.size() - 1); + } + return str; + }; + + private void callModuleContext() { + + } + + //引入一些class内部的方法(能起到一定的教学作用) + private void callMethodContext() { + } + + private void callResourceContext() { + + } + + + //启动任务 + public static void start(Task task) { + ProgressManager.getInstance().run(task); + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/background/EditorAiCode.java b/athena-all/src/main/java/run/mone/ultraman/background/EditorAiCode.java new file mode 100644 index 000000000..a2d1779e4 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/background/EditorAiCode.java @@ -0,0 +1,89 @@ +package run.mone.ultraman.background; + +import com.google.gson.Gson; +import com.intellij.openapi.progress.ProgressIndicator; +import run.mone.m78.ip.bo.AiMessage; +import run.mone.m78.ip.bo.MessageConsumer; +import run.mone.m78.ip.common.Safe; +import lombok.extern.slf4j.Slf4j; + +import java.time.Duration; +import java.time.Instant; +import java.util.Date; +import java.util.concurrent.CountDownLatch; + +/** + * @author goodjava@qq.com + */ +@Slf4j +public class EditorAiCode extends MessageConsumer { + + private static Gson gson = new Gson(); + + private ProgressIndicator progressIndicator; + + private CountDownLatch countDownLatch; + + private Date beginTime; + + private float totalTime = 5.0f; + + private MessageConsumer consumer; + + public EditorAiCode(ProgressIndicator progressIndicator, CountDownLatch countDownLatch, MessageConsumer consumer) { + this.progressIndicator = progressIndicator; + this.countDownLatch = countDownLatch; + this.consumer = consumer; + } + + @Override + public void begin(AiMessage message) { + String str = gson.toJson(message); + log.info(str); + beginTime = new Date(); + consumer.begin(message); + } + + @Override + public void onEvent(AiMessage message) { + String str = gson.toJson(message); + log.info(str); + if (!progressIndicator.isCanceled()) { + long sencodes = getSecondsBetween(this.beginTime.toInstant(), Instant.now()); + progressIndicator.setFraction(Math.min(sencodes / totalTime, 0.99)); + consumer.onEvent(message); + } + } + + public long getSecondsBetween(Instant past, Instant present) { + return Duration.between(past, present).getSeconds(); + } + + @Override + public void end(AiMessage message) { + String str = gson.toJson(message); + log.info(str); + if (!progressIndicator.isCanceled()) { + consumer.end(message); + progressIndicator.setFraction(1); + } + Safe.run(() -> { + if (progressIndicator.isRunning()) { + progressIndicator.stop(); + } + }); + countDownLatch.countDown(); + } + + @Override + public void failure(AiMessage message) { + Safe.run(() -> { + if (progressIndicator.isRunning()) { + progressIndicator.stop(); + } + }); + countDownLatch.countDown(); + } + + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/background/TaskState.java b/athena-all/src/main/java/run/mone/ultraman/background/TaskState.java new file mode 100644 index 000000000..04cfc7f80 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/background/TaskState.java @@ -0,0 +1,17 @@ +package run.mone.ultraman.background; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/6/23 08:23 + */ +@Data +public class TaskState implements Serializable { + + private boolean finish; + + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/bo/AiReq.java b/athena-all/src/main/java/run/mone/ultraman/bo/AiReq.java new file mode 100644 index 000000000..ce92b71e4 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/bo/AiReq.java @@ -0,0 +1,29 @@ +package run.mone.ultraman.bo; + +import lombok.Data; + +import java.io.Serializable; +import java.util.Map; + +/** + * @author goodjava@qq.com + * @date 2023/4/28 10:55 + */ +@Data +public class AiReq implements Serializable { + + private String cmd; + + private String ai; + + private String project; + + private String module; + + private boolean mute; + + private String param; + + private Map meta; + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/bo/AthenaClassInfo.java b/athena-all/src/main/java/run/mone/ultraman/bo/AthenaClassInfo.java new file mode 100644 index 000000000..e3fc40f2f --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/bo/AthenaClassInfo.java @@ -0,0 +1,30 @@ +package run.mone.ultraman.bo; + +import lombok.Builder; +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/11/6 10:03 + */ +@Data +@Builder +public class AthenaClassInfo { + + private String name; + + private String classCode; + + private String md5; + + private List annoList; + + private List publicMethodList; + + @Builder.Default + private List interfaceList = new ArrayList<>(); + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/bo/AthenaFieldInfo.java b/athena-all/src/main/java/run/mone/ultraman/bo/AthenaFieldInfo.java new file mode 100644 index 000000000..339e4f6f1 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/bo/AthenaFieldInfo.java @@ -0,0 +1,24 @@ +package run.mone.ultraman.bo; + +import lombok.Builder; +import lombok.Data; + +/** + * @author goodjava@qq.com + * @date 2023/11/6 22:43 + */ +@Data +@Builder +public class AthenaFieldInfo { + + private String name; + + private String code; + + private String md5; + + //相关性评分 + @Builder.Default + private int score = 0; + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/bo/AthenaMethodInfo.java b/athena-all/src/main/java/run/mone/ultraman/bo/AthenaMethodInfo.java new file mode 100644 index 000000000..d9c940595 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/bo/AthenaMethodInfo.java @@ -0,0 +1,24 @@ +package run.mone.ultraman.bo; + +import lombok.Builder; +import lombok.Data; + +/** + * @author goodjava@qq.com + * @date 2023/11/6 22:43 + */ +@Data +@Builder +public class AthenaMethodInfo { + + private String name; + + private String code; + + private String md5; + + //相关性评分 + @Builder.Default + private int score = 0; + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/bo/AthenaPair.java b/athena-all/src/main/java/run/mone/ultraman/bo/AthenaPair.java new file mode 100644 index 000000000..67ecb7bc0 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/bo/AthenaPair.java @@ -0,0 +1,24 @@ +package run.mone.ultraman.bo; + +import lombok.Data; + +/** + * @author goodjava@qq.com + * @date 2023/11/5 22:41 + */ +@Data +public class AthenaPair { + + private K key; + + private V value; + + + public static AthenaPair of(K key, V value) { + AthenaPair a = new AthenaPair<>(); + a.setKey(key); + a.setValue(value); + return a; + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/bo/ClientData.java b/athena-all/src/main/java/run/mone/ultraman/bo/ClientData.java new file mode 100644 index 000000000..4a61d665d --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/bo/ClientData.java @@ -0,0 +1,22 @@ +package run.mone.ultraman.bo; + +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/12/26 10:50 + */ +@Data +@Builder +public class ClientData implements Serializable { + + private String projectName; + + private String module; + + private String scope; + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/bo/CodeReq.java b/athena-all/src/main/java/run/mone/ultraman/bo/CodeReq.java new file mode 100644 index 000000000..af10b5477 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/bo/CodeReq.java @@ -0,0 +1,43 @@ +package run.mone.ultraman.bo; + +import lombok.Builder; +import lombok.Data; + +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/11/5 22:46 + */ +@Data +@Builder +public class CodeReq { + + private String projectName; + + private String moduleName; + + private String className; + + private String methodName; + + private String code; + + private List codeList; + + private String data; + + //需求 + private String requirement; + + //返回几条记录 + @Builder.Default + private int limit = 1; + + //文榜需要用到的一个id,随便起就可以 + @Builder.Default + private Long knowledgeBaseId = 1038L; + + private List fileTypeList; + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/bo/NameInfo.java b/athena-all/src/main/java/run/mone/ultraman/bo/NameInfo.java new file mode 100644 index 000000000..4c7ddc457 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/bo/NameInfo.java @@ -0,0 +1,8 @@ +package run.mone.ultraman.bo; + +/** + * @author goodjava@qq.com + * @date 2023/6/24 21:47 + */ +public interface NameInfo { +} diff --git a/athena-all/src/main/java/run/mone/ultraman/bo/PackageInfo.java b/athena-all/src/main/java/run/mone/ultraman/bo/PackageInfo.java new file mode 100644 index 000000000..4cb60b8f2 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/bo/PackageInfo.java @@ -0,0 +1,16 @@ +package run.mone.ultraman.bo; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/6/24 21:33 + */ +@Data +public class PackageInfo implements Serializable,NameInfo { + + private String name; + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/bo/ParamsInfo.java b/athena-all/src/main/java/run/mone/ultraman/bo/ParamsInfo.java new file mode 100644 index 000000000..c42df4b39 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/bo/ParamsInfo.java @@ -0,0 +1,16 @@ +package run.mone.ultraman.bo; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/7/20 14:26 + */ +@Data +public class ParamsInfo implements Serializable { + + private String params; + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/bo/T.java b/athena-all/src/main/java/run/mone/ultraman/bo/T.java new file mode 100644 index 000000000..3256067cc --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/bo/T.java @@ -0,0 +1,29 @@ +package run.mone.ultraman.bo; + +/** + * @author goodjava@qq.com + * @date 2023/11/13 21:53 + */ +public class T { + + private int a; + + private int b; + + + public T() { + System.out.println("T"); + } + + public void k(){ + System.out.println("k"); + } + + static { + System.out.println("static"); + } + + private void a() { + System.out.println("a"); + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/bo/Version.java b/athena-all/src/main/java/run/mone/ultraman/bo/Version.java new file mode 100644 index 000000000..51dbf716c --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/bo/Version.java @@ -0,0 +1,15 @@ +package run.mone.ultraman.bo; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/6/7 14:06 + */ +public class Version implements Serializable { + + @Override + public String toString() { + return "0.0.1:2024-01-12-1"; + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/common/ActionEventUtils.java b/athena-all/src/main/java/run/mone/ultraman/common/ActionEventUtils.java new file mode 100644 index 000000000..71ca1055e --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/common/ActionEventUtils.java @@ -0,0 +1,60 @@ +package run.mone.ultraman.common; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.Project; +import com.intellij.ui.speedSearch.SpeedSearchSupply; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author goodjava@qq.com + * @date 2023/4/20 17:22 + */ +public class ActionEventUtils { + + + public static AnActionEvent createAnAction(Project project, String data) { + // 创建一个新的 Presentation 对象 + Presentation presentation = new Presentation(); + // 获取 ActionManager 实例 + ActionManager actionManager = ActionManager.getInstance(); + + // 创建一个新的 DataContext 对象 + DataContext dataContext = new MyDataContext(project, data); + + // 创建一个新的 AnActionEvent 对象 + AnActionEvent anActionEvent = new AnActionEvent( + null, + dataContext, + "", + presentation, + actionManager, + 0 + ); + return anActionEvent; + } + + private static class MyDataContext implements DataContext { + private final Project project; + + private String data; + + public MyDataContext(Project project, String data) { + this.project = project; + this.data = data; + } + + @Override + public Object getData(String dataId) { + if (CommonDataKeys.PROJECT.is(dataId)) { + return project; + } + if (dataId.equals(SpeedSearchSupply.SPEED_SEARCH_CURRENT_QUERY.getName())) { + return this.data; + } + // 如果需要支持其他 dataId,可以在此处添加相应的条件 + return null; + } + + } +} \ No newline at end of file diff --git a/athena-all/src/main/java/run/mone/ultraman/common/Code.java b/athena-all/src/main/java/run/mone/ultraman/common/Code.java new file mode 100644 index 000000000..f01dca91a --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/common/Code.java @@ -0,0 +1,168 @@ +package run.mone.ultraman.common; + +import com.google.common.base.Strings; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import run.mone.m78.ip.bo.PromptInfo; +import run.mone.m78.ip.service.CodeService; +import lombok.Data; +import org.apache.commons.lang3.StringUtils; + +import java.util.Arrays; +import java.util.stream.IntStream; + +/** + * @author goodjava@qq.com + * @date 2023/5/26 16:47 + */ +@Data +public class Code { + + private Document document; + + private PsiFile psiFile; + + private int offset; + + private Project project; + + private Editor editor; + + private int incrNum = 0; + + private PromptInfo promptInfo; + + /** + * 需要引入end,不然生成的代码里有数字,就不太好处理了,这个end代表这一行结束了 + */ + private boolean end = true; + + /** + * 是否需要insert 这行,有的情况下是不需要的 + */ + private boolean needInsert = true; + + public void append(String c) { + String str = removeEnter(c); + if (isNum(str) && end) { + //move + int lineNum = Integer.parseInt(str.trim()); + lineNum += incrNum; + offset = document.getLineStartOffset(lineNum - 1); + int lineEndOffset = document.getLineEndOffset(lineNum - 1); + int num = calWhitespaceNum(document, offset, lineEndOffset); + needInsert = needInsert(lineNum); + if (needInsert) { + WriteCommandAction.runWriteCommandAction(project, () -> { + document.insertString(offset + num, "\n" + Strings.repeat(" ", num)); + PsiDocumentManager.getInstance(project).commitDocument(document); + incrNum++; + }); + offset += num; + } + end = false; + } else if (isEnterOrSpace(str)) { + //忽略 + } else if (isEndStr(str)) { + end = true; + needInsert = true; + } else { + //输入 + if (needInsert) { + WriteCommandAction.runWriteCommandAction(project, () -> { + document.insertString(offset, str); + PsiDocumentManager.getInstance(project).commitDocument(document); + offset += str.length(); + }); + } + } + + + } + + private boolean needInsert(int lineNum) { + boolean checkAnno = Boolean.valueOf(this.promptInfo.getLabels().getOrDefault("check_anno", "false")); + if (checkAnno) { + String currContent = this.getLineContent(document, lineNum); + PsiJvmModifiersOwner pmo = null; + if (CodeService.isClass(currContent)) { + pmo = CodeService.getPsiClassWithLineNum(project, document, lineNum); + } else if (CodeService.isPrivateField(currContent)) { + pmo = CodeService.getPsiFieldWithLineNum(project, document, lineNum); + } else { + pmo = CodeService.getPsiMethodWithLineNum(project, document, lineNum); + } + PsiJvmModifiersOwner pmot = pmo; + if (null != pmo) { + String[] array = this.promptInfo.getLabels().getOrDefault("skip", "").split(","); + return ApplicationManager.getApplication() + .runReadAction((Computable) () -> !Arrays.stream(pmot.getAnnotations()) + .filter(it -> Arrays.stream(array) + .filter(it2 -> it2.equals(it.getQualifiedName())).findAny().isPresent()) + .findAny().isPresent() + ); + } + } + return true; + } + + private boolean isEndStr(String str) { + return str.trim().equals("✓"); + } + + + private String getLineContent(Document document, int lineNumber) { + int startOffset = document.getLineStartOffset(lineNumber - 1); + int endOffset = document.getLineEndOffset(lineNumber - 1); + String lineContent = document.getText(new TextRange(startOffset, endOffset)); + return lineContent; + } + + private boolean needInsert(String content) { + String str = this.promptInfo.getLabels().getOrDefault("skip", ""); + if (StringUtils.isNotEmpty(str)) { + String[] array = str.split(","); + return !IntStream.range(0, array.length).filter(i -> content.contains(array[i])).findAny().isPresent(); + } + return true; + } + + + private int calWhitespaceNum(Document document, int lineStartOffset, int lineEndOffset) { + int num = 0; + String lineText = document.getText(new TextRange(lineStartOffset, lineEndOffset)); + for (int i = 0; i < lineText.length(); i++) { + if (!Character.isWhitespace(lineText.charAt(i))) { + break; + } + num++; + } + return num; + } + + + private boolean isNum(String str) { + str = str.trim(); + try { + Integer.parseInt(str); + return true; + } catch (Throwable ex) { + return false; + } + } + + private boolean isEnterOrSpace(String str) { + return str.trim().equals("\n") || "".equals(str.trim()); + } + + private String removeEnter(String str) { + return str.replaceAll("\n", ""); + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/common/CodeUtils.java b/athena-all/src/main/java/run/mone/ultraman/common/CodeUtils.java new file mode 100644 index 000000000..6af6d2ea2 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/common/CodeUtils.java @@ -0,0 +1,56 @@ +package run.mone.ultraman.common; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2023/4/20 23:01 + */ +public class CodeUtils { + + public static String format(String code) { + return code.replaceFirst("\n+", "").replaceAll("import.*\n",""); + } + + public static String formatRemoveEnter(String code) { + return code.replaceFirst("\n+", ""); + } + + public static String formatRemoveEnter1(String code) { + return code.replaceFirst(":\n+", ""); + } + + public static List getImportList(String code) { + return Arrays.stream(code.split("\n|;")).filter(it->it.startsWith("import")).map(it->it.replaceAll(";|import| ","")).collect(Collectors.toList()); + } + + public static List getImportList2(String code) { + return Arrays.stream(code.split("\n|;")).filter(it->it.startsWith("import")).map(it->it.replaceAll(";|import","")).collect(Collectors.toList()); + } + + public static String getComment(String code) { + return code.replaceAll("/\\*\\*|\\*/| +\\* ","").replaceAll("

","\n"); + } + + + public static void main(String[] args) { + String code = " /**\n" + + " * 方法作用:\n" + + " * 对两个整数进行求和操作\n" + + " *

\n" + + " * 方法参数:\n" + + " * 参数a和b分别为两个整数\n" + + " *

\n" + + " * 方法返回类型:\n" + + " * int\n" + + " *

\n" + + " * 方法逻辑:\n" + + " * 将参数a和参数b相加,并返回结果\n" + + " */"; + + System.out.println(getComment(code)); + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/common/Comment.java b/athena-all/src/main/java/run/mone/ultraman/common/Comment.java new file mode 100644 index 000000000..30756d2d6 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/common/Comment.java @@ -0,0 +1,55 @@ +package run.mone.ultraman.common; + +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.Project; +import lombok.Data; + +/** + * @author goodjava@qq.com + * @date 2023/5/26 16:47 + */ +@Data +public class Comment { + + private Document document; + + private int offset; + + private Project project; + + + public void append(String str) { + if (isNum(str)) { + //move + int lineNum = Integer.parseInt(str.trim()); + offset = document.getLineEndOffset(lineNum - 1); + } else if (isEnterOrSpace(str)) { + //忽略 + } else { + //输入 + WriteCommandAction.runWriteCommandAction(project, () -> { + document.insertString(offset, str); + offset += str.length(); + }); + } + + + } + + + private boolean isNum(String str) { + str = str.trim(); + try { + Integer.parseInt(str); + return true; + } catch (Throwable ex) { + return false; + } + } + + private boolean isEnterOrSpace(String str) { + return str.trim().equals("\n") || "".equals(str.trim()); + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/common/FunctionReqUtils.java b/athena-all/src/main/java/run/mone/ultraman/common/FunctionReqUtils.java new file mode 100644 index 000000000..115a370d8 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/common/FunctionReqUtils.java @@ -0,0 +1,44 @@ +package run.mone.ultraman.common; + +import com.google.common.collect.Maps; +import com.intellij.openapi.project.Project; +import run.mone.m78.ip.common.ConfigUtils; +import run.mone.m78.ip.util.GitUtils; +import run.mone.ultraman.AthenaContext; + +import java.util.List; +import java.util.Map; + +/** + * @author goodjava@qq.com + * @date 2023/12/18 20:31 + */ +public class FunctionReqUtils { + + + public static Map getCallScriptMap(String projectName, Map memary, Map promptLables) { + Map map = Maps.newHashMap(); + map.putAll(memary); + Project project = AthenaContext.ins().getProjectMap().get(projectName); + map.put("project", project); + map.put("_project", projectName); + map.put("projectName", projectName); + map.put("user", ConfigUtils.user()); + map.put("token", AthenaContext.ins().getToken()); + map.put("prompt_labels", promptLables); + map.put("memary", memary); + //这个项目的git地址 + map.put("gitUrl", GitUtils.getGitAddress(project)); + //这个项目最后一次提交的commitId + List commitList = GitUtils.getLastCommit(project); + String lastCommitId = ""; + if (commitList.size() > 0) { + lastCommitId = commitList.get(0); + lastCommitId = lastCommitId.substring(1, lastCommitId.length() - 1); + } + map.put("lastCommitId", lastCommitId); + return map; + } + + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/common/GitProjectOpener.java b/athena-all/src/main/java/run/mone/ultraman/common/GitProjectOpener.java new file mode 100644 index 000000000..b1cd0507c --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/common/GitProjectOpener.java @@ -0,0 +1,14 @@ +package run.mone.ultraman.common; + +import com.intellij.ide.impl.ProjectUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; + +import java.io.File; + +public class GitProjectOpener { + + public static void openGitProject(String projectPath) { + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/common/GsonUtils.java b/athena-all/src/main/java/run/mone/ultraman/common/GsonUtils.java new file mode 100644 index 000000000..276a94da4 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/common/GsonUtils.java @@ -0,0 +1,13 @@ +package run.mone.ultraman.common; + +import com.google.gson.Gson; + +/** + * @author goodjava@qq.com + * @date 2023/12/10 16:00 + */ +public class GsonUtils { + + public static Gson gson = new Gson(); + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/common/ImportCode.java b/athena-all/src/main/java/run/mone/ultraman/common/ImportCode.java new file mode 100644 index 000000000..cc059a12b --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/common/ImportCode.java @@ -0,0 +1,49 @@ +package run.mone.ultraman.common; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import run.mone.m78.ip.service.CodeService; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +/** + * @author goodjava@qq.com + *

+ * 带import的code + */ +@Data +@Slf4j +public class ImportCode { + + private Project project; + + private Editor editor; + + private StringBuilder importBuilder = new StringBuilder(); + + private boolean isImport = false; + + public void append(String str) { + if (isImportBegin(str)) { + isImport = true; + } else if (isImportEnd(str)) { + isImport = false; + log.info(importBuilder.toString()); + CodeService.addImport(this.project, this.editor, CodeUtils.getImportList2(importBuilder.toString())); + } else if (isImport) { + importBuilder.append(str); + } else { + CodeService.writeCode2(project, editor, str); + } + } + + private boolean isImportEnd(String str) { + return str.trim().equals("☽"); + } + + private boolean isImportBegin(String str) { + str = str.trim(); + return str.equals("☾"); + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/common/MyGotoActionAction.java b/athena-all/src/main/java/run/mone/ultraman/common/MyGotoActionAction.java new file mode 100644 index 000000000..4c523ad4b --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/common/MyGotoActionAction.java @@ -0,0 +1,18 @@ +package run.mone.ultraman.common; + +import com.intellij.ide.actions.GotoActionAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import org.jetbrains.annotations.NotNull; + +/** + * @author goodjava@qq.com + * @date 2023/4/20 17:29 + */ +public class MyGotoActionAction extends GotoActionAction { + + + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + super.actionPerformed(e); + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/common/PythonExecutor.java b/athena-all/src/main/java/run/mone/ultraman/common/PythonExecutor.java new file mode 100644 index 000000000..861def947 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/common/PythonExecutor.java @@ -0,0 +1,49 @@ +package run.mone.ultraman.common; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +/** + * @author goodjava@qq.com + * @date 2023/4/18 14:18 + */ +public class PythonExecutor { + + private static boolean open = false; + + + public static void run(String path, String param) { + if (!open) { + return; + } + System.out.println("param:" + param); + // 请将此路径替换为你的Python脚本路径 + String pythonScriptPath = path; + // 构建ProcessBuilder,以运行Python脚本 + try { + ProcessBuilder processBuilder = new ProcessBuilder("sh", pythonScriptPath, param); + // 启动进程 + Process process = processBuilder.start(); + // 获取进程的输出流 + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + // 读取并打印进程的输出 + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } + // 等待进程结束 + int exitCode = process.waitFor(); + System.out.println("Python script finished with exit code: " + exitCode); + } catch (IOException e) { + System.out.println("Error executing Python script: " + e.getMessage()); + } catch ( + InterruptedException e) { + System.out.println("Process interrupted: " + e.getMessage()); + } catch (Throwable ex) { + System.out.println(ex.getMessage()); + } + } + + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/common/SafeRun.java b/athena-all/src/main/java/run/mone/ultraman/common/SafeRun.java new file mode 100644 index 000000000..d5e69d81b --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/common/SafeRun.java @@ -0,0 +1,17 @@ +package run.mone.ultraman.common; + +/** + * @author goodjava@qq.com + * @date 2023/4/19 14:30 + */ +public class SafeRun { + + public static void run(Runnable runnable) { + try { + runnable.run(); + } catch (Throwable ex) { + ex.printStackTrace(); + } + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/common/SearchUtils.java b/athena-all/src/main/java/run/mone/ultraman/common/SearchUtils.java new file mode 100644 index 000000000..c4c566a76 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/common/SearchUtils.java @@ -0,0 +1,20 @@ +package run.mone.ultraman.common; + +import com.intellij.ide.actions.GotoActionAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.project.Project; + +/** + * @author goodjava@qq.com + * @date 2023/4/20 16:54 + */ +public class SearchUtils { + + public static void search(Project project,String searchData) { + GotoActionAction gotoActionAction = new MyGotoActionAction(); + AnActionEvent anAction = ActionEventUtils.createAnAction(project,searchData); + gotoActionAction.actionPerformed(anAction); + } + + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/common/TemplateUtils.java b/athena-all/src/main/java/run/mone/ultraman/common/TemplateUtils.java new file mode 100644 index 000000000..62ddd7cc4 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/common/TemplateUtils.java @@ -0,0 +1,57 @@ +package run.mone.ultraman.common; + +import com.google.common.collect.Maps; +import org.apache.commons.compress.utils.Lists; +import org.beetl.core.Configuration; +import org.beetl.core.Function; +import org.beetl.core.GroupTemplate; +import org.beetl.core.Template; +import org.beetl.core.resource.StringTemplateResourceLoader; + +import java.util.List; +import java.util.Map; +import java.util.UUID; + +/** + * @author goodjava@qq.com + * @date 2023/5/30 13:23 + */ +public class TemplateUtils { + + + public static String renderTemplate(String template, Map m) { + return renderTemplate(template, m, Lists.newArrayList()); + } + + public static String renderTemplate(String template, Map m, List functionList) { + try { + StringTemplateResourceLoader resourceLoader = new StringTemplateResourceLoader(); + Configuration cfg = Configuration.defaultConfiguration(); + GroupTemplate gt = new GroupTemplate(resourceLoader, cfg, cfg.getClass().getClassLoader()); + functionList.forEach(it -> gt.registerFunction(it.toString(), it)); + Template t = gt.getTemplate(template); + m.forEach((k, v) -> t.binding(k, v)); + String str = t.render(); + return str; + } catch (Throwable ex) { + ex.printStackTrace(); + } + return ""; + } + + public static Map getParams(String template) { + try { + StringTemplateResourceLoader resourceLoader = new StringTemplateResourceLoader(); + Configuration cfg = Configuration.defaultConfiguration(); + GroupTemplate gt = new GroupTemplate(resourceLoader, cfg); + Template t = gt.getTemplate(template); + Map map = t.program.metaData.globalIndexMap; + return map; + } catch (Throwable ex) { + ex.printStackTrace(); + } + return Maps.newHashMap(); + } + + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/common/beetl/AthenaFunction.java b/athena-all/src/main/java/run/mone/ultraman/common/beetl/AthenaFunction.java new file mode 100644 index 000000000..c3dc56adf --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/common/beetl/AthenaFunction.java @@ -0,0 +1,20 @@ +package run.mone.ultraman.common.beetl; + +import org.beetl.core.Context; +import org.beetl.core.Function; + +/** + * @author goodjava@qq.com + * @date 2023/8/13 22:07 + */ +public class AthenaFunction implements Function { + @Override + public Object call(Object[] paras, Context ctx) { + return "hello " + paras[0]; + } + + @Override + public String toString() { + return "athena"; + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/event/AthenaEventBus.java b/athena-all/src/main/java/run/mone/ultraman/event/AthenaEventBus.java new file mode 100644 index 000000000..5b931d63e --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/event/AthenaEventBus.java @@ -0,0 +1,36 @@ +package run.mone.ultraman.event; + +import com.google.common.eventbus.EventBus; +import lombok.Getter; + +/** + * @author goodjava@qq.com + * @date 2023/6/24 10:48 + */ +public class AthenaEventBus { + + private EventBus eventBus; + + @Getter + private EventListener listener; + + private AthenaEventBus() { + eventBus = new EventBus(); + this.listener = new EventListener(); + eventBus.register(this.listener); + } + + private static final class LazyHolder{ + private static final AthenaEventBus ins = new AthenaEventBus(); + } + + public static final AthenaEventBus ins() { + return LazyHolder.ins; + } + + + public void post(Object obj) { + eventBus.post(obj); + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/event/ConsumerBo.java b/athena-all/src/main/java/run/mone/ultraman/event/ConsumerBo.java new file mode 100644 index 000000000..387fa60d0 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/event/ConsumerBo.java @@ -0,0 +1,18 @@ +package run.mone.ultraman.event; + +import lombok.Data; + +import java.util.function.Consumer; + +/** + * @author goodjava@qq.com + * @date 2023/6/24 21:49 + */ +@Data +public class ConsumerBo { + + private String type; + + private Consumer consumer; + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/event/EventListener.java b/athena-all/src/main/java/run/mone/ultraman/event/EventListener.java new file mode 100644 index 000000000..5fdf8c63e --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/event/EventListener.java @@ -0,0 +1,76 @@ +package run.mone.ultraman.event; + +import com.google.common.eventbus.Subscribe; +import run.mone.m78.ip.bo.ClassInfo; +import run.mone.m78.ip.bo.ValueInfo; +import lombok.Getter; +import run.mone.ultraman.bo.PackageInfo; +import run.mone.ultraman.bo.ParamsInfo; + +import java.util.function.Consumer; + +/** + * @author goodjava@qq.com + * @date 2023/6/24 10:49 + */ +public class EventListener { + + @Getter + private Consumer packageConsumer; + + @Getter + private Consumer classConsumer; + + @Getter + private Consumer valueInfoConsumer; + + @Getter + private Consumer paramsInfoConsumer; + + @Subscribe + public void listenSelectPackage(PackageInfo packageInfo) { + if (null != packageConsumer) { + packageConsumer.accept(packageInfo); + this.packageConsumer = null; + } + } + + @Subscribe + public void listenParamsInfo(ParamsInfo paramsInfo) { + if (null != paramsInfoConsumer) { + paramsInfoConsumer.accept(paramsInfo); + this.paramsInfoConsumer = null; + } + } + + @Subscribe + public void listenSelectClass(ClassInfo ci) { + if (null != classConsumer) { + classConsumer.accept(ci); + this.classConsumer = null; + } + } + + @Subscribe + public void listenValueInfo(ValueInfo ci) { + if (null != valueInfoConsumer) { + valueInfoConsumer.accept(ci); + this.valueInfoConsumer = null; + } + } + + @Subscribe + public void listenConsumer(ConsumerBo bo) { + if ("params".equals(bo.getType())) { + this.paramsInfoConsumer = bo.getConsumer(); + } else if ("class".equals(bo.getType())) { + this.classConsumer = bo.getConsumer(); + } else if ("value".equals(bo.getType())) { + this.valueInfoConsumer = bo.getConsumer(); + } else { + this.packageConsumer = bo.getConsumer(); + } + } + + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/http/HttpClient.java b/athena-all/src/main/java/run/mone/ultraman/http/HttpClient.java new file mode 100644 index 000000000..065659862 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/http/HttpClient.java @@ -0,0 +1,179 @@ +package run.mone.ultraman.http; + +import com.google.common.base.Stopwatch; +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import run.mone.m78.ip.common.ConfigUtils; +import run.mone.m78.ip.common.NotificationCenter; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import okhttp3.*; +import org.jetbrains.annotations.NotNull; +import run.mone.ultraman.AthenaContext; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; + +/** + * @author goodjava@qq.com + * @date 2023/4/26 22:16 + */ +@Slf4j +public class HttpClient { + + private static Gson gson = new Gson(); + + @SneakyThrows + public static String callAiProxy(String action, Map params) { + String url = ConfigUtils.getConfig().getAiProxy() + "/" + action; + JsonObject r = new JsonObject(); + params.forEach((k, v) -> r.addProperty(k, v)); + String json = gson.toJson(r); + return callHttpServer(url, action, json); + } + + public static String callZServer(String url, String action, String request) { + return callHttpServer(url, action, request); + } + + + public static String get(String url) { + return get(url, false); + } + + + public static String get(String url, boolean useToken) { + OkHttpClient client = new OkHttpClient(); + Request.Builder requestBuilder = new Request.Builder(); + if (useToken) { + requestBuilder.header("athena_token", AthenaContext.ins().getToken()); + } + requestBuilder.url(url); + try (Response response = client.newCall(requestBuilder.build()).execute()) { + if (!response.isSuccessful()) { + return "error"; + } + return response.body().string(); + } catch (Exception e) { + return ""; + } + } + + public static String callHttpServer(String url, String action, String req) { + return callHttpServer(url, action, req, true); + } + + public static String callHttpServer(String url, String action, String req, boolean notify) { + return callHttpServer(url, action, req, notify, false); + } + + + @SneakyThrows + public static String callHttpServer(String url, String action, String req, boolean notify, boolean useToken) { + log.info("call action:{}", action); + Stopwatch sw = Stopwatch.createStarted(); + try { + OkHttpClient client = new OkHttpClient.Builder() + .connectTimeout(5, TimeUnit.SECONDS) + .readTimeout(5, TimeUnit.SECONDS) + .writeTimeout(5, TimeUnit.SECONDS) + .build(); + RequestBody body = RequestBody.create(MediaType.parse("application/json"), req); + Request.Builder requestBuilder = new Request.Builder(); + if (useToken) { + requestBuilder.header("athena_token", AthenaContext.ins().getToken()); + } + requestBuilder.url(url); + requestBuilder.post(body); + requestBuilder.build(); + Call call = client.newCall(requestBuilder.build()); + Response response = call.execute(); + String res = response.body().string(); + return res; + } catch (Throwable ex) { + log.error(ex.getMessage(), ex); + return ex.getMessage(); + } finally { + long useTime = sw.elapsed(TimeUnit.MILLISECONDS); + if (notify) { + NotificationCenter.notice(null, "call http server action " + action + " use time:" + useTime + "ms", true); + } + } + } + + public static String post(String url, String req) { + return callHttpServer(url, "", req, false); + } + + public static String post(String url, String req, boolean useToken) { + return callHttpServer(url, "", req, false, useToken); + } + + + @SneakyThrows + public static void asyncCallHttpServer(String url, String action, String req, Consumer consumer) { + log.info("call action:{}", action); + Stopwatch sw = Stopwatch.createStarted(); + try { + OkHttpClient client = new OkHttpClient.Builder() + .connectTimeout(5, TimeUnit.SECONDS) + .readTimeout(5, TimeUnit.SECONDS) + .writeTimeout(5, TimeUnit.SECONDS) + .build(); + RequestBody body = RequestBody.create(MediaType.parse("application/json"), req); + Request request = new Request.Builder() + .url(url) + .post(body) + .build(); + client.newCall(request).enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + log.info("call http async error:{}", e.getMessage()); + consumer.accept(e.getMessage()); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { + log.info("call http async success"); + consumer.accept("success"); + } + }); + + } finally { + long useTime = sw.elapsed(TimeUnit.MILLISECONDS); + NotificationCenter.notice(null, "call http server action " + action + " use time:" + useTime + "ms", true); + } + } + + + public static String callChatgml(String req) throws IOException { + OkHttpClient client = new OkHttpClient.Builder() + .connectTimeout(120, TimeUnit.SECONDS) + .readTimeout(120, TimeUnit.SECONDS) + .writeTimeout(120, TimeUnit.SECONDS) + .build(); + + JsonObject r = new JsonObject(); + r.addProperty("prompt", req); + r.add("history", new JsonArray()); + + String json = gson.toJson(r); + RequestBody body = RequestBody.create( + MediaType.parse("application/json"), json); + + String url = ConfigUtils.getConfig().getJavaPath(); + + Request request = new Request.Builder() + .url(url) + .post(body) + .build(); + Call call = client.newCall(request); + Response response = call.execute(); + String res = response.body().string(); + return gson.fromJson(res, JsonObject.class).get("response").getAsString(); + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/http/HttpResponseUtils.java b/athena-all/src/main/java/run/mone/ultraman/http/HttpResponseUtils.java new file mode 100644 index 000000000..03ea8e5cf --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/http/HttpResponseUtils.java @@ -0,0 +1,24 @@ +package run.mone.ultraman.http; + +import io.netty.buffer.Unpooled; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.FullHttpResponse; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.HttpVersion; + +/** + * @author goodjava@qq.com + * @date 2023/4/19 17:43 + */ +public class HttpResponseUtils { + + + public static FullHttpResponse createResponse(HttpResponseStatus status,String data) { + FullHttpResponse response = new DefaultFullHttpResponse( + HttpVersion.HTTP_1_1, + status, + Unpooled.wrappedBuffer(data.getBytes())); + return response; + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/http/Param.java b/athena-all/src/main/java/run/mone/ultraman/http/Param.java new file mode 100644 index 000000000..fd64407b9 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/http/Param.java @@ -0,0 +1,96 @@ +package run.mone.ultraman.http; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.QueryStringDecoder; +import org.apache.commons.lang3.tuple.Pair; + +import java.io.Serializable; +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/4/19 14:44 + */ +public class Param implements Serializable { + + private Gson gson = new Gson(); + + private String cmd; + + private String param; + + private String path; + + private String v = ""; + + public void decode(FullHttpRequest req) { + QueryStringDecoder decoder = new QueryStringDecoder(req.uri()); + this.path = decoder.path().replaceAll("/", ""); + List cmdList = decoder.parameters().get("cmd"); + if (null != cmdList && cmdList.size() > 0) { + this.cmd = cmdList.get(0); + } + List vList = decoder.parameters().get("v"); + if (null != vList && vList.size() > 0) { + this.v = vList.get(0); + } + List paramList = decoder.parameters().get("param"); + if (null != paramList && paramList.size() > 0) { + this.param = paramList.get(0); + } + } + + public Pair getPathAndParam(String res) { + String param = ""; + String path = ""; + try { + int i = res.indexOf("{"); + if (i > 0) { + res = res.substring(i); + } + JsonObject obj = gson.fromJson(res, JsonObject.class); + path = obj.get("cmd2").getAsString(); + if (null != obj.get("param")) { + param = obj.get("param").getAsString(); + } + return Pair.of(path, param); + } catch (Throwable ex) { + ex.printStackTrace(); + } + return Pair.of(path, param); + } + + public String getCmd() { + return cmd; + } + + public void setCmd(String cmd) { + this.cmd = cmd; + } + + public String getParam() { + return param; + } + + public void setParam(String param) { + this.param = param; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getV() { + return v; + } + + public void setV(String v) { + this.v = v; + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/listener/AthenaApplicationActivationListener.java b/athena-all/src/main/java/run/mone/ultraman/listener/AthenaApplicationActivationListener.java new file mode 100644 index 000000000..72fa8c7a9 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/listener/AthenaApplicationActivationListener.java @@ -0,0 +1,68 @@ +package run.mone.ultraman.listener; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.application.ApplicationActivationListener; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Caret; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.editor.actionSystem.EditorActionManager; +import com.intellij.openapi.wm.IdeFrame; +import run.mone.m78.ip.service.CodeService; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import run.mone.ultraman.manager.InlayHintManager; + +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * @author goodjava@qq.com + * @date 2023/7/27 22:34 + */ +public class AthenaApplicationActivationListener implements ApplicationActivationListener { + + + private AtomicBoolean init = new AtomicBoolean(false); + + + @Override + public void applicationActivated(@NotNull IdeFrame ideFrame) { + if (init.compareAndSet(false, true)) { + ApplicationManager.getApplication().executeOnPooledThread(() -> { + //用来捕获 editor中输入enter + EditorActionManager actionManager = EditorActionManager.getInstance(); + EditorActionHandler originalEnterHandler = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_ENTER); + actionManager.setActionHandler(IdeActions.ACTION_EDITOR_ENTER, new EditorActionHandler() { + @Override + protected void doExecute(@NotNull Editor editor, @Nullable Caret caret, DataContext dataContext) { + String text = InlayHintManager.ins().getHintText(); + if (StringUtils.isNotEmpty(text)) { + CodeService.insertCode(editor.getProject(), text, false); + CodeService.deleteCode(editor); + CodeService.formatCode(editor.getProject()); + InlayHintManager.ins().dispose(); + } else { + originalEnterHandler.execute(editor, caret, dataContext); + } + } + }); + + //用来捕获 editor中输入esc + EditorActionHandler originalEscapeHandler = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_ESCAPE); + actionManager.setActionHandler(IdeActions.ACTION_EDITOR_ESCAPE, new EditorActionHandler() { + @Override + public void doExecute(@NotNull Editor editor, @Nullable Caret caret, DataContext dataContext) { + if (null != InlayHintManager.ins().getInlay()) { + CodeService.deleteCode(editor); + CodeService.formatCode(editor.getProject()); + InlayHintManager.ins().dispose(); + } + originalEscapeHandler.execute(editor, dataContext); + } + }); + }); + } + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/listener/AthenaFileDocumentManagerListener.java b/athena-all/src/main/java/run/mone/ultraman/listener/AthenaFileDocumentManagerListener.java new file mode 100644 index 000000000..d09c99423 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/listener/AthenaFileDocumentManagerListener.java @@ -0,0 +1,19 @@ +package run.mone.ultraman.listener; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManagerListener; +import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; + +/** + * @author goodjava@qq.com + * @date 2023/7/14 10:25 + */ +@Slf4j +public class AthenaFileDocumentManagerListener implements FileDocumentManagerListener { + + @Override + public void beforeDocumentSaving(@NotNull Document document) { + log.debug(document.getText()); + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/listener/AthenaFileEditorManagerListener.java b/athena-all/src/main/java/run/mone/ultraman/listener/AthenaFileEditorManagerListener.java new file mode 100644 index 000000000..8d9b2fc75 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/listener/AthenaFileEditorManagerListener.java @@ -0,0 +1,39 @@ +package run.mone.ultraman.listener; + +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.FileEditorManagerListener; +import com.intellij.openapi.vfs.VirtualFile; +import run.mone.m78.ip.bo.ValueInfo; +import run.mone.m78.ip.common.Const; +import run.mone.m78.ip.common.Safe; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; +import run.mone.ultraman.event.AthenaEventBus; +import run.mone.ultraman.service.AutoFlushBizService; + +/** + * @author goodjava@qq.com + * @date 2023/7/14 11:21 + */ +@Slf4j +public class AthenaFileEditorManagerListener implements FileEditorManagerListener { + + @Override + public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile file) { + AutoFlushBizService.notifyDocumentClosed(file, source.getProject()); + String data = file.getUserData(Const.T_KEY); + if (StringUtils.isNotEmpty(data)) { + Safe.run(() -> { + if (AthenaEventBus.ins().getListener().getValueInfoConsumer() != null) { + String text = FileDocumentManager.getInstance().getDocument(file).getText(); + log.info(text); + ValueInfo pi = new ValueInfo(); + pi.setValue(text); + AthenaEventBus.ins().post(pi); + } + }); + } + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/listener/AthenaMessageListener.java b/athena-all/src/main/java/run/mone/ultraman/listener/AthenaMessageListener.java new file mode 100644 index 000000000..82fdba7b7 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/listener/AthenaMessageListener.java @@ -0,0 +1,16 @@ +package run.mone.ultraman.listener; + +import run.mone.ultraman.listener.bo.AthenaMessage; + + +/** + * @author goodjava@qq.com + * @date 2023/7/14 14:52 + */ +public interface AthenaMessageListener { + + + void handleMessage(AthenaMessage message); + + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/listener/AthenaMessageListenerImpl.java b/athena-all/src/main/java/run/mone/ultraman/listener/AthenaMessageListenerImpl.java new file mode 100644 index 000000000..06b59dbbf --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/listener/AthenaMessageListenerImpl.java @@ -0,0 +1,37 @@ +package run.mone.ultraman.listener; + +import com.intellij.openapi.application.ApplicationManager; +import lombok.extern.slf4j.Slf4j; +import run.mone.ultraman.listener.bo.AthenaMessage; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; + +/** + * @author goodjava@qq.com + * @date 2023/7/14 15:24 + */ +@Slf4j +public class AthenaMessageListenerImpl implements AthenaMessageListener { + + private ConcurrentHashMap consumerMap = new ConcurrentHashMap<>(); + + @Override + public void handleMessage(AthenaMessage message) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + log.info("Received message: " + message); + if (message.getType().equals("reg")) { + consumerMap.put(message.getName(),message.getConsumer()); + } + + if (message.getType().equals("unreg")) { + consumerMap.get(message.getName()).accept(null); + } + + } + }); + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/listener/AthenaProjectManagerListener.java b/athena-all/src/main/java/run/mone/ultraman/listener/AthenaProjectManagerListener.java new file mode 100644 index 000000000..55dd879e0 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/listener/AthenaProjectManagerListener.java @@ -0,0 +1,40 @@ +package run.mone.ultraman.listener; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManagerListener; +import run.mone.m78.ip.bo.robot.AiMessageManager; +import run.mone.m78.ip.bo.robot.ProjectAiMessageManager; +import run.mone.m78.ip.common.ConfigUtils; +import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; +import run.mone.ultraman.AthenaContext; +import run.mone.ultraman.state.FsmManager; +import run.mone.ultraman.state.ProjectFsmManager; + +/** + * @author goodjava@qq.com + * @date 2023/6/25 23:29 + */ +@Slf4j +public class AthenaProjectManagerListener implements ProjectManagerListener { + + + @Override + public void projectOpened(Project project) { + log.info("Project reopened: " + project.getName()); + AthenaContext.ins().getProjectMap().put(project.getName(), project); + AthenaContext.ins().setGptModel(ConfigUtils.getConfig().getModel()); + ProjectAiMessageManager.getInstance().putMessageManager(project.getName(), new AiMessageManager()); + FsmManager fsmManager = new FsmManager(); + fsmManager.setProject(project.getName()); + fsmManager.init(); + ProjectFsmManager.map.put(project.getName(), fsmManager); + } + + @Override + public void projectClosed(@NotNull Project project) { + AthenaContext.ins().getProjectMap().remove(project.getName()); + ProjectAiMessageManager.getInstance().removeMessageManager(project.getName()); + ProjectFsmManager.map.remove(project.getName()); + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/listener/bo/AthenaMessage.java b/athena-all/src/main/java/run/mone/ultraman/listener/bo/AthenaMessage.java new file mode 100644 index 000000000..e6eca89ba --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/listener/bo/AthenaMessage.java @@ -0,0 +1,22 @@ +package run.mone.ultraman.listener.bo; + +import lombok.Data; + +import java.io.Serializable; +import java.util.function.Consumer; + +/** + * @author goodjava@qq.com + * @date 2023/7/14 14:54 + */ +@Data +public class AthenaMessage implements Serializable { + + private String type; + + private String name; + + private Consumer consumer; + + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/manager/AthenaTypedActionHandler.java b/athena-all/src/main/java/run/mone/ultraman/manager/AthenaTypedActionHandler.java new file mode 100644 index 000000000..499acf12b --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/manager/AthenaTypedActionHandler.java @@ -0,0 +1,23 @@ +package run.mone.ultraman.manager; + +import com.intellij.codeInsight.editorActions.TypedHandlerDelegate; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.NotNull; + +/** + * @author goodjava@qq.com + * @date 2023/7/21 14:21 + */ +public class AthenaTypedActionHandler extends TypedHandlerDelegate { + + + @Override + public @NotNull Result charTyped(char c, @NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) { + System.out.println(c); + return super.charTyped(c, project, editor, file); + } + + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/manager/ConsoleViewManager.java b/athena-all/src/main/java/run/mone/ultraman/manager/ConsoleViewManager.java new file mode 100644 index 000000000..6a292ba3e --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/manager/ConsoleViewManager.java @@ -0,0 +1,48 @@ +package run.mone.ultraman.manager; + +import com.intellij.execution.ExecutionManager; +import com.intellij.execution.impl.ConsoleViewImpl; +import com.intellij.execution.testframework.ui.BaseTestsOutputConsoleView; +import com.intellij.execution.ui.ConsoleView; +import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.NlsSafe; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author goodjava@qq.com + * @date 2023/6/9 11:36 + */ +public class ConsoleViewManager { + + + public static String getSelectedText(Project project) { + try { + ExecutionManager executionManager = ExecutionManager.getInstance(project); + RunContentDescriptor currentDescriptor = executionManager.getContentManager().getSelectedContent(); + ConsoleView consoleView = (ConsoleView) currentDescriptor.getExecutionConsole(); + if (consoleView instanceof BaseTestsOutputConsoleView) { + BaseTestsOutputConsoleView btocv = (BaseTestsOutputConsoleView) consoleView; + @NotNull ConsoleView console = btocv.getConsole(); + if (console instanceof ConsoleViewImpl) { + return getText((ConsoleViewImpl) console); + } + } + + if (consoleView instanceof ConsoleViewImpl) { + return getText((ConsoleViewImpl) consoleView); + } + } catch (Throwable ignore) { + + } + return null; + } + + + private static String getText(ConsoleViewImpl cv) { + @Nullable @NlsSafe String text = cv.getEditor().getSelectionModel().getSelectedText(); + System.out.println(text); + return text; + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/manager/InlayHintManager.java b/athena-all/src/main/java/run/mone/ultraman/manager/InlayHintManager.java new file mode 100644 index 000000000..b1dfa8dd3 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/manager/InlayHintManager.java @@ -0,0 +1,45 @@ +package run.mone.ultraman.manager; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.Inlay; +import com.intellij.openapi.editor.InlayModel; +import lombok.Getter; +import run.mone.ultraman.render.AthenaInlayRenderer; + +/** + * @author goodjava@qq.com + * @date 2023/7/21 14:07 + */ +public class InlayHintManager { + + @Getter + private Inlay inlay; + + @Getter + private String hintText; + + + private static final class LazyHolder { + private static final InlayHintManager ins = new InlayHintManager(); + } + + public static final InlayHintManager ins() { + return LazyHolder.ins; + } + + public void dispose() { + if (null != inlay) { + inlay.dispose(); + this.hintText = null; + } + } + + + public Inlay addInlayHint(Editor editor, int offset, String hintText) { + InlayModel inlayModel = editor.getInlayModel(); + this.hintText = hintText; + inlay = inlayModel.addInlineElement(offset, true, new AthenaInlayRenderer(hintText, editor)); + return inlay; + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/manager/MemoryManager.java b/athena-all/src/main/java/run/mone/ultraman/manager/MemoryManager.java new file mode 100644 index 000000000..f6f70c508 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/manager/MemoryManager.java @@ -0,0 +1,33 @@ +package run.mone.ultraman.manager; + +/** + * @author goodjava@qq.com + * @date 2023/4/18 17:06 + */ +public class MemoryManager { + + private MemoryManager() { + + } + + + private String module; + + + private static MemoryManager ins() { + return LazyHolder.ins; + } + + + private static class LazyHolder { + private static MemoryManager ins = new MemoryManager(); + } + + public String getModule() { + return module; + } + + public void setModule(String module) { + this.module = module; + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/mysql/MySqlClient.java b/athena-all/src/main/java/run/mone/ultraman/mysql/MySqlClient.java new file mode 100644 index 000000000..25b02ea09 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/mysql/MySqlClient.java @@ -0,0 +1,30 @@ +package run.mone.ultraman.mysql; + +import lombok.SneakyThrows; +import org.nutz.dao.Sqls; +import org.nutz.dao.impl.NutDao; +import org.nutz.dao.impl.SimpleDataSource; +import org.nutz.dao.sql.Sql; + + +/** + * @author goodjava@qq.com + * @date 2023/12/21 00:14 + */ +public class MySqlClient { + + + @SneakyThrows + public static void createTable(String url, String userName, String password, String sqlStr) { + NutDao dao = new NutDao(); + SimpleDataSource dataSource = new SimpleDataSource(); + dataSource.setJdbcUrl(url); + dataSource.setUsername(userName); + dataSource.setPassword(password); + dataSource.setDriverClassName("com.mysql.jdbc.Driver"); + dao.setDataSource(dataSource); + Sql sql = Sqls.create(sqlStr); + dao.execute(sql); + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/quickfix/AthenaInspection.java b/athena-all/src/main/java/run/mone/ultraman/quickfix/AthenaInspection.java new file mode 100644 index 000000000..5f0e6bdec --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/quickfix/AthenaInspection.java @@ -0,0 +1,41 @@ +package run.mone.ultraman.quickfix; + +import com.intellij.codeInspection.LocalInspectionTool; +import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.psi.JavaElementVisitor; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiMethod; +import org.jetbrains.annotations.NotNull; + +/** + * @author goodjava@qq.com + * @date 2023/7/9 07:32 + */ +public class AthenaInspection extends LocalInspectionTool { + + @Override + public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) { + return new MyVisitor(holder); + } + + private static class MyVisitor extends JavaElementVisitor { + + private final ProblemsHolder holder; + + public MyVisitor(ProblemsHolder holder) { + this.holder = holder; + } + + @Override + public void visitMethod(PsiMethod method) { + super.visitMethod(method); + + // 检查方法名是否以大写字母开头 + if (Character.isUpperCase(method.getName().charAt(0))) { + holder.registerProblem(method.getNameIdentifier(), "Method name should start with a lowercase letter", ProblemHighlightType.WEAK_WARNING); + } + } + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/render/AthenaInlayRenderer.java b/athena-all/src/main/java/run/mone/ultraman/render/AthenaInlayRenderer.java new file mode 100644 index 000000000..7ff97b6c3 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/render/AthenaInlayRenderer.java @@ -0,0 +1,49 @@ +package run.mone.ultraman.render; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorCustomElementRenderer; +import com.intellij.openapi.editor.Inlay; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.colors.EditorFontType; +import com.intellij.openapi.editor.ex.util.EditorUtil; +import com.intellij.openapi.editor.markup.TextAttributes; +import org.jetbrains.annotations.NotNull; + +import java.awt.*; + +/** + * @author goodjava@qq.com + * @date 2023/7/21 14:08 + */ +public class AthenaInlayRenderer implements EditorCustomElementRenderer { + + private final String hintText; + + private final Editor editor; + + public AthenaInlayRenderer(String hintText, Editor editor) { + this.hintText = hintText; + this.editor = editor; + } + + @Override + public int calcWidthInPixels(@NotNull Inlay inlay) { + EditorColorsScheme colorsScheme = EditorColorsManager.getInstance().getGlobalScheme(); + Font font = colorsScheme.getFont(EditorFontType.PLAIN); + return EditorUtil.textWidth(editor, hintText, 0, hintText.length(), font.getStyle(), 0); + } + + + @Override + public void paint(@NotNull Inlay inlay, @NotNull Graphics g, @NotNull Rectangle r, @NotNull TextAttributes textAttributes) { + g.setColor(Color.RED); + String content = hintText; + String[] lines = content.split("\n"); + int fontHeight = g.getFontMetrics().getHeight(); + for (int i = 0; i < lines.length; i++) { + g.drawString(lines[i], r.x, r.y + i * fontHeight + fontHeight); + } + + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/service/AiCodeService.java b/athena-all/src/main/java/run/mone/ultraman/service/AiCodeService.java new file mode 100644 index 000000000..a6d1d9024 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/service/AiCodeService.java @@ -0,0 +1,35 @@ +package run.mone.ultraman.service; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import run.mone.m78.ip.bo.GenerateCodeReq; +import run.mone.m78.ip.bo.PromptInfo; +import run.mone.m78.ip.common.Prompt; +import run.mone.m78.ip.service.PromptService; + +/** + * @author goodjava@qq.com + * @date 2023/12/10 15:28 + */ +public class AiCodeService { + + public static void generateBizCode(String scope, Project project, String comment) { + ApplicationManager.getApplication().invokeLater(() -> PromptService.dynamicInvoke(getGenerateCodeReq(project, scope, comment))); + } + + + public static GenerateCodeReq getGenerateCodeReq(Project project, String scope, String comment) { + PromptInfo promptInfo = Prompt.getPromptInfo("biz_sidecar"); + return GenerateCodeReq.builder() + .scope(scope) + .chatComment(comment) + .project(project) + .promptInfo(promptInfo) + .promptName(promptInfo.getPromptName()) + .promptType(Prompt.getPromptType(promptInfo)) + .projectName(project.getName()) + .build(); + } + + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/service/AthenaCodeService.java b/athena-all/src/main/java/run/mone/ultraman/service/AthenaCodeService.java new file mode 100644 index 000000000..74ba3d2f9 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/service/AthenaCodeService.java @@ -0,0 +1,120 @@ +package run.mone.ultraman.service; + +import com.github.javaparser.JavaParser; +import com.github.javaparser.ParseResult; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.*; +import com.github.javaparser.ast.comments.Comment; +import com.google.common.hash.Hashing; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.intellij.openapi.project.Project; +import run.mone.m78.ip.bo.AiMessage; +import run.mone.m78.ip.bo.MessageConsumer; +import run.mone.m78.ip.bo.z.EmbeddingStatus; +import run.mone.m78.ip.bo.z.ZKnowledgeRes; +import run.mone.m78.ip.bo.z.ZResult; +import run.mone.m78.ip.common.NotificationCenter; +import run.mone.m78.ip.service.CodeService; +import it.unimi.dsi.fastutil.Pair; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.compress.utils.Lists; +import run.mone.ultraman.AthenaContext; +import run.mone.ultraman.bo.*; +import run.mone.ultraman.http.HttpClient; + +import java.lang.reflect.Type; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2023/11/5 22:36 + */ +@Slf4j +public class AthenaCodeService { + + private static Gson gson = new Gson(); + + + public static final boolean openCodeServer = true; + + public static final int CLASS_MAX_LEN = 3000; + + + public static String getCodeServer() { + return AthenaContext.ins().getZAddr(); + } + + + @SneakyThrows + public static Pair callProxy(Project project, Map map, String promptName, int timeout) { + return null; + } + + + //解析代码,返回一个列表,每个元素包含一个类信息和对应的代码字符串 + public static List> parseCode(String code) { + return null; + } + + public static AthenaClassInfo classInfo(String code) { + return null; + } + + + public static String parseAndSkipCode(String code) { + return ""; + } + + //解析方法代码,返回一个包含AthenaMethodInfo对象的列表 + public static List parseMethodCode(String code) { + return null; + } + + //解析方法代码,返回一个包含AthenaMethodInfo对象的列表 + public static List parseFieldCode(String code) { + return null; + } + + + //使用MD5算法对输入的字符串进行哈希计算 + public static String md5(String code) { + return Hashing.md5().hashString(code, StandardCharsets.UTF_8).toString(); + } + + //上传方法代码的实现 + public static void uploadMethodCode(CodeReq req) { + } + + //获取方法代码列表 + public static List getMethodCodeList(CodeReq req) { + return null; + } + + + public static EmbeddingStatus embeddingStatus(CodeReq req) { + return null; + } + + + //上传代码到服务器(那边的服务器会计算向量) + public static void uploadCode(CodeReq req) { + } + + //获取和这次业务相关的代码(根据需求取回相应的代码片段) + public static List getCodeList(CodeReq req) { + return Lists.newArrayList(); + } + + + public static List callSimilar(CodeReq req) { + return null; + } + + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/service/AutoFlushBizService.java b/athena-all/src/main/java/run/mone/ultraman/service/AutoFlushBizService.java new file mode 100644 index 000000000..e5288ae6c --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/service/AutoFlushBizService.java @@ -0,0 +1,37 @@ +package run.mone.ultraman.service; + +import com.intellij.ide.highlighter.JavaFileType; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import run.mone.m78.ip.util.LabelUtils; +import lombok.extern.slf4j.Slf4j; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author wmin + * @date 2023/11/21 + */ +@Slf4j +public class AutoFlushBizService { + + final static ConcurrentHashMap> fileChangeStatus = new ConcurrentHashMap<>(); + + static String CHANGED = "changed"; + + public static void notifyDocumentChanged(VirtualFile file){ + } + + public static void notifyDocumentClosed(VirtualFile file, Project project){ + + } + + public static void autoFlushBiz(VirtualFile file, Project project){ + Module module = ModuleUtil.findModuleForFile(file, project); + ModuleService.uploadFileText(project, module, file); + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/service/ModuleService.java b/athena-all/src/main/java/run/mone/ultraman/service/ModuleService.java new file mode 100644 index 000000000..be46af1be --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/service/ModuleService.java @@ -0,0 +1,76 @@ +package run.mone.ultraman.service; + +import com.google.common.base.Joiner; +import com.google.common.collect.Lists; +import com.intellij.ide.highlighter.JavaFileType; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.Task; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiJavaFile; +import com.intellij.psi.PsiManager; +import run.mone.m78.ip.common.Const; +import run.mone.m78.ip.common.NotificationCenter; +import run.mone.m78.ip.service.TextService; +import run.mone.m78.ip.util.LabelUtils; +import run.mone.m78.ip.util.PsiClassUtils; +import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; +import run.mone.ultraman.background.AthenaTask; +import run.mone.ultraman.bo.CodeReq; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/11/2 16:03 + */ +@Slf4j +public class ModuleService { + + + /** + * 上传单个java file 到 code server + * + * @param project + * @param module + * @param file + */ + public static void uploadFileText(Project project, Module module, VirtualFile file) { + + } + + + /** + * 获取整个model的文本描述,并上传到codeserver(主要是接口内容) + * + * @param project + * @param module + */ + public static void uploadModelText(Project project, Module module) { + + } + + private static void sendToCodeServer(List list, Project project, Module module, String type) { + + } + + + public static String javaFileText(Project project, Module module, VirtualFile virtualFile) { + return ""; + } + + + public static String classText(Project project, PsiClass psiClass) { + return ""; + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/state/ActionType.java b/athena-all/src/main/java/run/mone/ultraman/state/ActionType.java new file mode 100644 index 000000000..2a3c179da --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/state/ActionType.java @@ -0,0 +1,18 @@ +package run.mone.ultraman.state; + +/** + * @author goodjava@qq.com + * @date 2023/12/4 17:59 + */ +public enum ActionType { + //记忆到内存 + memary, + //仅仅打印输出 + print, + //执行方法 + method, + //直接退出了,不再操作了 + exit, + //跳过这次执行的function + skip, +} diff --git a/athena-all/src/main/java/run/mone/ultraman/state/AfterQuestionState.java b/athena-all/src/main/java/run/mone/ultraman/state/AfterQuestionState.java new file mode 100644 index 000000000..006587aa0 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/state/AfterQuestionState.java @@ -0,0 +1,35 @@ +package run.mone.ultraman.state; + +/** + * @author goodjava@qq.com + * @date 2023/12/17 12:32 + * + * 主要就是用来准备参数,已被后边的提问 + */ +public class AfterQuestionState extends AthenaState { + + + /** + * 执行一个function或者一个prompt + * + * @param req + * @param context + */ + @Override + public void execute(StateReq req, StateContext context) { + if (context.getPromptStep() < context.getFinishPromptStep()) { + String it = context.getBeforePrompt().get(context.getPromptStep()); + if (it.startsWith("_")) { + String promptName = it.substring(1); + PromptAndFunctionProcessor.prompt(promptName, context); + } else { + PromptAndFunctionProcessor.funciton(context, it); + } + context.setPromptStep(context.getPromptStep() + 1); + this.fsm.changeState(new WaitQuestionState("before")); + } else { + this.fsm.changeState(new WaitQuestionState(context)); + } + + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/state/AnswerState.java b/athena-all/src/main/java/run/mone/ultraman/state/AnswerState.java new file mode 100644 index 000000000..23efd1b6c --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/state/AnswerState.java @@ -0,0 +1,9 @@ +package run.mone.ultraman.state; + +/** + * @author goodjava@qq.com + * @date 2023/12/2 20:59 + * 回答问题模式 + */ +public class AnswerState extends AthenaState{ +} diff --git a/athena-all/src/main/java/run/mone/ultraman/state/AnswerType.java b/athena-all/src/main/java/run/mone/ultraman/state/AnswerType.java new file mode 100644 index 000000000..1a86b1487 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/state/AnswerType.java @@ -0,0 +1,12 @@ +package run.mone.ultraman.state; + +/** + * @author goodjava@qq.com + * @date 2023/12/3 11:22 + */ +public enum AnswerType { + normal, + cmd, + //空答案 + empty, +} diff --git a/athena-all/src/main/java/run/mone/ultraman/state/AthenaEvent.java b/athena-all/src/main/java/run/mone/ultraman/state/AthenaEvent.java new file mode 100644 index 000000000..d2c118ee6 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/state/AthenaEvent.java @@ -0,0 +1,38 @@ +package run.mone.ultraman.state; + +import run.mone.m78.ip.bo.PromptInfo; +import run.mone.m78.ip.common.PromptType; +import lombok.Builder; +import lombok.Data; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CountDownLatch; + +/** + * @author goodjava@qq.com + * @date 2023/12/3 10:30 + */ +@Builder +@Data +public class AthenaEvent { + + private PromptInfo promptInfo; + + private PromptType promptType; + + private String answer; + + private AnswerType answerType; + + private String project; + + @Builder.Default + private Map meta = new HashMap<>(); + + + @Builder.Default + private CountDownLatch askLatch = new CountDownLatch(1); + + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/state/AthenaFsm.java b/athena-all/src/main/java/run/mone/ultraman/state/AthenaFsm.java new file mode 100644 index 000000000..94c776cdb --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/state/AthenaFsm.java @@ -0,0 +1,52 @@ +package run.mone.ultraman.state; + +import lombok.Getter; +import lombok.Setter; + +import java.util.concurrent.ArrayBlockingQueue; + +/** + * @author goodjava@qq.com + * @date 2023/12/2 20:58 + */ +public class AthenaFsm { + + @Setter + @Getter + private String project; + + private GlobalState globalState = new GlobalState(); + + @Getter + private AthenaState currentState = new NormalState(); + + @Getter + private ArrayBlockingQueue eventQueue = new ArrayBlockingQueue<>(1000); + + @Getter + private StateContext context = new StateContext(); + + private StateReq req = StateReq.builder().build(); + + public AthenaFsm() { + this.globalState.setFsm(this); + this.currentState.setFsm(this); + } + + public void execute() { + globalState.execute(req, context); + if (context.exit) { + changeState(new NormalState()); + return; + } + currentState.execute(req, context); + } + + + public void changeState(AthenaState state) { + this.currentState.exit(); + this.currentState = state; + this.currentState.setFsm(this); + this.currentState.enter(this.context); + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/state/AthenaState.java b/athena-all/src/main/java/run/mone/ultraman/state/AthenaState.java new file mode 100644 index 000000000..cb8615162 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/state/AthenaState.java @@ -0,0 +1,28 @@ +package run.mone.ultraman.state; + +import lombok.Setter; + +/** + * @author goodjava@qq.com + * @date 2023/12/2 20:58 + */ +public class AthenaState { + + @Setter + protected AthenaFsm fsm; + + + public void enter(StateContext context) { + + } + + public void execute(StateReq req, StateContext context) { + + } + + + public void exit() { + + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/state/CalState.java b/athena-all/src/main/java/run/mone/ultraman/state/CalState.java new file mode 100644 index 000000000..1fa8c3735 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/state/CalState.java @@ -0,0 +1,47 @@ +package run.mone.ultraman.state; + +import run.mone.m78.ip.common.ChromeUtils; + +/** + * @author goodjava@qq.com + * @date 2023/12/3 10:26 + *

+ * 计算答案 + */ +public class CalState extends AthenaState { + + private String type = "after"; + + public CalState(String type) { + this.type = type; + } + + public CalState() { + } + + @Override + public void execute(StateReq req, StateContext context) { + if (type.equals("after")) { + //恢复到普通模式(回答完了所有问题) + if (context.getStep() >= context.getFinishStep()) { + //所有前置问题都提问完了,最后一个prompt只要展示即可 + String prompt = req.getPromptInfo().getData(); + ChromeUtils.call(context.getProject(), prompt, 0); + this.fsm.changeState(new NormalState()); + } else { + //准备下一个问题 + this.fsm.changeState(new InitQuestionState()); + } + } else { + if (context.getPromptStep() >= context.getFinishPromptStep()) { + this.fsm.changeState(new WaitQuestionState(context)); + } else { + this.fsm.changeState(new AfterQuestionState()); + } + } + + + + + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/state/FsmManager.java b/athena-all/src/main/java/run/mone/ultraman/state/FsmManager.java new file mode 100644 index 000000000..020ce5acb --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/state/FsmManager.java @@ -0,0 +1,55 @@ +package run.mone.ultraman.state; + +import run.mone.m78.ip.bo.robot.ProjectAiMessageManager; +import lombok.Getter; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +/** + * @author goodjava@qq.com + * @date 2023/12/3 10:51 + */ +@Slf4j +public class FsmManager { + + private String project; + + + public FsmManager setProject(String project) { + this.project = project; + return this; + } + + @Getter + private AthenaFsm fsm = new AthenaFsm(); + + + public FsmManager() { + + } + + public void init() { + new Thread(() -> execute()).start(); + } + + + @SneakyThrows + public void execute() { + while (true) { + try { + if (!ProjectAiMessageManager.getInstance().getMap().containsKey(this.project)) { + //直接退出了 + log.info("project {} fsm quit", this.project); + fsm.getContext().quit = true; + break; + } + fsm.execute(); + } catch (Throwable ex) { + log.error(ex.getMessage(), ex); + } finally { + Thread.sleep(500); + } + } + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/state/GlobalState.java b/athena-all/src/main/java/run/mone/ultraman/state/GlobalState.java new file mode 100644 index 000000000..d746440a3 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/state/GlobalState.java @@ -0,0 +1,72 @@ +package run.mone.ultraman.state; + +import run.mone.m78.ip.util.UltramanConsole; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import run.mone.ultraman.common.GsonUtils; +import run.mone.ultraman.state.bo.StateInfo; + +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/12/3 10:19 + */ +@Slf4j +public class GlobalState extends AthenaState { + + + public static final String EXIT_CMD = "exit!"; + + + public static final String ASK = "ASK!"; + + + private long lastUpdateTime = 0L; + + + @Override + public void execute(StateReq req, StateContext context) { + //10秒一打印 + if (System.currentTimeMillis() - lastUpdateTime > 10000) { + log.info("project:{} state:{}", context.getProject(), this.fsm.getCurrentState()); + if (StringUtils.isNotEmpty(context.getProject())) { + UltramanConsole.append(context.getProject(), "ai fsm state:" + this.fsm.getCurrentState() + " step:(" + context.getStep() + "/" + context.getFinishStep() + ") question:" + context.getQuestion() + "(" + context.getPromptStep() + "/" + context.getFinishPromptStep() + ")"); + } + lastUpdateTime = System.currentTimeMillis(); + } + + AthenaEvent event = this.fsm.getEventQueue().peek(); + if (null != event && null != event.getAnswer()) { + //退出 + if (event.getAnswer().equals(EXIT_CMD)) { + context.exit = true; + } + + + //向状态机提问题 + if (event.getAnswer().equals(ASK)) { + //直接就拿出来了(后边就获取不到了) + event = this.fsm.getEventQueue().poll(); + String question = event.getMeta().getOrDefault("question", "info"); + switch (question) { + case "info": { + List list = context.getAddonList(); + event.getMeta().put("result", GsonUtils.gson.toJson(StateInfo.builder().step(context.getStep()).addonList(list).build())); + //解除对面阻塞 + event.getAskLatch().countDown(); + break; + } + case "modify_state": { + int index = Integer.valueOf(event.getMeta().getOrDefault("index", "0")); + context.reset(GsonUtils.gson.fromJson(context.getSnapshots().get(index).getStateContext(), StateContext.class)); + this.fsm.changeState(new InitQuestionState()); + break; + } + } + } + + } + + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/state/InitQuestionState.java b/athena-all/src/main/java/run/mone/ultraman/state/InitQuestionState.java new file mode 100644 index 000000000..9d0ce48d9 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/state/InitQuestionState.java @@ -0,0 +1,59 @@ +package run.mone.ultraman.state; + +import com.google.common.base.Splitter; +import run.mone.m78.ip.bo.PromptInfo; +import org.apache.commons.lang3.StringUtils; +import run.mone.ultraman.common.GsonUtils; + +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/12/17 12:55 + */ +public class InitQuestionState extends AthenaState { + + + @Override + public void execute(StateReq req, StateContext context) { + int index = context.getStep(); + //只记录第一次的状态 + context.getSnapshots().putIfAbsent(index, Snapshot.builder().stateContext(GsonUtils.gson.toJson(context)).build()); + + PromptInfo info = req.getPromptInfo(); + //获取问题 + String question = info.getAddon().get(context.getStep()); + question = getQuestion(context, question); + + context.setQuestionMeta(info.getAddon_metas().get(context.getStep()).getMeta()); + context.setQuestion(question); + context.setStep(context.getStep() + 1); + context.setPromptLables(info.getLabels()); + this.fsm.changeState(new QuestionState()); + } + + + private static String getQuestion(StateContext context, String question) { + //example + //请选择模块&&模块列表&& + List list = Splitter.on("&&").splitToList(question); + if (list.size() == 3) { + //让问题可以和工程相结合(通过提示词实现) + + String beforePrompt = list.get(1); + context.getBeforePrompt().clear(); + if (StringUtils.isNotEmpty(beforePrompt)) { + context.getBeforePrompt().addAll(Splitter.on(",").splitToList(beforePrompt)); + } + + String afterPrompt = list.get(2); + context.getAfterPrompt().clear(); + if (StringUtils.isNotEmpty(afterPrompt)) { + context.getAfterPrompt().addAll(Splitter.on(",").splitToList(afterPrompt)); + } + + question = list.get(0); + } + return question; + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/state/NormalState.java b/athena-all/src/main/java/run/mone/ultraman/state/NormalState.java new file mode 100644 index 000000000..d3e911155 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/state/NormalState.java @@ -0,0 +1,50 @@ +package run.mone.ultraman.state; + +import com.google.common.base.Splitter; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2023/12/2 22:21 + */ +@Slf4j +public class NormalState extends AthenaState { + + @Override + public void enter(StateContext context) { + context.reset(); + this.fsm.getEventQueue().clear(); + } + + @Override + public void execute(StateReq req, StateContext context) { + AthenaEvent event = this.fsm.getEventQueue().poll(); + if (null == event) { + return; + } + + //每个prompt可以外挂很多提问(这些就是那些提问) + List list = event.getPromptInfo().getAddon(); + if (null == list) { + log.error("addon list is empty"); + return; + } + + List addonList = list.stream().map(it -> { + List l = Splitter.on("&&").splitToList(it); + return l.get(0); + }).collect(Collectors.toList()); + context.setAddonList(addonList); + + req.setPromptInfo(event.getPromptInfo()); + req.setPromptType(event.getPromptType()); + context.setProject(event.getProject()); + context.setStep(0); + context.setFinishStep(list.size()); + + this.fsm.changeState(new InitQuestionState()); + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/state/ProjectFsmManager.java b/athena-all/src/main/java/run/mone/ultraman/state/ProjectFsmManager.java new file mode 100644 index 000000000..984cd3c65 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/state/ProjectFsmManager.java @@ -0,0 +1,71 @@ +package run.mone.ultraman.state; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author goodjava@qq.com + * @date 2023/12/3 16:14 + */ +public class ProjectFsmManager { + + public static ConcurrentHashMap map = new ConcurrentHashMap<>(); + + + public static boolean processMsg(String projectName, String msg) { + return processMsg(projectName, msg, AnswerType.normal, new HashMap<>()); + } + + //如果状态机正在等待答案,则会传入状态机 + public static boolean processMsg(String projectName, String msg, AnswerType answerType, Map meta) { + FsmManager fsmManager = ProjectFsmManager.map.get(projectName); + if (null != fsmManager) { + //等待答案呢(那么这次的就不是提问) + if (fsmManager.getFsm().getCurrentState() instanceof WaitQuestionState) { + fsmManager.getFsm().getEventQueue().add(AthenaEvent.builder().answer(msg).meta(meta).answerType(answerType).build()); + return true; + } + } + return false; + } + + + //向状态机提问题 + public static AthenaEvent ask(String projectName, Map map) { + AthenaEvent event = AthenaEvent.builder().answer(GlobalState.ASK).meta(map).answerType(AnswerType.empty).build(); + FsmManager fsmManager = ProjectFsmManager.map.get(projectName); + if (null != fsmManager) { + fsmManager.getFsm().getEventQueue().add(event); + } + return event; + } + + public static void tell(String projectName, Map map) { + AthenaEvent event = AthenaEvent.builder().answer(GlobalState.ASK).meta(map).answerType(AnswerType.empty).build(); + FsmManager fsmManager = ProjectFsmManager.map.get(projectName); + if (null != fsmManager) { + fsmManager.getFsm().getEventQueue().add(event); + } + } + + + //查询当前状态机所属状态 + public static String state(String projectName) { + FsmManager fsmManager = ProjectFsmManager.map.get(projectName); + if (null != fsmManager) { + Object object = fsmManager.getFsm().getCurrentState(); + return object.getClass().getSimpleName() + ":" + object.getClass(); + } + return ""; + } + + public static void stop(String projectName) { + FsmManager fsmManager = ProjectFsmManager.map.get(projectName); + if (null != fsmManager) { + fsmManager.getFsm().getEventQueue().add(AthenaEvent.builder().answer(GlobalState.EXIT_CMD).meta(new HashMap<>()).answerType(AnswerType.normal).build()); + } + } + + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/state/PromptAndFunctionProcessor.java b/athena-all/src/main/java/run/mone/ultraman/state/PromptAndFunctionProcessor.java new file mode 100644 index 000000000..cd665f745 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/state/PromptAndFunctionProcessor.java @@ -0,0 +1,270 @@ +package run.mone.ultraman.state; + +import com.google.common.base.Stopwatch; +import com.google.gson.JsonObject; +import com.intellij.openapi.project.Project; +import run.mone.m78.ip.bo.GenerateCodeReq; +import run.mone.m78.ip.bo.PromptContext; +import run.mone.m78.ip.bo.PromptInfo; +import run.mone.m78.ip.bo.chatgpt.Completions; +import run.mone.m78.ip.bo.chatgpt.Format; +import run.mone.m78.ip.bo.chatgpt.Message; +import run.mone.m78.ip.bo.robot.*; +import run.mone.m78.ip.common.ChromeUtils; +import run.mone.m78.ip.common.Const; +import run.mone.m78.ip.common.Prompt; +import run.mone.m78.ip.service.AiService; +import run.mone.m78.ip.service.PromptService; +import run.mone.m78.ip.service.RobotService; +import run.mone.m78.ip.util.ResourceUtils; +import run.mone.m78.ip.util.UltramanConsole; +import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; +import run.mone.ultraman.AthenaContext; +import run.mone.ultraman.common.FunctionReqUtils; +import run.mone.ultraman.common.GsonUtils; +import run.mone.ultraman.common.TemplateUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2023/12/4 17:53 + *

+ * 长对话调用function和prompt都从这里调出去 + */ +@Slf4j +public class PromptAndFunctionProcessor { + + + //直接调用某个prompt(这个prompt 必须是返回json的那种prompt) + public static JsonObject callPrompt(Project project, PromptInfo promptInfo, Map map) { + String prompt = promptInfo.getData(); + List> list = new ArrayList<>(); + boolean vip = false; + + Message.MessageBuilder messageBuilder = Message.builder(); + + if (!"no permission".equals(prompt.trim()) && false) { + prompt = TemplateUtils.renderTemplate(prompt, map); + list.add(AiChatMessage.builder().data(prompt).role(Role.user).build()); + vip = true; + } else { + //需要远程拼凑出prompt + list.add(AiChatMessage.builder().data("").role(Role.user).build()); + Map params = getParamMap(map); + messageBuilder.promptName(promptInfo.getPromptName()).params(params); + } + + List messageList = list.stream().map(it -> messageBuilder + .content(it.toString()) + .role(it.getRole().name()) + .build()).collect(Collectors.toList()); + + log.info("vip:{} prompt:{}", vip, prompt); + + Completions completions = Completions.builder().stream(false).response_format(Format.builder().build()).messages(messageList).build(); + UltramanConsole.append(project, "call ai prompt:" + promptInfo.getPromptName()); + Stopwatch swCallAi = Stopwatch.createStarted(); + JsonObject jsonObj = AiService.call(GsonUtils.gson.toJson(completions), Long.parseLong(promptInfo.getLabels().getOrDefault("timeout", "50000")), vip); + UltramanConsole.append(project, "call ai prompt:" + promptInfo.getPromptName() + " finish res:" + jsonObj + " use time:" + swCallAi.elapsed(TimeUnit.SECONDS) + "s"); + return jsonObj; + } + + @NotNull + private static Map getParamMap(Map map) { + return map.entrySet() + .stream() + .collect(Collectors.toMap( + Map.Entry::getKey, + e -> String.valueOf(e.getValue()) + )); + } + + + /** + * 处理prompt,后边可能挂一个function + *

+ * 模式都是用prompt完成推理+参数抽取->调用function + * + * @param promptName + * @param context + */ + public static void prompt(String promptName, StateContext context) { + List> list = ProjectAiMessageManager.getInstance().getMessageList(context.getProject()); + PromptInfo promptInfo = Prompt.getPromptInfo(promptName); + + //需要获取一些code信息 + if (promptInfo.open("_code")) { + Project project = AthenaContext.ins().getProjectMap().get(context.getProject()); + GenerateCodeReq req = GenerateCodeReq.builder().project(project).promptInfo(promptInfo).build(); + PromptService.setReq(req); + String code = PromptService.getCode(req, new PromptContext()); + context.getMemary().put("_code", code); + } + + String prompt = promptInfo.getData(); + prompt = TemplateUtils.renderTemplate(prompt, context.getMemary()); + list.add(AiChatMessage.builder().data(prompt).role(Role.user).build()); + //这里的it.toString 就是message to string 的过程 + List messageList = list.stream().map(it -> Message.builder().content(it.toString()).role(it.getRole().name()).build()).collect(Collectors.toList()); + //让返回的结果是json + Completions completions = Completions.builder().stream(false).response_format(Format.builder().build()).messages(messageList).build(); + UltramanConsole.append(context.getProject(), "call ai prompt:" + promptName); + Stopwatch swCallAi = Stopwatch.createStarted(); + JsonObject jsonObj = AiService.call(GsonUtils.gson.toJson(completions), Long.parseLong(promptInfo.getLabels().getOrDefault("timeout", "50000")), true); + UltramanConsole.append(context.getProject(), "call ai prompt:" + promptName + " finish res:" + jsonObj + " use time:" + swCallAi.elapsed(TimeUnit.SECONDS) + "s"); + log.info("promptName:{} res:{}", promptName, jsonObj); + if (!jsonObj.has("action")) { + jsonObj.addProperty("action", ActionType.print.name()); + } + + //展示一些debug信息到前台 + showDebugInfo(context, jsonObj.toString()); + + String action = jsonObj.get("action").getAsString(); + + //直接退出了 + if (action.equals(ActionType.exit.name())) { + log.info("action exit"); + ProjectFsmManager.stop(context.getProject()); + ChromeUtils.call(context.getProject(), "stop", 0); + return; + } + + //跳过这个function + if (action.equals(ActionType.skip.name())) { + log.info("action skip"); + ChromeUtils.call(context.getProject(), "skip", 0); + return; + } + + //记忆结果(先放入记忆) + memaryResult(context, jsonObj); + + if (action.equals(ActionType.memary.name())) { + //完成记忆 + } else if (action.equals(ActionType.print.name())) { + //输出到前台 + ChromeUtils.call(context.getProject(), jsonObj.toString(), 0); + ProjectAiMessageManager.getInstance().addMessage(context.getProject(), AiChatMessage.builder().role(Role.assistant).type(MessageType.string).data(jsonObj.toString()).build()); + } else if (action.equals(ActionType.method.name())) { + //执行一个方法 + String methodName = jsonObj.get("methodName").getAsString(); + //记忆中的内容也会放入请求map + Map map = FunctionReqUtils.getCallScriptMap(context.getProject(), context.getMemary(), context.getPromptLables()); + Object r = null; + Stopwatch sw = Stopwatch.createStarted(); + try { + UltramanConsole.append(context.getProject(), "call ai funtion:" + methodName); + //根据prompt需要调整一些调用function的参数(会改变请求参数) + changeFunctionParam(jsonObj, map, promptInfo); + r = RobotService.runScriptMethod(map, methodName); + log.info("call function finish result:{}", r); + if (r instanceof AiChatMessage am) { + //table中填的map直接当记忆使用 + if (am.getType().equals(MessageType.map)) { + MapData mapData = (MapData) am.getData(); + if (!mapData.getMap().isEmpty()) { + mapData.getMap().entrySet().stream().forEach((entry) -> { + String key = entry.getKey(); + if (mapData.getMemaryMap().containsKey(key)) { + context.getMemary().put(mapData.getMemaryMap().get(key).toString(), entry.getValue()); + } else { + context.getMemary().put(key, entry.getValue()); + } + }); + } + } + context.getMemary().putAll(am.getMeta()); + ProjectAiMessageManager.getInstance().addMessage(context.getProject(), AiChatMessage.builder().role(Role.assistant).type(am.getType()).data(am.getData()).build()); + ChromeUtils.call(context.getProject(), am); + } + } catch (Throwable ex) { + log.error("call function error:" + ex.getMessage(), ex); + ChromeUtils.call(context.getProject(), "error:" + ex.getMessage(), 0); + } finally { + UltramanConsole.append(context.getProject(), "call ai function:" + methodName + " finish res:" + r + " use time:" + sw.elapsed(TimeUnit.SECONDS) + "s"); + } + } + } + + //label 的优先级比较高,会直接替换掉map中的值(调用function的参数) + private static void changeFunctionParam(JsonObject promptRes, Map map, PromptInfo promptInfo) { + Map lables = promptInfo.getLabels(); + if (null != lables) { + lables.entrySet().stream().forEach(entry -> { + String key = entry.getKey(); + if (key.startsWith("#") && !entry.getValue().equals("null")) { + String newKey = key.substring(1); + if (map.containsKey(newKey) && promptRes.has(newKey)) { + log.info("change call function param key:{} value:{} oldValue:{}", newKey, entry.getValue(), map.get(newKey)); + map.put(newKey, entry.getValue()); + } + } + }); + } + } + + private static void memaryResult(StateContext context, JsonObject jsonObj) { + jsonObj.keySet().forEach(key -> { + if (jsonObj.get(key).isJsonPrimitive()) { + context.getMemary().put(key, jsonObj.get(key).getAsString()); + } else { + context.getMemary().put(key, jsonObj.get(key)); + } + }); + } + + private static void showDebugInfo(StateContext context, String jsonObj) { + if (ResourceUtils.getAthenaConfig().getOrDefault(Const.DEBUG, "false").equals("true")) { + ChromeUtils.call(context.getProject(), "debug: res:" + jsonObj + " memary:" + context.getMemary().toString(), 0); + } + } + + + public static void funciton(StateContext context, String prompt) { + //单纯调用function(会调用bot prompt 获取functio) + String project = context.getProject(); + String cmd = ""; + //直接调用方法 + //知道具体的命令 + if (prompt.startsWith("+")) { + cmd = prompt.substring(1); + } else { + //调用一次ai获取命令 + cmd = RobotService.getPromptCmd(prompt); + } + + Map map = FunctionReqUtils.getCallScriptMap(project, context.getMemary(), context.getPromptLables()); + log.info("call function:{} params:{}", cmd, map); + + Object r = RobotService.runScript(map, cmd); + + showDebugInfo(context, GsonUtils.gson.toJson(r)); + + if (r instanceof AiChatMessage am) { + //这个计算结果其实是通过函数来计算的 + String id = UUID.randomUUID().toString(); + AiChatMessage aiChatMessage = AiChatMessage.builder().id(id).role(Role.assistant).type(am.getType()).data(am.getData()).build(); + if (null != am.getMeta()) { + aiChatMessage.getMeta().putAll(am.getMeta()); + } + + //放入记忆体 + context.getMemary().putAll(am.getMeta()); + + //添加到自己记录的信息管理器中 + ProjectAiMessageManager.getInstance().addMessage(project, aiChatMessage); + am.setId(id); + //发送到前台 + ChromeUtils.call(project, am); + } + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/state/QuestionState.java b/athena-all/src/main/java/run/mone/ultraman/state/QuestionState.java new file mode 100644 index 000000000..df48464ee --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/state/QuestionState.java @@ -0,0 +1,56 @@ +package run.mone.ultraman.state; + +import run.mone.m78.ip.bo.robot.AiChatMessage; +import run.mone.m78.ip.bo.robot.MessageType; +import run.mone.m78.ip.bo.robot.ProjectAiMessageManager; +import run.mone.m78.ip.bo.robot.Role; +import run.mone.m78.ip.common.ChromeUtils; +import lombok.extern.slf4j.Slf4j; + +/** + * @author goodjava@qq.com + * @date 2023/12/2 21:00 + * 问问题模式(ai向人类提问) + * 很多时候用户是不知道如何向ai提问的,这种情况下不如让ai向人类提问(人类做选择) + */ +@Slf4j +public class QuestionState extends AthenaState { + + @Override + public void enter(StateContext context) { + context.setPromptStep(0); + context.setFinishPromptStep(0); + } + + @Override + public void execute(StateReq req, StateContext context) { + //向用户提问 + ask(context); + //初始化这些后边需要用到的prompt + if (needCallBeforePromptOrFunction(context)) { + return; + } + //等待用户回答问题 + this.fsm.changeState(new WaitQuestionState(context)); + } + + private static void ask(StateContext context) { + String question = context.getQuestion(); + //记录下这个信息 + ProjectAiMessageManager.getInstance().addMessage(context.getProject(), AiChatMessage.builder().role(Role.assistant).type(MessageType.string).data(question).build()); + //输出到聊天窗口 + ChromeUtils.call(context.getProject(), question, 0); + } + + private boolean needCallBeforePromptOrFunction(StateContext context) { + if (context.getBeforePrompt().size() > 0) { + context.setPromptStep(0); + context.setFinishPromptStep(context.getBeforePrompt().size()); + this.fsm.changeState(new AfterQuestionState()); + return true; + } + return false; + } + + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/state/Snapshot.java b/athena-all/src/main/java/run/mone/ultraman/state/Snapshot.java new file mode 100644 index 000000000..5f3b94177 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/state/Snapshot.java @@ -0,0 +1,19 @@ +package run.mone.ultraman.state; + +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/12/23 14:59 + */ +@Data +@Builder +public class Snapshot implements Serializable { + + //用json序列化过来 + private String stateContext; + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/state/StateContext.java b/athena-all/src/main/java/run/mone/ultraman/state/StateContext.java new file mode 100644 index 000000000..4be26e894 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/state/StateContext.java @@ -0,0 +1,95 @@ +package run.mone.ultraman.state; + + +import com.google.common.collect.Maps; +import lombok.Data; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author goodjava@qq.com + * @date 2023/12/3 10:18 + */ +@Data +public class StateContext { + + //目前第几步 + private int step; + + //第几步完成 + private int finishStep; + + private int promptStep; + + private int finishPromptStep; + + //隶属于那个项目 + private String project; + + //当前的问题 + private String question; + + //当前问题的元数据 + private Map questionMeta = new HashMap<>(); + + //用户提出问题后的处理(可以是prompt,也可以是function) + private List beforePrompt = new ArrayList<>(); + + //用户回答问题后的处理 + private List afterPrompt = new ArrayList<>(); + + //记忆 + private Map memary = new HashMap<>(); + + + //prompt的labels + private Map promptLables = new HashMap<>(); + + + boolean exit; + + //直接退出循环 + volatile boolean quit; + + //存储一些快照信息,方便回滚(目前只记录InitQuestionState中的上下文) + private Map snapshots = Maps.newHashMap(); + + //附加问题列表(索引就是第几个问题) + private List addonList; + + + public void reset() { + this.step = 0; + this.finishStep = 0; + this.promptStep = 0; + this.finishPromptStep = 0; + this.beforePrompt.clear(); + this.afterPrompt.clear(); + this.memary.clear(); + this.exit = false; + this.question = ""; + this.questionMeta.clear(); + } + + public void reset(StateContext context) { + this.step = context.getStep(); + this.finishStep = context.getFinishStep(); + this.promptStep = context.getPromptStep(); + this.finishPromptStep = context.getFinishPromptStep(); + this.beforePrompt.clear(); + this.beforePrompt.addAll(context.getBeforePrompt()); + this.afterPrompt.clear(); + this.afterPrompt.addAll(context.getAfterPrompt()); + this.memary.clear(); + this.memary.putAll(context.getMemary()); + this.exit = context.isExit(); + this.question = context.getQuestion(); + this.questionMeta.clear(); + this.questionMeta.putAll(context.getQuestionMeta()); + } + + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/state/StateReq.java b/athena-all/src/main/java/run/mone/ultraman/state/StateReq.java new file mode 100644 index 000000000..c1e4b9e3e --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/state/StateReq.java @@ -0,0 +1,25 @@ +package run.mone.ultraman.state; + +import run.mone.m78.ip.bo.PromptInfo; +import run.mone.m78.ip.common.PromptType; +import lombok.Builder; +import lombok.Data; + +/** + * @author goodjava@qq.com + * @date 2023/12/3 10:18 + */ +@Data +@Builder +public class StateReq { + + private PromptInfo promptInfo; + + private PromptType promptType; + + public void reset() { + this.promptInfo = null; + this.promptType = null; + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/state/WaitQuestionState.java b/athena-all/src/main/java/run/mone/ultraman/state/WaitQuestionState.java new file mode 100644 index 000000000..5f32daa83 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/state/WaitQuestionState.java @@ -0,0 +1,112 @@ +package run.mone.ultraman.state; + +import com.google.gson.reflect.TypeToken; +import run.mone.m78.ip.bo.robot.AiChatMessage; +import run.mone.m78.ip.bo.robot.ProjectAiMessageManager; +import run.mone.m78.ip.bo.robot.Role; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import run.mone.ultraman.common.GsonUtils; + +import java.lang.reflect.Type; +import java.util.List; +import java.util.Map; + +/** + * @author goodjava@qq.com + * @date 2023/12/2 22:24 + *

+ * 等待user答题的的状态 + */ +@Slf4j +public class WaitQuestionState extends AthenaState { + + /** + * before 用户回答之前的一些调用 + * after 用户回答问题后的一些调用 + */ + private String type = "after"; + + + public WaitQuestionState(String type) { + this.type = type; + } + + public WaitQuestionState() { + } + + public WaitQuestionState(StateContext context) { + Map meta = context.getQuestionMeta(); + + if (null != meta) { + //有确认流程(也就是答案是固定的几个) + if (meta.containsKey("confirm")) { + String value = meta.get("confirm"); + Type typeOfT = new TypeToken>() { + }.getType(); + List list = GsonUtils.gson.fromJson(value, typeOfT); + context.getMemary().put("confirm_list", list); + PromptAndFunctionProcessor.funciton(context, "+confirmList"); + } + } + + + } + + @SneakyThrows + @Override + public void execute(StateReq req, StateContext context) { + //等待用户的回答 + AthenaEvent event = this.fsm.getEventQueue().poll(); + if (null == event) { + return; + } + + log.info("event:{}", event); + + AnswerType type = event.getAnswerType(); + //就是普通的回答 + if (type.equals(AnswerType.normal)) { + ProjectAiMessageManager.getInstance().addMessage(context.getProject(), AiChatMessage.builder() + .data(event.getAnswer()) + .message(event.getAnswer()) + .role(Role.user) + .build()); + } + + if (type.equals(AnswerType.empty)) { + //空答案什么也不处理 + } + + //如果有一些meta数据则放入记忆体中 + if (!event.getMeta().isEmpty()) { + event.getMeta().forEach((key, value) -> context.getMemary().putIfAbsent(key, value)); + } + + + if (this.type.equals("after")) { + //用户已经有反馈了,执行后续prompt(基本上prompt后边也会挂一个function),或者function + executePromptOrFunction(context); + } + this.fsm.changeState(new CalState(this.type)); + } + + private static void executePromptOrFunction(StateContext context) { + //用户已经回答了(这里可以对回答进行操作) + context.getAfterPrompt().stream().forEach(it -> { + if (StringUtils.isEmpty(it)) { + return; + } + String prompt = it; + //调用prompt + if (prompt.startsWith("_")) { + String promptName = prompt.substring(1); + PromptAndFunctionProcessor.prompt(promptName, context); + } else { + //单纯调用function + PromptAndFunctionProcessor.funciton(context, prompt); + } + }); + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/state/bo/StateInfo.java b/athena-all/src/main/java/run/mone/ultraman/state/bo/StateInfo.java new file mode 100644 index 000000000..13c7d5157 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/state/bo/StateInfo.java @@ -0,0 +1,21 @@ +package run.mone.ultraman.state.bo; + +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/12/24 19:15 + */ +@Data +@Builder +public class StateInfo implements Serializable { + + private int step; + + private List addonList; + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/statusbar/AthenaStatusBarWidget.java b/athena-all/src/main/java/run/mone/ultraman/statusbar/AthenaStatusBarWidget.java new file mode 100644 index 000000000..d1fe65ccb --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/statusbar/AthenaStatusBarWidget.java @@ -0,0 +1,119 @@ +package run.mone.ultraman.statusbar; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.ui.popup.ListPopup; +import com.intellij.openapi.ui.popup.PopupStep; +import com.intellij.openapi.ui.popup.util.BaseListPopupStep; +import com.intellij.openapi.util.NlsContexts; +import com.intellij.openapi.wm.StatusBar; +import com.intellij.openapi.wm.StatusBarWidget; +import com.intellij.ui.awt.RelativePoint; +import com.intellij.util.Consumer; +import run.mone.m78.ip.bo.GenerateCodeReq; +import run.mone.m78.ip.bo.PromptInfo; +import run.mone.m78.ip.common.Const; +import run.mone.m78.ip.common.Prompt; +import run.mone.m78.ip.common.PromptType; +import run.mone.m78.ip.service.PromptService; +import run.mone.m78.ip.util.LabelUtils; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import run.mone.ultraman.AthenaContext; +import run.mone.ultraman.bo.ClientData; +import run.mone.ultraman.statusbar.bo.PopupItem; + +import java.awt.*; +import java.awt.event.MouseEvent; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2023/7/18 23:41 + */ +public class AthenaStatusBarWidget implements StatusBarWidget { + + private final Project project; + + private StatusBar statusBar; + + public AthenaStatusBarWidget(Project project) { + this.project = project; + } + + + @Override + public @NonNls @NotNull String ID() { + return "AthenaStatusBarWidget"; + } + + @Override + public void install(@NotNull StatusBar statusBar) { + this.statusBar = statusBar; + } + + @Override + public void dispose() { + } + + @Override + public @Nullable WidgetPresentation getPresentation() { + + return new StatusBarWidget.TextPresentation() { + + @Override + public @Nullable @NlsContexts.Tooltip String getTooltipText() { + return "Athena"; + } + + @Override + public @Nullable Consumer getClickConsumer() { + return (MouseEvent e) -> { + + if (!LabelUtils.open(Const.ENABLE_ATHENA_STATUS_BAR)) { + return; + } + + List collectedList = Prompt.getCollected(); + collectedList.addAll(Prompt.getPromptInfoByTag("system")); + List list = collectedList.stream().filter(it -> it.getTags().stream().map(i -> i.getName()).collect(Collectors.toList()).contains("popup")).map(it -> PopupItem.builder().name(it.getPromptName()).desc(it.getDesc()).build()).collect(Collectors.toList()); + ListPopup listPopup = JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep("Prompt", list) { + @Override + public PopupStep onChosen(PopupItem selectedValue, boolean finalChoice) { + ApplicationManager.getApplication().invokeLater(() -> { + PromptInfo info = Prompt.getPromptInfo(selectedValue.getName()); + PromptType type = Prompt.getPromptType(info); + ClientData clientData = AthenaContext.ins().getClientData(project.getName()); + PromptService.dynamicInvoke(GenerateCodeReq.builder() + .scope(clientData.getScope()) + .project(project) + .projectName(project.getName()) + .promptInfo(info).promptType(type) + .promptName(selectedValue.getName()) + .build()); + }); + return super.onChosen(selectedValue, finalChoice); + } + }); + Rectangle r = statusBar.getComponent().getBounds(); + Point p = new Point(r.x + r.width, r.y + r.height); + RelativePoint showPoint = new RelativePoint(statusBar.getComponent(), p); + listPopup.show(showPoint); + }; + } + + @Override + public @NotNull @NlsContexts.Label String getText() { + return "Athena"; + } + + @Override + public float getAlignment() { + return 0; + } + }; + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/statusbar/AthenaStatusBarWidgetFactory.java b/athena-all/src/main/java/run/mone/ultraman/statusbar/AthenaStatusBarWidgetFactory.java new file mode 100644 index 000000000..c1a3e69a8 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/statusbar/AthenaStatusBarWidgetFactory.java @@ -0,0 +1,45 @@ +package run.mone.ultraman.statusbar; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.StatusBar; +import com.intellij.openapi.wm.StatusBarWidget; +import com.intellij.openapi.wm.StatusBarWidgetFactory; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +/** + * @author goodjava@qq.com + * @date 2023/7/18 23:39 + */ +public class AthenaStatusBarWidgetFactory implements StatusBarWidgetFactory { + @Override + public @NonNls @NotNull String getId() { + return "AtheanStatusBarWidgetFactory"; + } + + @Override + public @Nls @NotNull String getDisplayName() { + return "Athena"; + } + + @Override + public boolean isAvailable(@NotNull Project project) { + return true; + } + + @Override + public @NotNull StatusBarWidget createWidget(@NotNull Project project) { + return new AthenaStatusBarWidget(project); + } + + @Override + public void disposeWidget(@NotNull StatusBarWidget widget) { + + } + + @Override + public boolean canBeEnabledOn(@NotNull StatusBar statusBar) { + return true; + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/statusbar/bo/PopupItem.java b/athena-all/src/main/java/run/mone/ultraman/statusbar/bo/PopupItem.java new file mode 100644 index 000000000..5766fb1bd --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/statusbar/bo/PopupItem.java @@ -0,0 +1,24 @@ +package run.mone.ultraman.statusbar.bo; + +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2023/7/19 10:54 + */ +@Data +@Builder +public class PopupItem implements Serializable { + + private String name; + + private String desc; + + @Override + public String toString() { + return this.desc; + } +} diff --git a/athena-all/src/main/resources/META-INF/plugin.xml b/athena-all/src/main/resources/META-INF/plugin.xml new file mode 100644 index 000000000..b139a0e38 --- /dev/null +++ b/athena-all/src/main/resources/META-INF/plugin.xml @@ -0,0 +1,134 @@ + + + com.xiaomi.youpin.code.generate + + Athena + + mone + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + run.mone.m78.ip.component.project.AthenaProjectComment + + + + + + + + + run.mone.m78.ip.component.PluginComponent + + + + run.mone.m78.ip.component.TeslaAppComponent + + + + + run.mone.m78.ip.component.VersionComponent + + + + run.mone.m78.ip.component.UltramanComponent + + + + + + + + + + + + + + + + + + diff --git a/athena-all/src/main/resources/META-INF/pluginIcon.svg b/athena-all/src/main/resources/META-INF/pluginIcon.svg new file mode 100644 index 000000000..8faabba91 --- /dev/null +++ b/athena-all/src/main/resources/META-INF/pluginIcon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/athena-all/src/main/resources/icons/a.svg b/athena-all/src/main/resources/icons/a.svg new file mode 100644 index 000000000..0ed3aa445 --- /dev/null +++ b/athena-all/src/main/resources/icons/a.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/athena-all/src/main/resources/icons/image.png b/athena-all/src/main/resources/icons/image.png new file mode 100644 index 000000000..edc7cb5dd Binary files /dev/null and b/athena-all/src/main/resources/icons/image.png differ diff --git a/athena-all/src/main/resources/icons/music.png b/athena-all/src/main/resources/icons/music.png new file mode 100644 index 000000000..8d3668c7e Binary files /dev/null and b/athena-all/src/main/resources/icons/music.png differ diff --git a/athena-all/src/main/resources/icons/spider.png b/athena-all/src/main/resources/icons/spider.png new file mode 100644 index 000000000..bd6d43380 Binary files /dev/null and b/athena-all/src/main/resources/icons/spider.png differ diff --git a/athena-all/src/main/resources/icons/task.png b/athena-all/src/main/resources/icons/task.png new file mode 100644 index 000000000..2892399b2 Binary files /dev/null and b/athena-all/src/main/resources/icons/task.png differ diff --git a/athena-all/src/main/resources/icons/text.png b/athena-all/src/main/resources/icons/text.png new file mode 100644 index 000000000..7fca6416e Binary files /dev/null and b/athena-all/src/main/resources/icons/text.png differ diff --git a/athena-all/src/main/resources/icons/ultraman.png b/athena-all/src/main/resources/icons/ultraman.png new file mode 100644 index 000000000..82fa5ee53 Binary files /dev/null and b/athena-all/src/main/resources/icons/ultraman.png differ diff --git a/athena-all/src/main/resources/icons/user.png b/athena-all/src/main/resources/icons/user.png new file mode 100644 index 000000000..46606b921 Binary files /dev/null and b/athena-all/src/main/resources/icons/user.png differ diff --git a/athena-all/src/test/java/run/mone/ultraman/test/AiTest.java b/athena-all/src/test/java/run/mone/ultraman/test/AiTest.java new file mode 100644 index 000000000..bcad78290 --- /dev/null +++ b/athena-all/src/test/java/run/mone/ultraman/test/AiTest.java @@ -0,0 +1,31 @@ +package run.mone.ultraman.test; + +import com.google.common.collect.Lists; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import run.mone.m78.ip.bo.chatgpt.Completions; +import run.mone.m78.ip.bo.chatgpt.Format; +import run.mone.m78.ip.bo.chatgpt.Message; +import run.mone.m78.ip.service.LocalAiService; +import org.junit.Test; + +/** + * @author goodjava@qq.com + * @date 2023/12/3 21:25 + */ +public class AiTest { + + private Gson gson = new Gson(); + + + @Test + public void testCall() { + Completions completions = Completions.builder() + .stream(false) + .response_format(Format.builder().build()) + .model("gpt-4-1106-preview").messages(Lists.newArrayList(Message.builder().role("system").content("你是我的ai助手,请返回json格式数据").build(),Message.builder().role("user").content("1+1=?").build())).build(); + JsonObject res = LocalAiService.call(gson.toJson(completions)); + System.out.println(res); + } + +} diff --git a/athena-all/src/test/java/run/mone/ultraman/test/AthenaCodeServiceTest.java b/athena-all/src/test/java/run/mone/ultraman/test/AthenaCodeServiceTest.java new file mode 100644 index 000000000..a955f065a --- /dev/null +++ b/athena-all/src/test/java/run/mone/ultraman/test/AthenaCodeServiceTest.java @@ -0,0 +1,70 @@ +package run.mone.ultraman.test; + +import com.github.javaparser.JavaParser; +import com.github.javaparser.ParseResult; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.ConstructorDeclaration; +import com.github.javaparser.ast.body.FieldDeclaration; +import com.github.javaparser.ast.body.InitializerDeclaration; +import com.github.javaparser.ast.body.MethodDeclaration; +import lombok.SneakyThrows; +import org.junit.Test; +import run.mone.ultraman.bo.AthenaClassInfo; +import run.mone.ultraman.bo.AthenaFieldInfo; +import run.mone.ultraman.bo.AthenaMethodInfo; +import run.mone.ultraman.service.AthenaCodeService; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/11/6 22:46 + */ +public class AthenaCodeServiceTest { + + @Test + public void testParseMethod() { + List list = AthenaCodeService.parseMethodCode("public class A { public void t(){} public int sum(int a, int b) {return a+b;}}"); + System.out.println(list); + } + + + @SneakyThrows + @Test + public void testClassInfo() { + String code = Files.readString(Paths.get("/tmp/o.java")); + AthenaClassInfo info = AthenaCodeService.classInfo(code); + System.out.println(info); + System.out.println(info.getClassCode().length()); + } + + + @SneakyThrows + @Test + public void testRemove() { + String code = Files.readString(Paths.get("/tmp/T.java")); + JavaParser javaParser = new JavaParser(); + ParseResult pr = javaParser.parse(code); + if (!pr.isSuccessful()) { + System.out.println(pr.getProblems()); + } + CompilationUnit cu = pr.getResult().get(); + cu.findAll(MethodDeclaration.class).stream().filter(it -> it.isPrivate()).forEach(it -> it.removeForced()); + cu.findAll(ConstructorDeclaration.class).stream().forEach(it->it.getBody().removeForced()); + cu.findAll(InitializerDeclaration.class, init -> init.isStatic()).forEach(it -> it.removeForced()); + + cu.findAll(FieldDeclaration.class).stream().forEach(it->it.removeForced()); + System.out.println(cu.toString()); + } + + + @SneakyThrows + @Test + public void testParseField() { + String code = Files.readString(Paths.get("/tmp/AthenaClassInfo.java")); + List fieldList = AthenaCodeService.parseFieldCode(code); + System.out.println(fieldList); + } +} diff --git a/athena-all/src/test/java/run/mone/ultraman/test/Base64Test.java b/athena-all/src/test/java/run/mone/ultraman/test/Base64Test.java new file mode 100644 index 000000000..991612847 --- /dev/null +++ b/athena-all/src/test/java/run/mone/ultraman/test/Base64Test.java @@ -0,0 +1,101 @@ +package run.mone.ultraman.test; + +import cn.hutool.core.codec.Base64; +import com.google.common.net.UrlEscapers; +import lombok.SneakyThrows; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.net.URLEncoder; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * @author goodjava@qq.com + * @date 2023/6/2 16:58 + */ +public class Base64Test { + + + @Test + public void testa() throws InterruptedException { + Instant begin = new Date().toInstant(); + TimeUnit.SECONDS.sleep(3); + long sencodes = getSecondsBetween(begin, Instant.now()); + System.out.println(sencodes); + System.out.println(Math.min(sencodes / 5.0f, 0.99)); + Assert.assertTrue(true); + } + + public long getSecondsBetween(Instant past, Instant present) { + return Duration.between(past, present).getSeconds(); + } + + @Test + public void test() { + String str = "You must have clicked twice!"; + System.out.println(Base64.encode(str)); + } + + + @Test + public void testDeocde() throws IOException { + byte[] data = Base64.decode(Files.readAllBytes(Paths.get("/tmp/mp3.txt"))); + Files.write(Paths.get("/tmp/a.mp3"), data); + } + + + @SneakyThrows + @Test + public void test1() { + String str = URLEncoder.encode("你一定点击了两次!", "utf-8"); + System.out.println(str); + } + + @Test + public void test3() { + String str = "@SneakyThrows\n" + + " public static void call(String method, String param) {\n" + + " param = URLEncoder.encode(param, \"utf8\");\n" + + " UltrmanTreeKeyAdapter.browser.getCefBrowser().executeJavaScript(method + \"('\" + param + \"');\", UltrmanTreeKeyAdapter.browser.getCefBrowser().getURL(), 1);\n" + + " }"; + str = UrlEscapers.urlFragmentEscaper().escape(str); + System.out.println(str); + } + + private List parse(String str1, String str2) { + str1 = str1.trim(); + str2 = str2.trim(); + int start = 0; + int end = 0; + for (; start < str1.length() && start < str2.length(); start++) { + if (str1.charAt(start) != str2.charAt(start)) { + break; + } + } + for (; end < str1.length() && end < str2.length(); end++) { + if (str1.charAt(str1.length() - 1 - end) != str2.charAt(str2.length() - 1 - end)) { + break; + } + } + List res = new ArrayList<>(); + res.add(str1.substring(start, str1.length() - end).trim()); + res.add(str2.substring(start, str2.length() - end).trim()); + return res; + } + + @SneakyThrows + @Test + public void testText() { + String str = "abcd1234\n abcd"; + String str2 = "abcd567890abcd"; + System.out.println(parse(str, str2)); + } +} diff --git a/athena-all/src/test/java/run/mone/ultraman/test/CommonUtilsTest.java b/athena-all/src/test/java/run/mone/ultraman/test/CommonUtilsTest.java new file mode 100644 index 000000000..31243cd4c --- /dev/null +++ b/athena-all/src/test/java/run/mone/ultraman/test/CommonUtilsTest.java @@ -0,0 +1,47 @@ +package run.mone.ultraman.test; + +import com.google.common.collect.Lists; +import run.mone.mone.ultraman.grpc.CommonUtils; +import org.junit.Test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.junit.Assert.assertEquals; + +/** + * @author goodjava@qq.com + * @date 2023/8/1 15:12 + */ +public class CommonUtilsTest { + + @Test + public void testGetIntersection() { + CommonUtils commonUtils = new CommonUtils(); + List list1 = Arrays.asList("a", "b", "c", "d"); + List list2 = Arrays.asList("c", "d", "e", "f"); + List expected = Arrays.asList("c", "d"); + List actual = commonUtils.getIntersection(list1, list2); + assertEquals(expected, actual); + } + + + @Test + public void testSubList() { + List list = Lists.newArrayList("a", "b", "c"); + System.out.println(getLastElements(list, 3)); + } + + + //给你一个list,然后给定一个num,你从这个list中取后边的元素(如果num大于list长度,则取整个list) + public List getLastElements(List list, int num) { + if (list == null || list.isEmpty() || num <= 0) { + return Collections.emptyList(); + } + int startIndex = Math.max(list.size() - num, 0); + return list.subList(startIndex, list.size()); + } + + +} diff --git a/athena-all/src/test/java/run/mone/ultraman/test/GsonTest.java b/athena-all/src/test/java/run/mone/ultraman/test/GsonTest.java new file mode 100644 index 000000000..d13ac2298 --- /dev/null +++ b/athena-all/src/test/java/run/mone/ultraman/test/GsonTest.java @@ -0,0 +1,25 @@ +package run.mone.ultraman.test; + +import com.google.gson.JsonObject; +import org.junit.Test; + +/** + * @author goodjava@qq.com + * @date 2023/12/5 14:32 + */ +public class GsonTest { + + + @Test + public void test1() { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("a","1"); + System.out.println(jsonObject.get("a").isJsonPrimitive()); + System.out.println(jsonObject.get("a").getAsString()); + } + + //计算两数和1 + + + +} diff --git a/athena-all/src/test/java/run/mone/ultraman/test/MonitorTest.java b/athena-all/src/test/java/run/mone/ultraman/test/MonitorTest.java new file mode 100644 index 000000000..2a854ffb0 --- /dev/null +++ b/athena-all/src/test/java/run/mone/ultraman/test/MonitorTest.java @@ -0,0 +1,68 @@ +package run.mone.ultraman.test; + +import com.google.common.util.concurrent.Monitor; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; +import org.junit.Test; + +import java.util.concurrent.TimeUnit; + +/** + * @author goodjava@qq.com + * @date 2023/6/25 16:04 + */ +@Slf4j +public class MonitorTest { + + + @SneakyThrows + @Test + public void test1() { + + System.out.println(123); + Monitor monitor = new Monitor(); + + Mutable m = new MutableObject<>(""); + + Monitor.Guard guard = monitor.newGuard(() -> { + return StringUtils.isNotEmpty(m.getValue()); + }); + + Monitor.Guard guard2 = monitor.newGuard(() -> { + return !StringUtils.isNotEmpty(m.getValue()); + }); + + new Thread(() -> { + try { + monitor.enterWhen(guard); + log.info(m.getValue()); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } finally { + monitor.leave(); + } + + }).start(); + + TimeUnit.SECONDS.sleep(1); + + new Thread(() -> { + try { + monitor.enterWhen(guard2); + log.info(m.getValue()); + m.setValue("123"); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } finally { + monitor.leave(); + } + }).start(); + + System.in.read(); + + } + +} diff --git a/athena-all/src/test/java/run/mone/ultraman/test/ScriptServiceTest.java b/athena-all/src/test/java/run/mone/ultraman/test/ScriptServiceTest.java new file mode 100644 index 000000000..47dcbc044 --- /dev/null +++ b/athena-all/src/test/java/run/mone/ultraman/test/ScriptServiceTest.java @@ -0,0 +1,54 @@ +package run.mone.ultraman.test; + +import com.google.common.base.Charsets; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; +import com.google.common.io.Resources; +import com.google.gson.Gson; +import run.mone.m78.ip.service.ScriptService; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; +import org.junit.Test; + +import java.io.IOException; + +/** + * @author goodjava@qq.com + * @date 2023/7/4 14:13 + */ +@Slf4j +public class ScriptServiceTest { + + + @SneakyThrows + @Test + public void test1() { + String content = getScript(); + Object res = ScriptService.ins().invoke(content, "sum", Maps.newHashMap(), 1, 2); + System.out.println(res); + } + + @NotNull + private static String getScript() throws IOException { + String content = Resources.toString(Resources.getResource("fun.groovy"), Charsets.UTF_8); + return content; + } + + + @SneakyThrows + @Test + public void test2() { + Object res = ScriptService.ins().invoke(getScript(), "k", ImmutableMap.of("v", 22)); + System.out.println(res); + } + + + @SneakyThrows + @Test + public void test3() { + Object res = ScriptService.ins().invoke(getScript(), "g", ImmutableMap.of("gson", new Gson(), "log", log), new Gson(),log); + System.out.println(res); + } + +} diff --git a/athena-all/src/test/java/run/mone/ultraman/test/TemplateTest.java b/athena-all/src/test/java/run/mone/ultraman/test/TemplateTest.java new file mode 100644 index 000000000..3231a47e3 --- /dev/null +++ b/athena-all/src/test/java/run/mone/ultraman/test/TemplateTest.java @@ -0,0 +1,56 @@ +package run.mone.ultraman.test; + +import com.google.common.collect.ImmutableMap; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import org.junit.Test; +import run.mone.ultraman.common.TemplateUtils; + +import java.util.Map; + +/** + * @author goodjava@qq.com + * @date 2023/5/30 13:24 + */ +public class TemplateTest { + + + @Test + public void renderAndPrintTemplate() { + String str = TemplateUtils.renderTemplate("${name} hi", ImmutableMap.of("name", "zzy")); + System.out.println(str); + } + + @Test + public void testMyFunction() { + String str = TemplateUtils.renderTemplate("${name} hi ${athena('zzy')}", ImmutableMap.of("name", "zzy")); + System.out.println(str); + } + + + @Test + public void printTemplateParams() { + Map m = TemplateUtils.getParams("${name} ${age} aaa"); + System.out.println(m); + } + + @Test + public void printByteArrayAsString() { + byte[] data = new byte[]{34, 41, 10}; + String v = (new String(data)); + System.out.println(v); + } + class A{ + public String x; + public String y; + } + @Test + public void testOS() { + System.out.println(System.getProperty("os.name")); + A a=new A(); + a.x="a"; + System.out.println(new Gson().toJson(a)); + System.out.println(new GsonBuilder().serializeNulls().create().toJson(a)); + } + +} diff --git a/athena-all/src/test/java/run/mone/ultraman/test/XmlUtilsTest.java b/athena-all/src/test/java/run/mone/ultraman/test/XmlUtilsTest.java new file mode 100644 index 000000000..799c3146f --- /dev/null +++ b/athena-all/src/test/java/run/mone/ultraman/test/XmlUtilsTest.java @@ -0,0 +1,24 @@ +package run.mone.ultraman.test; + +import run.mone.m78.ip.util.XmlUtils; +import org.junit.Test; + +import java.util.Map; + +/** + * @author goodjava@qq.com + * @date 2023/12/21 11:55 + */ +public class XmlUtilsTest { + + @Test + public void test1() { + XmlUtils.updateGeneratorConfig("/tmp/generatorConfig.xml","Abc"); + } + + @Test + public void test2() { + Map m = XmlUtils.getMysqlConfigFromMybatisConfig("/tmp/generatorConfig.xml"); + System.out.println(m); + } +}