├── .gitignore ├── LICENSE ├── README.md ├── build.gradle ├── docs ├── _javacg2_all_config.md ├── call_type.md ├── change_log.md └── file_format.md ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── publish.gradle ├── run.bat ├── run.sh ├── src ├── main │ ├── java │ │ ├── com │ │ │ └── adrninistrator │ │ │ │ └── javacg2 │ │ │ │ ├── common │ │ │ │ ├── JavaCG2CommonNameConstants.java │ │ │ │ ├── JavaCG2ConfigPrintConstants.java │ │ │ │ ├── JavaCG2Constants.java │ │ │ │ ├── SpringAnnotationConstants.java │ │ │ │ ├── TypeConstants.java │ │ │ │ └── enums │ │ │ │ │ ├── JavaCG2ArithmeticOperationTypeEnum.java │ │ │ │ │ ├── JavaCG2CallTypeEnum.java │ │ │ │ │ ├── JavaCG2CalleeObjTypeEnum.java │ │ │ │ │ ├── JavaCG2CalleeRawActualEnum.java │ │ │ │ │ ├── JavaCG2ConstantTypeEnum.java │ │ │ │ │ ├── JavaCG2DirEnum.java │ │ │ │ │ ├── JavaCG2FieldRelationshipTypeEnum.java │ │ │ │ │ ├── JavaCG2MethodCallInfoTypeEnum.java │ │ │ │ │ ├── JavaCG2OutPutFileTypeEnum.java │ │ │ │ │ └── JavaCG2YesNoEnum.java │ │ │ │ ├── comparator │ │ │ │ ├── Comparator4MainConfig.java │ │ │ │ └── Comparator4MethodArgReturnTypes.java │ │ │ │ ├── conf │ │ │ │ ├── BaseConfigureWrapper.java │ │ │ │ ├── BaseGenConfFromEnum.java │ │ │ │ ├── JavaCG2ConfInfo.java │ │ │ │ ├── JavaCG2ConfManager.java │ │ │ │ ├── JavaCG2ConfigureWrapper.java │ │ │ │ └── enums │ │ │ │ │ ├── JavaCG2ConfigKeyEnum.java │ │ │ │ │ ├── JavaCG2OtherConfigFileUseListEnum.java │ │ │ │ │ ├── JavaCG2OtherConfigFileUseSetEnum.java │ │ │ │ │ └── interfaces │ │ │ │ │ ├── ConfigInterface.java │ │ │ │ │ ├── MainConfigInterface.java │ │ │ │ │ └── OtherConfigInterface.java │ │ │ │ ├── dto │ │ │ │ ├── accessflag │ │ │ │ │ └── JavaCG2AccessFlags.java │ │ │ │ ├── branch │ │ │ │ │ └── BranchStackEntry.java │ │ │ │ ├── call │ │ │ │ │ ├── MethodCall.java │ │ │ │ │ ├── MethodCallList.java │ │ │ │ │ ├── MethodCallPossibleEntry.java │ │ │ │ │ ├── MethodCallPossibleInfo.java │ │ │ │ │ └── MethodCallPossibleList.java │ │ │ │ ├── classes │ │ │ │ │ ├── ClassExtendsInfo.java │ │ │ │ │ ├── InnerClassInfo.java │ │ │ │ │ └── Node4ClassExtendsMethod.java │ │ │ │ ├── counter │ │ │ │ │ └── JavaCG2Counter.java │ │ │ │ ├── element │ │ │ │ │ ├── BaseElement.java │ │ │ │ │ ├── constant │ │ │ │ │ │ ├── ConstElement.java │ │ │ │ │ │ ├── ConstElementByte.java │ │ │ │ │ │ ├── ConstElementDouble.java │ │ │ │ │ │ ├── ConstElementFloat.java │ │ │ │ │ │ ├── ConstElementInt.java │ │ │ │ │ │ ├── ConstElementLong.java │ │ │ │ │ │ ├── ConstElementNull.java │ │ │ │ │ │ ├── ConstElementShort.java │ │ │ │ │ │ └── ConstElementString.java │ │ │ │ │ └── variable │ │ │ │ │ │ ├── FieldElement.java │ │ │ │ │ │ ├── JSRElement.java │ │ │ │ │ │ ├── LocalVariableElement.java │ │ │ │ │ │ ├── StaticFieldElement.java │ │ │ │ │ │ ├── StaticFieldMethodCallElement.java │ │ │ │ │ │ └── VariableElement.java │ │ │ │ ├── exception │ │ │ │ │ ├── CatchAndFinallyInfo.java │ │ │ │ │ ├── CatchInfo.java │ │ │ │ │ ├── ExceptionTargetInfo.java │ │ │ │ │ ├── FinallyInfo.java │ │ │ │ │ ├── ThrowInfo.java │ │ │ │ │ └── ThrowInfoList.java │ │ │ │ ├── field │ │ │ │ │ ├── ClassField.java │ │ │ │ │ ├── ClassFieldMethodCall.java │ │ │ │ │ ├── FieldPossibleTypes.java │ │ │ │ │ ├── FieldTypeAndName.java │ │ │ │ │ └── StaticFieldTypeAndName.java │ │ │ │ ├── fieldrelationship │ │ │ │ │ └── GetSetFieldRelationship.java │ │ │ │ ├── frame │ │ │ │ │ ├── FieldInformationMap.java │ │ │ │ │ ├── FrameSnapshotEntry.java │ │ │ │ │ ├── FrameSnapshotsOfIhs.java │ │ │ │ │ ├── InstructionStepList.java │ │ │ │ │ ├── JavaCG2LocalVariables.java │ │ │ │ │ └── JavaCG2OperandStack.java │ │ │ │ ├── inputoutput │ │ │ │ │ └── JavaCG2InputAndOutput.java │ │ │ │ ├── instruction │ │ │ │ │ ├── InvokeInstructionPosAndCallee.java │ │ │ │ │ └── parseresult │ │ │ │ │ │ ├── AThrowNullParseResult.java │ │ │ │ │ │ ├── AThrowParseResult.java │ │ │ │ │ │ ├── BaseInstructionParseResult.java │ │ │ │ │ │ ├── MethodCallParseResult.java │ │ │ │ │ │ ├── PutFieldParseResult.java │ │ │ │ │ │ ├── PutStaticParseResult.java │ │ │ │ │ │ ├── RetParseResult.java │ │ │ │ │ │ └── ReturnParseResult.java │ │ │ │ ├── jar │ │ │ │ │ ├── ClassAndJarNum.java │ │ │ │ │ └── OuterInnerJarPath.java │ │ │ │ ├── method │ │ │ │ │ ├── JavaCG2MethodInfo.java │ │ │ │ │ └── MethodArgReturnTypes.java │ │ │ │ ├── methodcode │ │ │ │ │ ├── MethodCodeInstruction.java │ │ │ │ │ ├── MethodCodeInstructionArg.java │ │ │ │ │ ├── MethodCodeInstructionJump.java │ │ │ │ │ ├── MethodCodeInstructionLookupSwitch.java │ │ │ │ │ ├── MethodCodeInstructionLookupSwitchJump.java │ │ │ │ │ └── MethodCodeInstructionTableSwitch.java │ │ │ │ ├── output │ │ │ │ │ ├── JavaCG2OtherRunResult.java │ │ │ │ │ └── JavaCG2OutputInfo.java │ │ │ │ ├── stack │ │ │ │ │ └── ListAsStack.java │ │ │ │ ├── type │ │ │ │ │ ├── JavaCG2GenericsType.java │ │ │ │ │ └── JavaCG2Type.java │ │ │ │ └── variabledatasource │ │ │ │ │ ├── AbstractVariableDataSource.java │ │ │ │ │ ├── VariableDataSourceArithmeticOperation.java │ │ │ │ │ ├── VariableDataSourceField.java │ │ │ │ │ ├── VariableDataSourceMethodArg.java │ │ │ │ │ └── VariableDataSourceMethodCallReturn.java │ │ │ │ ├── el │ │ │ │ ├── checker │ │ │ │ │ ├── ElChecker.java │ │ │ │ │ ├── JavaCG2ElChecker.java │ │ │ │ │ ├── JavaCG2ElChecker4MergeFileInDir.java │ │ │ │ │ ├── JavaCG2ElChecker4MergeFileInJarWar.java │ │ │ │ │ ├── JavaCG2ElChecker4MethodCallEe.java │ │ │ │ │ ├── JavaCG2ElChecker4MethodCallEr.java │ │ │ │ │ ├── JavaCG2ElChecker4MethodCallErEe.java │ │ │ │ │ ├── JavaCG2ElChecker4ParseClass.java │ │ │ │ │ └── JavaCG2ElChecker4ParseMethod.java │ │ │ │ ├── enums │ │ │ │ │ ├── ElStringAnyFunctionEnum.java │ │ │ │ │ ├── ElStringFunctionTwoArgsEnum.java │ │ │ │ │ ├── JavaCG2ElAllowedVariableEnum.java │ │ │ │ │ ├── JavaCG2ElConfigEnum.java │ │ │ │ │ └── interfaces │ │ │ │ │ │ ├── ElAllowedVariableInterface.java │ │ │ │ │ │ └── ElConfigInterface.java │ │ │ │ ├── function │ │ │ │ │ ├── AbstractStringFunctionTwoArgs.java │ │ │ │ │ ├── any │ │ │ │ │ │ ├── AbstractStringAnyFunction.java │ │ │ │ │ │ ├── StringContainsAnyFunction.java │ │ │ │ │ │ ├── StringEndsWithAnyFunction.java │ │ │ │ │ │ ├── StringEqualsAnyFunction.java │ │ │ │ │ │ └── StringStartsWithAnyFunction.java │ │ │ │ │ └── ignorecase │ │ │ │ │ │ ├── StringContainsICFunction.java │ │ │ │ │ │ ├── StringEndsWithICFunction.java │ │ │ │ │ │ ├── StringEqualsICFunction.java │ │ │ │ │ │ └── StringStartsWithICFunction.java │ │ │ │ ├── handler │ │ │ │ │ └── ElHandler.java │ │ │ │ ├── manager │ │ │ │ │ ├── ElManager.java │ │ │ │ │ └── JavaCG2ElManager.java │ │ │ │ └── util │ │ │ │ │ └── ElUtil.java │ │ │ │ ├── entry │ │ │ │ └── JavaCG2Entry.java │ │ │ │ ├── exceptions │ │ │ │ ├── JavaCG2Error.java │ │ │ │ └── JavaCG2RuntimeException.java │ │ │ │ ├── extensions │ │ │ │ ├── annotationattributes │ │ │ │ │ ├── AnnotationAttributesFormatterInterface.java │ │ │ │ │ └── DefaultAnnotationAttributesFormatter.java │ │ │ │ ├── codeparser │ │ │ │ │ ├── AbstractSaveData2FileParser.java │ │ │ │ │ ├── CodeParserInterface.java │ │ │ │ │ ├── JarEntryOtherFileParser.java │ │ │ │ │ ├── MethodAnnotationParser.java │ │ │ │ │ └── SpringXmlBeanParserInterface.java │ │ │ │ ├── manager │ │ │ │ │ └── ExtensionsManager.java │ │ │ │ └── methodcall │ │ │ │ │ └── JavaCG2MethodCallExtensionInterface.java │ │ │ │ ├── handler │ │ │ │ ├── AbstractMethodHandler.java │ │ │ │ ├── ClassHandler.java │ │ │ │ ├── ExtendsImplHandler.java │ │ │ │ ├── InstructionHandler.java │ │ │ │ ├── MergeJarHandler.java │ │ │ │ ├── MethodCodeInstructionHandler.java │ │ │ │ ├── MethodHandler4Invoke.java │ │ │ │ └── MethodHandler4TypeAndValue.java │ │ │ │ ├── markdown │ │ │ │ ├── MarkdownConstants.java │ │ │ │ ├── enums │ │ │ │ │ └── MDCodeBlockTypeEnum.java │ │ │ │ └── writer │ │ │ │ │ └── MarkdownWriter.java │ │ │ │ ├── parser │ │ │ │ ├── AbstractJarEntryParser.java │ │ │ │ ├── JarEntryHandleParser.java │ │ │ │ ├── JarEntryPreHandle1Parser.java │ │ │ │ └── JarEntryPreHandle2Parser.java │ │ │ │ ├── spring │ │ │ │ ├── DefineSpringBeanByAnnotationHandler.java │ │ │ │ └── UseSpringBeanByAnnotationHandler.java │ │ │ │ ├── targz │ │ │ │ └── TarGzUnpacker.java │ │ │ │ ├── thread │ │ │ │ ├── JavaCG2UncaughtExceptionHandler.java │ │ │ │ └── ThreadFactory4TPE.java │ │ │ │ ├── util │ │ │ │ ├── JavaCG2AnnotationUtil.java │ │ │ │ ├── JavaCG2BootstrapMethodUtil.java │ │ │ │ ├── JavaCG2ByteCodeUtil.java │ │ │ │ ├── JavaCG2ClassMethodUtil.java │ │ │ │ ├── JavaCG2ElementUtil.java │ │ │ │ ├── JavaCG2FileUtil.java │ │ │ │ ├── JavaCG2GenericsTypeUtil.java │ │ │ │ ├── JavaCG2InstructionUtil.java │ │ │ │ ├── JavaCG2JarUtil.java │ │ │ │ └── JavaCG2Util.java │ │ │ │ └── writer │ │ │ │ └── WriterSupportSkip.java │ │ └── copy │ │ │ └── javassist │ │ │ └── bytecode │ │ │ ├── BadBytecode.java │ │ │ ├── SignatureAttribute.java │ │ │ └── package-info.java │ └── resources │ │ ├── _javacg2_config │ │ ├── config.properties │ │ ├── fr_eq_conversion_method.properties │ │ └── jar_dir.properties │ │ ├── _javacg2_merge_file_switch │ │ ├── ignore_class_in_dir.av │ │ ├── ignore_class_in_jar_war.av │ │ ├── ignore_jar_in_dir.av │ │ ├── ignore_jar_in_jar_war.av │ │ ├── ignore_jar_war_by_class_dir_prefix.av │ │ ├── ignore_other_in_dir.av │ │ ├── ignore_other_in_jar_war.av │ │ └── ignore_war_in_dir.av │ │ ├── _javacg2_parse_class_method_switch │ │ ├── parse_ignore_class.av │ │ └── parse_ignore_method.av │ │ ├── _javacg2_parse_method_call_switch │ │ ├── parse_ignore_method_call_ee.av │ │ ├── parse_ignore_method_call_er.av │ │ └── parse_ignore_method_call_er_ee.av │ │ └── el_example.md └── test │ ├── java │ └── test │ │ ├── base │ │ └── TestBase.java │ │ ├── config │ │ ├── TestAllConfig.java │ │ ├── TestCalleeRawActual.java │ │ └── TestConfig.java │ │ ├── other │ │ └── TestMd.java │ │ └── parse │ │ ├── TestNotAllowed.java │ │ ├── TestParse.java │ │ ├── TestParseElFixed.java │ │ ├── TestParseElMergeFile.java │ │ └── TestParseElMethodCall.java │ └── resources │ ├── log4j2.xml │ └── log4j2_file.xml └── unittest.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | bin/ 3 | out/ 4 | .project 5 | .settings/ 6 | .idea/ 7 | .gradle/ 8 | *.iml 9 | .classpath 10 | jar_output_dir/ 11 | log_javacg2/ 12 | runlocal/ 13 | config_local/ -------------------------------------------------------------------------------- /docs/call_type.md: -------------------------------------------------------------------------------- 1 | # 1. 方法调用类型 2 | 3 | |类型|描述| 4 | |---|---| 5 | |VIR|JVM的原始方法指令: INVOKEVIRTUAL| 6 | |INT|JVM的原始方法指令: INVOKEINTERFACE| 7 | |SPE|JVM的原始方法指令: INVOKESPECIAL| 8 | |STA|JVM的原始方法指令: INVOKESTATIC| 9 | |DYN|JVM的原始方法指令: INVOKEDYNAMIC| 10 | |_SPR_ACT_I|被调用接口为 Spring Bean ,替换为实际的实现类类型| 11 | |_SPR_ACT_C|被调用类为 Spring Bean ,替换为实际的子类类型| 12 | |_ACT_I|被调用接口替换为实际的实现类类型| 13 | |_ACT_C|被调用类替换为实际的子类类型| 14 | |_ITF|接口调用实现类对应的方法| 15 | |_LM|Lambda表达式| 16 | |_RIR1|其他方法调用Runnable 构造函数| 17 | |_RIR2|Runnable 构造函数调用 run() 方法| 18 | |_CIC1|其他方法调用Callable 构造函数| 19 | |_CIC2|Callable 构造函数调用 call() 方法| 20 | |_TCID1|其他方法调用 TransactionCallback 构造函数| 21 | |_TCID2|TransactionCallback 构造函数调用 doInTransaction() 方法| 22 | |_TCWRID1|其他方法调用 TransactionCallbackWithoutResult 构造函数| 23 | |_TCWRID2|TransactionCallbackWithoutResult 构造函数调用 doInTransactionWithoutResult() 方法| 24 | |_TSR|Thread start() 方法调用 run() 方法| 25 | |_SCC|父类调用子类对应的方法| 26 | |_CCS|子类调用父类对应的方法| 27 | |_CCS_SPE|子类通过super.调用父类方法| 28 | |_CCS_I|子接口调用父接口对应的方法| 29 | |_CCID|实现类调用接口对应的default方法| 30 | |_ICID|子接口调用父接口对应的default方法| 31 | |_MA|人工添加的方法调用| 32 | |_MAA|通过方法注解添加的调用关系| 33 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adrninistrator/java-callgraph2/1a59b1bb85def3913bb5fbc93f3320c8ac0e9c3e/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto init 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto init 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :init 68 | @rem Get command-line arguments, handling Windows variants 69 | 70 | if not "%OS%" == "Windows_NT" goto win9xME_args 71 | 72 | :win9xME_args 73 | @rem Slurp the command line arguments. 74 | set CMD_LINE_ARGS= 75 | set _SKIP=2 76 | 77 | :win9xME_args_slurp 78 | if "x%~1" == "x" goto execute 79 | 80 | set CMD_LINE_ARGS=%* 81 | 82 | :execute 83 | @rem Setup the command line 84 | 85 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 86 | 87 | @rem Execute Gradle 88 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 89 | 90 | :end 91 | @rem End local scope for the variables with windows NT shell 92 | if "%ERRORLEVEL%"=="0" goto mainEnd 93 | 94 | :fail 95 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 96 | rem the _cmd.exe /c_ return code! 97 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 98 | exit /b 1 99 | 100 | :mainEnd 101 | if "%OS%"=="Windows_NT" endlocal 102 | 103 | :omega 104 | -------------------------------------------------------------------------------- /publish.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'maven-publish' 2 | apply plugin: 'signing' 3 | 4 | apply from: 'build.gradle' 5 | 6 | task sourcesJar(type: Jar) { 7 | duplicatesStrategy = DuplicatesStrategy.INCLUDE 8 | 9 | doFirst { 10 | archiveClassifier.set('sources') 11 | from sourceSets.main.allJava 12 | } 13 | } 14 | 15 | publishing { 16 | publications { 17 | mavenJava(MavenPublication) { 18 | groupId project.group 19 | artifactId project.name 20 | version "${version}" 21 | from components.java 22 | artifact sourcesJar 23 | 24 | pom { 25 | name = "java-callgraph2" 26 | description = "Programs for producing static call graphs for Java programs" 27 | url = "https://github.com/Adrninistrator/java-callgraph2" 28 | licenses { 29 | license { 30 | name = "The Apache License, Version 2.0" 31 | url = "http://www.apache.org/licenses/LICENSE-2.0.txt" 32 | } 33 | } 34 | developers { 35 | developer { 36 | id = "Adrninistrator" 37 | name = "zhengyiee" 38 | email = "zhengyiee@qq.com" 39 | } 40 | } 41 | scm { 42 | connection = "scm:git:https://github.com/Adrninistrator/java-callgraph2.git" 43 | developerConnection = "scm:git:https://github.com/Adrninistrator/java-callgraph2.git" 44 | url = "https://github.com/Adrninistrator/java-callgraph2" 45 | } 46 | } 47 | } 48 | } 49 | repositories { 50 | maven { 51 | name 'sonatypeRepository' 52 | url 'https://oss.sonatype.org/service/local/staging/deploy/maven2/' 53 | credentials { 54 | username = "${NEXUS_USERNAME}" 55 | password = "${NEXUS_PASSWORD}" 56 | } 57 | } 58 | maven { 59 | name = 'sonatypeSnapshotRepository' 60 | url = 'https://oss.sonatype.org/content/repositories/snapshots/' 61 | credentials { 62 | username = "${NEXUS_USERNAME}" 63 | password = "${NEXUS_PASSWORD}" 64 | } 65 | } 66 | } 67 | } 68 | 69 | signing { 70 | sign publishing.publications.mavenJava 71 | } 72 | -------------------------------------------------------------------------------- /run.bat: -------------------------------------------------------------------------------- 1 | SETLOCAL ENABLEDELAYEDEXPANSION 2 | set CLASSPATH= 3 | FOR %%C IN (lib\*.jar) DO set CLASSPATH=!CLASSPATH!;%%C 4 | echo %CLASSPATH% 5 | java -Dfile.encoding=UTF-8 -cp .;./jar/run_javacg2.jar;%CLASSPATH%;./config com.adrninistrator.javacg2.entry.JavaCG2Entry 6 | 7 | pause... -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | java -Dfile.encoding=UTF-8 -cp .:./jar/run_javacg2.jar:./lib/*:./config com.adrninistrator.javacg2.entry.JavaCG2Entry -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/common/JavaCG2CommonNameConstants.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.common; 2 | 3 | import org.apache.bcel.generic.GETFIELD; 4 | import org.apache.bcel.generic.INVOKESTATIC; 5 | 6 | import java.util.TimerTask; 7 | import java.util.concurrent.Callable; 8 | 9 | /** 10 | * @author adrninistrator 11 | * @date 2023/2/10 12 | * @description: 13 | */ 14 | public class JavaCG2CommonNameConstants { 15 | public static final String CLASS_NAME_RUNNABLE = Runnable.class.getName(); 16 | public static final String CLASS_NAME_CALLABLE = Callable.class.getName(); 17 | public static final String CLASS_NAME_THREAD = Thread.class.getName(); 18 | public static final String CLASS_NAME_TIMER_TASK = TimerTask.class.getName(); 19 | public static final String CLASS_NAME_OBJECT = Object.class.getName(); 20 | public static final String CLASS_NAME_STRING = String.class.getName(); 21 | public static final String CLASS_NAME_CHAR_SEQUENCE = CharSequence.class.getName(); 22 | public static final String CLASS_NAME_CLASS = Class.class.getName(); 23 | public static final String CLASS_NAME_THROWABLE = Throwable.class.getName(); 24 | public static final String CLASS_NAME_NULL_POINTER_EXCEPTION = NullPointerException.class.getName(); 25 | 26 | public static final String CLASS_NAME_TRANSACTION_CALLBACK = "org.springframework.transaction.support.TransactionCallback"; 27 | public static final String CLASS_NAME_TRANSACTION_CALLBACK_WITHOUT_RESULT = "org.springframework.transaction.support.TransactionCallbackWithoutResult"; 28 | 29 | public static final String CLASS_NAME_GET_FIELD = GETFIELD.class.getName(); 30 | 31 | public static final String SIMPLE_CLASS_NAME_INVOKE_STATIC = INVOKESTATIC.class.getSimpleName(); 32 | public static final String SIMPLE_CLASS_NAME_OBJECT = Object.class.getSimpleName(); 33 | public static final String SIMPLE_CLASS_NAME_STRING = String.class.getSimpleName(); 34 | 35 | public static final String PACKAGE_JAVA = "java."; 36 | public static final String PACKAGE_JAVAX = "javax."; 37 | public static final String PACKAGE_JAVAFX = "javafx."; 38 | public static final String PACKAGE_SUN = "sun."; 39 | public static final String PACKAGE_COM_SUN = "com.sun."; 40 | 41 | public static final String[] PACKAGES_JDK = new String[]{PACKAGE_JAVA, PACKAGE_JAVAX, PACKAGE_JAVAFX, PACKAGE_SUN, PACKAGE_COM_SUN}; 42 | 43 | public static final String METHOD_NAME_INIT = ""; 44 | public static final String METHOD_NAME_CLINIT = ""; 45 | public static final String METHOD_NAME_START = "start"; 46 | public static final String METHOD_NAME_CLOSE = "close"; 47 | public static final String METHOD_NAME_ADD_SUPPRESSED = "addSuppressed"; 48 | 49 | public static final String METHOD_DO_IN_TRANSACTION = "doInTransaction"; 50 | public static final String METHOD_DO_IN_TRANSACTION_WITHOUT_RESULT = "doInTransactionWithoutResult"; 51 | 52 | public static final String ARGS_TRANSACTION_STATUS = 53 | JavaCG2Constants.FLAG_LEFT_BRACKET + "org.springframework.transaction.TransactionStatus" + JavaCG2Constants.FLAG_RIGHT_BRACKET; 54 | 55 | public static final String METHOD_RUNNABLE_RUN = "run"; 56 | public static final String METHOD_CALLABLE_CALL = "call"; 57 | 58 | public static final String RETURN_TYPE_VOID = "void"; 59 | 60 | public static final String CATCH = "catch"; 61 | public static final String FINALLY = "finally"; 62 | 63 | public static final String SWITCH_MAP = "$SwitchMap$"; 64 | 65 | public static final String MODIFIERS_PUBLIC = "public"; 66 | public static final String MODIFIERS_PROTECTED = "protected"; 67 | public static final String MODIFIERS_PRIVATE = "private"; 68 | public static final String MODIFIERS_DEFAULT = "default"; 69 | 70 | private JavaCG2CommonNameConstants() { 71 | throw new IllegalStateException("illegal"); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/common/JavaCG2ConfigPrintConstants.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.common; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2025/1/29 6 | * @description: 打印配置信息时使用的常量 7 | */ 8 | public class JavaCG2ConfigPrintConstants { 9 | 10 | public static final String MAIN_CONFIG = "主要的配置信息"; 11 | public static final String CONFIG_FLAG_FILE_KEY = "配置文件名称"; 12 | public static final String CONFIG_FLAG_FILE_ENUM_CLASS = "配置文件枚举类名"; 13 | public static final String CONFIG_FLAG_FILE_ENUM_CLASS_AND_NAME = "配置文件枚举类名与枚举名"; 14 | public static final String CONFIG_FLAG_FILE_DESC = "配置文件说明"; 15 | public static final String CONFIG_FLAG_CONF_KEY = "参数名称"; 16 | public static final String CONFIG_FLAG_CONF_ENUM_NAME = "参数枚举名"; 17 | public static final String CONFIG_FLAG_CONF_DESC = "参数说明"; 18 | public static final String CONFIG_FLAG_CONF_VALUE = "参数值"; 19 | public static final String CONFIG_FLAG_CONF_LIST = "区分顺序的其他配置信息"; 20 | public static final String CONFIG_FLAG_CONF_SET = "不区分顺序的其他配置信息"; 21 | 22 | private JavaCG2ConfigPrintConstants() { 23 | throw new IllegalStateException("illegal"); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/common/SpringAnnotationConstants.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.common; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2022/10/3 6 | * @description: 7 | */ 8 | public class SpringAnnotationConstants { 9 | 10 | public static final String[] SPRING_COMPONENT_ANNOTATIONS_RAW = new String[]{ 11 | "Lorg/springframework/stereotype/Component;", 12 | "Lorg/springframework/stereotype/Controller;", 13 | "Lorg/springframework/stereotype/Repository;", 14 | "Lorg/springframework/stereotype/Service;", 15 | "Lorg/springframework/web/bind/annotation/RestController;" 16 | }; 17 | 18 | public static final String ANNOTATION_ATTRIBUTE_VALUE = "value"; 19 | public static final String ANNOTATION_ATTRIBUTE_NAME = "name"; 20 | public static final String ANNOTATION_ATTRIBUTE_TYPE = "type"; 21 | 22 | public static final String ANNOTATION_NAME_RESOURCE = "Ljavax/annotation/Resource;"; 23 | public static final String ANNOTATION_NAME_AUTOWIRED = "Lorg/springframework/beans/factory/annotation/Autowired;"; 24 | public static final String ANNOTATION_NAME_QUALIFIER = "Lorg/springframework/beans/factory/annotation/Qualifier;"; 25 | public static final String ANNOTATION_NAME_CONFIGURATION = "Lorg/springframework/context/annotation/Configuration;"; 26 | public static final String ANNOTATION_NAME_BEAN = "Lorg/springframework/context/annotation/Bean;"; 27 | public static final String ANNOTATION_NAME_NAMED = "Ljavax/inject/Named;"; 28 | public static final String ANNOTATION_NAME_INJECT = "Ljavax/inject/Inject;"; 29 | 30 | private SpringAnnotationConstants() { 31 | throw new IllegalStateException("illegal"); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/common/TypeConstants.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.common; 2 | 3 | import com.adrninistrator.javacg2.common.enums.JavaCG2ConstantTypeEnum; 4 | import org.apache.bcel.Const; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2022/5/14 9 | * @description: 10 | */ 11 | public class TypeConstants { 12 | // 与int兼容的类型 13 | public static final String[] COMPATIBLE_INT_TYPES = new String[]{ 14 | JavaCG2ConstantTypeEnum.CONSTTE_BOOLEAN.getType(), 15 | JavaCG2ConstantTypeEnum.CONSTTE_BYTE.getType(), 16 | JavaCG2ConstantTypeEnum.CONSTTE_SHORT.getType(), 17 | JavaCG2ConstantTypeEnum.CONSTTE_CHAR.getType(), 18 | }; 19 | 20 | public static final String BYTE_ARRAY_TYPE = JavaCG2ConstantTypeEnum.CONSTTE_BYTE.getType() + JavaCG2Constants.FLAG_ARRAY; 21 | public static final String BOOLEAN_ARRAY_TYPE = JavaCG2ConstantTypeEnum.CONSTTE_BOOLEAN.getType() + JavaCG2Constants.FLAG_ARRAY; 22 | 23 | public static final short[] GOTO_OPCODES = new short[]{Const.GOTO, Const.GOTO_W}; 24 | 25 | private TypeConstants() { 26 | throw new IllegalStateException("illegal"); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/common/enums/JavaCG2ArithmeticOperationTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.common.enums; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2023/8/5 6 | * @description: 算术运算类型枚举 7 | */ 8 | public enum JavaCG2ArithmeticOperationTypeEnum { 9 | AOTE_ADD("+"), 10 | AOTE_SUB("-"), 11 | AOTE_MUL("*"), 12 | AOTE_DIV("/"), 13 | ; 14 | 15 | private final String type; 16 | 17 | JavaCG2ArithmeticOperationTypeEnum(String type) { 18 | this.type = type; 19 | } 20 | 21 | public String getType() { 22 | return type; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/common/enums/JavaCG2CalleeObjTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.common.enums; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2023/3/6 6 | * @description: 被调用类型枚举 7 | */ 8 | public enum JavaCG2CalleeObjTypeEnum { 9 | COTE_THIS("t", "调用当前实例的方法"), 10 | COTE_STATIC_FIELD("sf", "调用静态字段的方法"), 11 | COTE_FIELD("f", "调用字段的方法"), 12 | COTE_VARIABLE("v", "调用其他变量的方法"), 13 | ; 14 | 15 | private final String type; 16 | private final String desc; 17 | 18 | JavaCG2CalleeObjTypeEnum(String type, String desc) { 19 | this.type = type; 20 | this.desc = desc; 21 | } 22 | 23 | public String getType() { 24 | return type; 25 | } 26 | 27 | public String getDesc() { 28 | return desc; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/common/enums/JavaCG2CalleeRawActualEnum.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.common.enums; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2025/3/23 6 | * @description: 选择涉及多态的被调用的类型,使用原始的还是实际的 7 | */ 8 | public enum JavaCG2CalleeRawActualEnum { 9 | CRAE_ONLY_RAW("only_raw", "仅记录原始类型"), 10 | CRAE_ONLY_ACTUAL("only_actual", "仅记录实际类型"), 11 | CRAE_RAW_ACTUAL("raw_actual", "记录原始类型+实际类型"), 12 | ; 13 | 14 | private final String type; 15 | private final String desc; 16 | 17 | JavaCG2CalleeRawActualEnum(String type, String desc) { 18 | this.type = type; 19 | this.desc = desc; 20 | } 21 | 22 | public String getType() { 23 | return type; 24 | } 25 | 26 | public String getDesc() { 27 | return desc; 28 | } 29 | 30 | public static JavaCG2CalleeRawActualEnum getFromType(String type) { 31 | for (JavaCG2CalleeRawActualEnum javaCG2CalleeRawActualEnum : JavaCG2CalleeRawActualEnum.values()) { 32 | if (javaCG2CalleeRawActualEnum.getType().equals(type)) { 33 | return javaCG2CalleeRawActualEnum; 34 | } 35 | } 36 | return null; 37 | } 38 | 39 | public static String getAllInfo() { 40 | StringBuilder stringBuilder = new StringBuilder(); 41 | for (JavaCG2CalleeRawActualEnum javaCG2CalleeRawActualEnum : JavaCG2CalleeRawActualEnum.values()) { 42 | if (stringBuilder.length() > 0) { 43 | stringBuilder.append("\t"); 44 | } 45 | stringBuilder.append(javaCG2CalleeRawActualEnum.getType()).append(" ").append(javaCG2CalleeRawActualEnum.getDesc()); 46 | } 47 | return stringBuilder.toString(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/common/enums/JavaCG2ConstantTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.common.enums; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2022/5/13 6 | * @description: 常量类型枚举 7 | */ 8 | public enum JavaCG2ConstantTypeEnum { 9 | // 以下都使用实际的类型,用于进行比较 10 | CONSTTE_NULL("null", false), 11 | CONSTTE_INT(int.class.getName(), true), 12 | CONSTTE_LONG(long.class.getName(), true), 13 | CONSTTE_FLOAT(float.class.getName(), true), 14 | CONSTTE_DOUBLE(double.class.getName(), true), 15 | CONSTTE_BYTE(byte.class.getName(), true), 16 | CONSTTE_CHAR(char.class.getName(), true), 17 | CONSTTE_SHORT(short.class.getName(), true), 18 | CONSTTE_STRING(String.class.getName(), false), 19 | CONSTTE_BOOLEAN(boolean.class.getName(), true), 20 | CONSTTE_ILLEGAL("ILLEGAL", false), 21 | ; 22 | 23 | private final String type; 24 | private final boolean primitive; 25 | 26 | JavaCG2ConstantTypeEnum(String type, boolean primitive) { 27 | this.type = type; 28 | this.primitive = primitive; 29 | } 30 | 31 | public String getType() { 32 | return type; 33 | } 34 | 35 | public boolean isPrimitive() { 36 | return primitive; 37 | } 38 | 39 | /** 40 | * 获取常量类型枚举 41 | * 42 | * @param type 43 | * @return 44 | */ 45 | public static JavaCG2ConstantTypeEnum getFromType(String type) { 46 | for (JavaCG2ConstantTypeEnum constantTypeEnum : JavaCG2ConstantTypeEnum.values()) { 47 | if (constantTypeEnum.getType().equals(type)) { 48 | return constantTypeEnum; 49 | } 50 | } 51 | return JavaCG2ConstantTypeEnum.CONSTTE_ILLEGAL; 52 | } 53 | 54 | /** 55 | * 判断指定的类型是否为常量类型 56 | * 57 | * @param type 58 | * @return 59 | */ 60 | public static boolean isConstantType(String type) { 61 | return JavaCG2ConstantTypeEnum.CONSTTE_ILLEGAL != getFromType(type); 62 | } 63 | 64 | /** 65 | * 判断指定的类型是否为基本类型 66 | * 67 | * @param type 68 | * @return 69 | */ 70 | public static boolean isPrimitiveType(String type) { 71 | return getFromType(type).isPrimitive(); 72 | } 73 | 74 | @Override 75 | public String toString() { 76 | return type; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/common/enums/JavaCG2DirEnum.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.common.enums; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2025/1/30 6 | * @description: 7 | */ 8 | public enum JavaCG2DirEnum { 9 | 10 | IDE_CONFIG("_javacg2_config", "java-callgraph2组件主要配置文件所在目录", true), 11 | IDE_MERGE_FILE_SWITCH("_javacg2_merge_file_switch", "合并jar/war文件、目录相关开关配置文件目录", true), 12 | IDE_PARSE_CLASS_METHOD_SWITCH("_javacg2_parse_class_method_switch", "解析类、方法相关开关配置文件所在目录", true), 13 | IDE_METHOD_CALL_SWITCH("_javacg2_parse_method_call_switch", "解析方法调用相关开关配置文件所在目录", true), 14 | IDE_FAIL_CLASSES("javacg2_fail_classes", "解析失败的class文件所在目录", false), 15 | ; 16 | 17 | private final String dirName; 18 | private final String description; 19 | private final boolean input; 20 | 21 | JavaCG2DirEnum(String dirName, String description, boolean input) { 22 | this.dirName = dirName; 23 | this.description = description; 24 | this.input = input; 25 | } 26 | 27 | public String getDirName() { 28 | return dirName; 29 | } 30 | 31 | public String getDescription() { 32 | return description; 33 | } 34 | 35 | public boolean isInput() { 36 | return input; 37 | } 38 | 39 | @Override 40 | public String toString() { 41 | return dirName; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/common/enums/JavaCG2FieldRelationshipTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.common.enums; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2023/8/6 6 | * @description: 通过get/set方法关联的字段关联类型 7 | */ 8 | public enum JavaCG2FieldRelationshipTypeEnum { 9 | FRTE_DIRECTLY("DI", "字段直接赋值"), 10 | FRTE_DIRECTLY_EQUIVALENT_CONVERSION("DI_EQC", "字段经过等值转换直接赋值"), 11 | FRTE_BEAN_UTIL("BU", "通过BeanUtil等方法拷贝赋值"), 12 | FRTE_MYBATIS_MAPPER_ARG_DB("MMAD", "MyBatis Mapper方法参数对应数据库字段"), 13 | FRTE_METHOD_CALL_PASSED("MCP", "通过方法调用传递的字段赋值"), 14 | FRTE_METHOD_CALL_PASSED_EQC("MCP_EQC", "字段经过等值转换,通过方法调用传递的字段赋值"), 15 | ; 16 | 17 | private final String type; 18 | private final String desc; 19 | 20 | JavaCG2FieldRelationshipTypeEnum(String type, String desc) { 21 | this.type = type; 22 | this.desc = desc; 23 | } 24 | 25 | public String getType() { 26 | return type; 27 | } 28 | 29 | public String getDesc() { 30 | return desc; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/common/enums/JavaCG2MethodCallInfoTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.common.enums; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2023/7/2 6 | * @description: 方法调用可能的信息类型枚举 7 | */ 8 | public enum JavaCG2MethodCallInfoTypeEnum { 9 | MCIT_TYPE("t", "类型"), 10 | MCIT_VALUE("v", "值"), 11 | MCIT_BASE64_VALUE("bv", "base64编码的值"), 12 | MCIT_STATIC_FIELD("sf", "静态字段"), 13 | MCIT_STATIC_FIELD_METHOD_CALL("sfm", "静态字段的方法调用"), 14 | MCIT_NAME_OF_FIELD("nof", "字段的名称"), 15 | MCIT_NAME_OF_VARIABLE("nov", "变量的名称"), 16 | MCIT_METHOD_CALL_RETURN_CALL_ID("mcrci", "方法调用返回的call_id"), 17 | MCIT_METHOD_ARG_SEQ("mas", "方法参数的序号"), 18 | MCIT_METHOD_CALL_RETURN_CALL_ID_EQC("mcrci_eqc", "等值转换前的方法调用返回的call_id"), 19 | MCIT_METHOD_ARG_SEQ_EQC("mas_eqc", "等值转换前的方法参数的序号"), 20 | MCIT_METHOD_CATCH_EXCEPTION_FROM_OFFSET("mcefo", "方法catch的异常对象对应的catch代码块开始指令偏移量"), 21 | MCIT_ILLEGAL("_illegal", "非法类型"), 22 | ; 23 | 24 | private final String type; 25 | private final String desc; 26 | 27 | JavaCG2MethodCallInfoTypeEnum(String type, String desc) { 28 | this.type = type; 29 | this.desc = desc; 30 | } 31 | 32 | public static JavaCG2MethodCallInfoTypeEnum getFromType(String type) { 33 | for (JavaCG2MethodCallInfoTypeEnum javaCG2MethodCallInfoTypeEnum : JavaCG2MethodCallInfoTypeEnum.values()) { 34 | if (javaCG2MethodCallInfoTypeEnum.getType().equals(type)) { 35 | return javaCG2MethodCallInfoTypeEnum; 36 | } 37 | } 38 | return MCIT_ILLEGAL; 39 | } 40 | 41 | public String getType() { 42 | return type; 43 | } 44 | 45 | public String getDesc() { 46 | return desc; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/common/enums/JavaCG2OutPutFileTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.common.enums; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2023/4/12 6 | * @description: 生成文件类型枚举 7 | */ 8 | public enum JavaCG2OutPutFileTypeEnum { 9 | 10 | OPFTE_CLASS_ANNOTATION("class_annotation", "类的注解"), 11 | OPFTE_CLASS_EXT_IMPL_GENERICS_TYPE("class_ext_impl_generics_type", "类的继承或实现的泛型信息"), 12 | OPFTE_CLASS_INFO("class_info", "类的信息"), 13 | OPFTE_CLASS_REFERENCE("class_reference", "引用的类"), 14 | OPFTE_CLASS_SIGNATURE_GENERICS_TYPE("class_signature_generics_type", "类的签名中的泛型信息"), 15 | OPFTE_DUP_CLASS_INFO("dup_class_info", "重复类的信息"), 16 | OPFTE_DUP_METHOD_INFO("dup_method_info", "重复类的方法的信息"), 17 | OPFTE_ENUM_INIT_ARG_FIELD("enum_init_arg_field", "枚举类构造函数参数与字段赋值关系"), 18 | OPFTE_ENUM_INIT_ASSIGN_INFO("enum_init_assign_info", "枚举类初始化赋值信息"), 19 | OPFTE_EXTENDS_IMPL("extends_impl", "继承与实现相关信息"), 20 | OPFTE_FIELD_ANNOTATION("field_annotation", "字段的注解"), 21 | OPFTE_FIELD_GENERICS_TYPE("field_generics_type", "非静态字段集合中涉及的泛型类型"), 22 | OPFTE_FIELD_INFO("field_info", "字段信息"), 23 | OPFTE_FIELD_RELATIONSHIP("field_relationship", "通过get/set方法关联的字段关系"), 24 | OPFTE_GET_METHOD("get_method", "dto的get方法及字段"), 25 | OPFTE_INNER_CLASS("inner_class", "内部类信息"), 26 | OPFTE_JAR_INFO("jar_info", "jar包信息"), 27 | OPFTE_JAVACG2_CONFIG("javacg2_config", "java-callgraph2组件使用的配置参数"), 28 | OPFTE_LAMBDA_METHOD_INFO("lambda_method_info", "Lambda表达式方法信息"), 29 | OPFTE_LOG_METHOD_SPEND_TIME("_log_method_spend_time", "日志-方法处理耗时"), 30 | OPFTE_METHOD_ANNOTATION("method_annotation", "方法的注解"), 31 | OPFTE_METHOD_ARG_ANNOTATION("method_arg_annotation", "方法参数的注解"), 32 | OPFTE_METHOD_ARG_GENERICS_TYPE("method_arg_generics_type", "方法参数集合中涉及的泛型类型"), 33 | OPFTE_METHOD_ARGUMENT("method_argument", "方法参数"), 34 | OPFTE_METHOD_CALL("method_call", "方法调用"), 35 | OPFTE_METHOD_CALL_INFO("method_call_info", "方法调用的信息"), 36 | OPFTE_METHOD_CALL_METHOD_CALL_RETURN("method_call_method_call_return", "方法调用使用方法调用返回值"), 37 | OPFTE_METHOD_CALL_STATIC_FIELD("method_call_static_field", "方法调用使用静态字段信息"), 38 | OPFTE_METHOD_CATCH("method_catch", "方法的catch信息"), 39 | OPFTE_METHOD_FINALLY("method_finally", "方法的finally信息"), 40 | OPFTE_METHOD_INFO("method_info", "方法的信息"), 41 | OPFTE_METHOD_LINE_NUMBER("method_line_number", "方法代码行号"), 42 | OPFTE_METHOD_RETURN_ARG_SEQ("method_return_arg_seq", "方法返回值对应的方法序号"), 43 | OPFTE_METHOD_RETURN_CALL_ID("method_return_call_id", "方法返回值对应的方法调用ID"), 44 | OPFTE_METHOD_RETURN_CONST_VALUE("method_return_const_value", "方法返回的常量值(含null)"), 45 | OPFTE_METHOD_RETURN_FIELD_INFO("method_return_field_info", "方法返回的字段(含枚举)"), 46 | OPFTE_METHOD_RETURN_GENERICS_TYPE("method_return_generics_type", "方法返回集合中涉及的泛型类型"), 47 | OPFTE_METHOD_THROW("method_throw", "方法通过throw抛出的异常信息"), 48 | OPFTE_SET_METHOD("set_method", "dto的set方法及字段"), 49 | OPFTE_SF_FIELD_METHOD_CALL("sf_field_method_call", "static、final字段初始化方法信息(含枚举)"), 50 | OPFTE_SPRING_BEAN("spring_bean", "Spring Bean信息"), 51 | OPFTE_ILLEGAL("illegal", "非法值"), 52 | ; 53 | 54 | private final String fileName; 55 | private final String desc; 56 | 57 | JavaCG2OutPutFileTypeEnum(String fileName, String desc) { 58 | this.fileName = fileName; 59 | this.desc = desc; 60 | } 61 | 62 | public String getFileName() { 63 | return fileName; 64 | } 65 | 66 | public String getDesc() { 67 | return desc; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/common/enums/JavaCG2YesNoEnum.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.common.enums; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2023/3/12 6 | * @description: 7 | */ 8 | public enum JavaCG2YesNoEnum { 9 | YES("1", 1, "是"), 10 | NO("0", 0, "否"), 11 | NOT_SURE("2", 2, "不确定"), 12 | ; 13 | 14 | private final String strValue; 15 | private final int intValue; 16 | private final String desc; 17 | 18 | JavaCG2YesNoEnum(String strValue, int intValue, String desc) { 19 | this.strValue = strValue; 20 | this.intValue = intValue; 21 | this.desc = desc; 22 | } 23 | 24 | public static String parseStrValue(boolean value) { 25 | return value ? YES.strValue : NO.strValue; 26 | } 27 | 28 | public static int parseIntValue(boolean value) { 29 | return value ? YES.intValue : NO.intValue; 30 | } 31 | 32 | public static String parseDesc(boolean value) { 33 | return value ? YES.desc : NO.desc; 34 | } 35 | 36 | public static boolean isYes(String value) { 37 | return YES.strValue.equals(value); 38 | } 39 | 40 | public static boolean isYes(int value) { 41 | return YES.intValue == value; 42 | } 43 | 44 | public static boolean isYesDesc(String desc) { 45 | return YES.desc.equals(desc); 46 | } 47 | 48 | public static boolean isNotSure(String value) { 49 | return NOT_SURE.strValue.equals(value); 50 | } 51 | 52 | public static boolean isNotSure(int value) { 53 | return NOT_SURE.intValue == value; 54 | } 55 | 56 | public static boolean isNotSureDesc(String desc) { 57 | return NOT_SURE.desc.equals(desc); 58 | } 59 | 60 | public String getStrValue() { 61 | return strValue; 62 | } 63 | 64 | public int getIntValue() { 65 | return intValue; 66 | } 67 | 68 | public String getDesc() { 69 | return desc; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/comparator/Comparator4MainConfig.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.comparator; 2 | 3 | 4 | import com.adrninistrator.javacg2.conf.enums.interfaces.MainConfigInterface; 5 | 6 | import java.util.Comparator; 7 | 8 | /** 9 | * @author adrninistrator 10 | * @date 2024/8/30 11 | * @description: 12 | */ 13 | public class Comparator4MainConfig implements Comparator { 14 | private static final Comparator4MainConfig INSTANCE = new Comparator4MainConfig(); 15 | 16 | public static Comparator4MainConfig getInstance() { 17 | return INSTANCE; 18 | } 19 | 20 | private Comparator4MainConfig() { 21 | } 22 | 23 | @Override 24 | public int compare(MainConfigInterface o1, MainConfigInterface o2) { 25 | int r1 = o1.getFileName().compareTo(o2.getFileName()); 26 | if (r1 != 0) { 27 | return r1; 28 | } 29 | 30 | return o1.getKey().compareTo(o2.getKey()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/comparator/Comparator4MethodArgReturnTypes.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.comparator; 2 | 3 | import com.adrninistrator.javacg2.dto.method.MethodArgReturnTypes; 4 | 5 | import java.util.Comparator; 6 | 7 | /** 8 | * @author adrninistrator 9 | * @date 2022/11/26 10 | * @description: 11 | */ 12 | public class Comparator4MethodArgReturnTypes implements Comparator { 13 | private static final Comparator4MethodArgReturnTypes INSTANCE = new Comparator4MethodArgReturnTypes(); 14 | 15 | public static Comparator4MethodArgReturnTypes getInstance() { 16 | return INSTANCE; 17 | } 18 | 19 | private Comparator4MethodArgReturnTypes() { 20 | } 21 | 22 | @Override 23 | public int compare(MethodArgReturnTypes o1, MethodArgReturnTypes o2) { 24 | int result1 = o1.getMethodName().compareTo(o2.getMethodName()); 25 | if (result1 != 0) { 26 | return result1; 27 | } 28 | 29 | return o1.getMethodArgTypes().compareTo(o2.getMethodArgTypes()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/conf/enums/JavaCG2OtherConfigFileUseListEnum.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.conf.enums; 2 | 3 | import com.adrninistrator.javacg2.common.enums.JavaCG2DirEnum; 4 | import com.adrninistrator.javacg2.conf.enums.interfaces.OtherConfigInterface; 5 | import com.adrninistrator.javacg2.exceptions.JavaCG2RuntimeException; 6 | 7 | /** 8 | * @author adrninistrator 9 | * @date 2022/11/7 10 | * @description: 11 | */ 12 | public enum JavaCG2OtherConfigFileUseListEnum implements OtherConfigInterface { 13 | OCFULE_JAR_DIR(JavaCG2DirEnum.IDE_CONFIG.getDirName() + "/jar_dir.properties", 14 | new String[]{"(作用) 指定需要处理的jar、war包路径,或保存class、jar、war文件的目录路径(每行代表一条记录,支持多行)", 15 | "(格式) 路径中的分隔符使用/或\\均可,目录最后指定或不指定分隔符均可", 16 | "(示例) build/", 17 | "(示例) build/test.jar", 18 | "(示例) D:/test/build/test.jar"}, 19 | null 20 | ), 21 | OCFULE_CODE_PARSER_ONLY_4SHOW("代码解析扩展类名(仅用于显示)", 22 | new String[]{"对代码进行解析的扩展类完整类名"}, 23 | null 24 | ), 25 | ; 26 | 27 | // 参数配置文件名 28 | private final String fileName; 29 | // 参数配置描述 30 | private final String[] descriptions; 31 | // 默认值 32 | private final String[] defaultValues; 33 | 34 | JavaCG2OtherConfigFileUseListEnum(String fileName, String[] descriptions, String[] defaultValues) { 35 | this.fileName = fileName; 36 | this.descriptions = descriptions; 37 | this.defaultValues = defaultValues; 38 | } 39 | 40 | @Override 41 | public String getEnumName() { 42 | return name(); 43 | } 44 | 45 | @Override 46 | public String getKey() { 47 | return fileName; 48 | } 49 | 50 | @Override 51 | public String[] getDescriptions() { 52 | return descriptions; 53 | } 54 | 55 | @Override 56 | public String[] getDefaultValues() { 57 | return defaultValues; 58 | } 59 | 60 | @Override 61 | public String getConfigPrintInfo() { 62 | return fileName + " " + JavaCG2OtherConfigFileUseListEnum.class.getSimpleName() + "." + name(); 63 | } 64 | 65 | @Override 66 | public OtherConfigInterface getFromKey(String key) { 67 | for (JavaCG2OtherConfigFileUseListEnum otherConfigFileUseListEnum : JavaCG2OtherConfigFileUseListEnum.values()) { 68 | if (otherConfigFileUseListEnum.getKey().equals(key)) { 69 | return otherConfigFileUseListEnum; 70 | } 71 | } 72 | throw new JavaCG2RuntimeException("不存在的key " + key); 73 | } 74 | 75 | @Override 76 | public String toString() { 77 | return fileName; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/conf/enums/JavaCG2OtherConfigFileUseSetEnum.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.conf.enums; 2 | 3 | import com.adrninistrator.javacg2.common.JavaCG2Constants; 4 | import com.adrninistrator.javacg2.common.enums.JavaCG2DirEnum; 5 | import com.adrninistrator.javacg2.conf.enums.interfaces.OtherConfigInterface; 6 | import com.adrninistrator.javacg2.exceptions.JavaCG2RuntimeException; 7 | 8 | /** 9 | * @author adrninistrator 10 | * @date 2022/11/7 11 | * @description: 12 | */ 13 | public enum JavaCG2OtherConfigFileUseSetEnum implements OtherConfigInterface { 14 | OCFUSE_FR_EQ_CONVERSION_METHOD(JavaCG2DirEnum.IDE_CONFIG.getDirName() + "/fr_eq_conversion_method.properties", 15 | new String[]{"(作用) 在处理通过get/set方法的字段关联关系时使用,指定方法返回值与被调用对象或参数认为是等值转换的方法(每行代表一条记录,支持多行)", 16 | "(内容) key指定对应的方法,包含{完整类名}:{方法名}", 17 | "(内容) value指定与方法返回值等值的被调用对象(使用0表示)或方法参数(从1开始)序号", 18 | "(格式) {完整类名}:{方法名}={被调用对象或方法参数序号}"}, 19 | JavaCG2Constants.FR_EQ_CONVERSION_METHODS 20 | ), 21 | ; 22 | 23 | // 参数配置文件名 24 | private final String fileName; 25 | // 参数配置描述 26 | private final String[] descriptions; 27 | // 默认值 28 | private final String[] defaultValues; 29 | 30 | JavaCG2OtherConfigFileUseSetEnum(String fileName, String[] descriptions, String[] defaultValues) { 31 | this.fileName = fileName; 32 | this.descriptions = descriptions; 33 | this.defaultValues = defaultValues; 34 | } 35 | 36 | @Override 37 | public String getEnumName() { 38 | return name(); 39 | } 40 | 41 | @Override 42 | public String getKey() { 43 | return fileName; 44 | } 45 | 46 | @Override 47 | public String[] getDescriptions() { 48 | return descriptions; 49 | } 50 | 51 | @Override 52 | public String[] getDefaultValues() { 53 | return defaultValues; 54 | } 55 | 56 | @Override 57 | public String getConfigPrintInfo() { 58 | return fileName + " " + JavaCG2OtherConfigFileUseSetEnum.class.getSimpleName() + "." + name(); 59 | } 60 | 61 | @Override 62 | public OtherConfigInterface getFromKey(String key) { 63 | for (JavaCG2OtherConfigFileUseSetEnum otherConfigFileUseSetEnum : JavaCG2OtherConfigFileUseSetEnum.values()) { 64 | if (otherConfigFileUseSetEnum.getKey().equals(key)) { 65 | return otherConfigFileUseSetEnum; 66 | } 67 | } 68 | throw new JavaCG2RuntimeException("不存在的key " + key); 69 | } 70 | 71 | @Override 72 | public String toString() { 73 | return fileName; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/conf/enums/interfaces/ConfigInterface.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.conf.enums.interfaces; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2022/11/14 6 | * @description: 配置枚举继承的接口 7 | */ 8 | public interface ConfigInterface { 9 | 10 | // 获取枚举名称 11 | String getEnumName(); 12 | 13 | // 获取key 14 | String getKey(); 15 | 16 | // 获取描述 17 | String[] getDescriptions(); 18 | 19 | // 获取配置用于打印的信息 20 | String getConfigPrintInfo(); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/conf/enums/interfaces/MainConfigInterface.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.conf.enums.interfaces; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2023/3/27 6 | * @description: 主要配置文件继承的接口 7 | */ 8 | public interface MainConfigInterface extends ConfigInterface { 9 | // 字段名称 10 | String getFileName(); 11 | 12 | // 字段类型 13 | Class getType(); 14 | 15 | // 是否不允许为空 16 | boolean isNotBlank(); 17 | 18 | // 默认值 19 | String getDefaultValue(); 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/conf/enums/interfaces/OtherConfigInterface.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.conf.enums.interfaces; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2025/1/30 6 | * @description: List与Set格式的其他枚举配置实现的接口 7 | */ 8 | public interface OtherConfigInterface extends ConfigInterface { 9 | 10 | // 通过key获取对应的配置枚举 11 | OtherConfigInterface getFromKey(String key); 12 | 13 | // 默认值 14 | String[] getDefaultValues(); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/accessflag/JavaCG2AccessFlags.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.accessflag; 2 | 3 | import org.apache.bcel.classfile.AccessFlags; 4 | 5 | /** 6 | * @author adrninistrator 7 | * @date 2022/12/7 8 | * @description: 9 | */ 10 | public class JavaCG2AccessFlags extends AccessFlags { 11 | public JavaCG2AccessFlags(int accessFlags) { 12 | super(accessFlags); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/branch/BranchStackEntry.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.branch; 2 | 3 | import org.apache.bcel.generic.InstructionHandle; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | /** 9 | * @author adrninistrator 10 | * @date 2022/10/16 11 | * @description: 对分支指令进行遍历时使用的栈结构 12 | */ 13 | public class BranchStackEntry { 14 | 15 | // 分支指令 16 | private final InstructionHandle branchIh; 17 | 18 | // 目标指令列表 19 | private final List targetIhList; 20 | 21 | // 当前处理的目标指令序号 22 | private int targetIhIndex; 23 | 24 | public BranchStackEntry(InstructionHandle branchIh, int targetNum) { 25 | this.branchIh = branchIh; 26 | targetIhList = new ArrayList<>(targetNum); 27 | targetIhIndex = 0; 28 | } 29 | 30 | public void addTargetIh(InstructionHandle targetIh) { 31 | targetIhList.add(targetIh); 32 | } 33 | 34 | // 35 | public InstructionHandle getBranchIh() { 36 | return branchIh; 37 | } 38 | 39 | public List getTargetIhList() { 40 | return targetIhList; 41 | } 42 | 43 | public int getTargetIhIndex() { 44 | return targetIhIndex; 45 | } 46 | 47 | public void setTargetIhIndex(int targetIhIndex) { 48 | this.targetIhIndex = targetIhIndex; 49 | } 50 | 51 | @Override 52 | public String toString() { 53 | return "BranchStackEntry{" + 54 | "branchIh=" + branchIh + 55 | ", targetIhList=" + targetIhList + 56 | ", targetIhIndex=" + targetIhIndex + 57 | '}'; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/call/MethodCallList.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.call; 2 | 3 | import com.adrninistrator.javacg2.common.JavaCG2Constants; 4 | import com.adrninistrator.javacg2.dto.counter.JavaCG2Counter; 5 | import com.adrninistrator.javacg2.exceptions.JavaCG2RuntimeException; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | /** 11 | * @author adrninistrator 12 | * @date 2023/2/7 13 | * @description: 方法之间调用关系列表 14 | */ 15 | public class MethodCallList { 16 | 17 | // 保存方法之间调用关系 18 | private final List methodCallList = new ArrayList<>(50); 19 | 20 | // 保存方法调用计数器 21 | private final JavaCG2Counter callIdCounter; 22 | 23 | public MethodCallList(JavaCG2Counter callIdCounter) { 24 | this.callIdCounter = callIdCounter; 25 | } 26 | 27 | /** 28 | * 增加方法调用对象,使用指定的的call_id 29 | * 30 | * @param methodCall 31 | */ 32 | public void addMethodCall(MethodCall methodCall) { 33 | if (methodCall == null || methodCall.getCallId() < JavaCG2Constants.METHOD_CALL_ID_MIN) { 34 | throw new JavaCG2RuntimeException("不允许传入null,或者是call_id非法"); 35 | } 36 | methodCallList.add(methodCall); 37 | } 38 | 39 | /** 40 | * 增加方法调用对象,使用自动增加的call_id 41 | * 42 | * @param methodCall 43 | */ 44 | public void addMethodCallAutoCallId(MethodCall methodCall) { 45 | if (methodCall == null || methodCall.getCallId() >= JavaCG2Constants.METHOD_CALL_ID_MIN) { 46 | throw new JavaCG2RuntimeException("不允许传入null,或者是call_id有值"); 47 | } 48 | methodCall.setCallId(callIdCounter.addAndGet()); 49 | methodCallList.add(methodCall); 50 | } 51 | 52 | public List getMethodCallList() { 53 | return methodCallList; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/call/MethodCallPossibleInfo.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.call; 2 | 3 | import com.adrninistrator.javacg2.common.enums.JavaCG2CalleeObjTypeEnum; 4 | import com.adrninistrator.javacg2.dto.element.BaseElement; 5 | 6 | import java.util.ArrayList; 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | /** 12 | * @author adrninistrator 13 | * @date 2022/11/3 14 | * @description: 方法调用可能的信息,包括对应的被调用对象及参数 15 | */ 16 | public class MethodCallPossibleInfo { 17 | 18 | // 被调用类型 19 | private JavaCG2CalleeObjTypeEnum objTypeEnum; 20 | 21 | // 被调用对象可能的信息 22 | private MethodCallPossibleList methodCallPossibleList4Object; 23 | 24 | /* 25 | 参数可能的信息 26 | key 27 | 参数的序号,从0开始 28 | value 29 | 方法调用中被调用对象、参数的可能的信息 30 | */ 31 | private Map methodCallPossibleListMap4Args; 32 | 33 | public JavaCG2CalleeObjTypeEnum getObjTypeEnum() { 34 | return objTypeEnum; 35 | } 36 | 37 | public void setObjTypeEnum(JavaCG2CalleeObjTypeEnum objTypeEnum) { 38 | this.objTypeEnum = objTypeEnum; 39 | } 40 | 41 | /** 42 | * 为被调用对象添加可能的信息 43 | * 44 | * @param baseElement 操作数栈中的元素 45 | * @param calleeClassName 方法调用指令中被调用对象类名 46 | */ 47 | public void addPossibleInfo4Object(BaseElement baseElement, String calleeClassName) { 48 | if (methodCallPossibleList4Object == null) { 49 | methodCallPossibleList4Object = new MethodCallPossibleList(); 50 | } 51 | List handledElementList = new ArrayList<>(1); 52 | methodCallPossibleList4Object.addPossibleInfo(baseElement, calleeClassName, handledElementList); 53 | } 54 | 55 | /** 56 | * 为参数添加可能的信息 57 | * 58 | * @param seq 参数序号,从0开始 59 | * @param baseElement 操作数栈中的元素 60 | * @param argClassName 方法调用指令中参数类名 61 | */ 62 | public void addPossibleInfo4Args(int seq, BaseElement baseElement, String argClassName) { 63 | if (methodCallPossibleListMap4Args == null) { 64 | methodCallPossibleListMap4Args = new HashMap<>(); 65 | } 66 | 67 | MethodCallPossibleList methodCallPossibleList = methodCallPossibleListMap4Args.computeIfAbsent(seq, k -> new MethodCallPossibleList()); 68 | List handledElementList = new ArrayList<>(1); 69 | methodCallPossibleList.addPossibleInfo(baseElement, argClassName, handledElementList); 70 | } 71 | 72 | /** 73 | * 获取被调用对象可能的信息 74 | * 75 | * @return 76 | */ 77 | public MethodCallPossibleList getPossibleInfo4Object() { 78 | return methodCallPossibleList4Object; 79 | } 80 | 81 | /** 82 | * 获取参数可能的信息 83 | * 84 | * @param seq 参数序号,从0开始 85 | * @return 86 | */ 87 | public MethodCallPossibleList getPossibleInfo4Args(int seq) { 88 | if (methodCallPossibleListMap4Args == null) { 89 | return null; 90 | } 91 | return methodCallPossibleListMap4Args.get(seq); 92 | } 93 | 94 | /** 95 | * 获取参数可能的信息的数量 96 | * 97 | * @return 98 | */ 99 | public int getPossibleInfoNum4Args() { 100 | if (methodCallPossibleListMap4Args == null) { 101 | return 0; 102 | } 103 | return methodCallPossibleListMap4Args.size(); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/classes/ClassExtendsInfo.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.classes; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2024/7/10 6 | * @description: 类涉及继承的信息,包含类的accessFlags,父类 7 | */ 8 | public class ClassExtendsInfo { 9 | 10 | // 类的的accessFlags 11 | private final int accessFlags; 12 | 13 | // 父类名称 14 | private final String superClassName; 15 | 16 | public ClassExtendsInfo(int accessFlags, String superClassName) { 17 | this.accessFlags = accessFlags; 18 | this.superClassName = superClassName; 19 | } 20 | 21 | public int getAccessFlags() { 22 | return accessFlags; 23 | } 24 | 25 | public String getSuperClassName() { 26 | return superClassName; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/classes/InnerClassInfo.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.classes; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2023/3/25 6 | * @description: 内部类信息 7 | */ 8 | public class InnerClassInfo { 9 | // 内部类名 10 | private final String innerClassName; 11 | 12 | // 外部类名 13 | private final String outerClassName; 14 | 15 | // 是否为匿名内部类 16 | private final boolean anonymousClass; 17 | 18 | public InnerClassInfo(String innerClassName, String outerClassName, boolean anonymousClass) { 19 | this.innerClassName = innerClassName; 20 | this.outerClassName = outerClassName; 21 | this.anonymousClass = anonymousClass; 22 | } 23 | 24 | public String getInnerClassName() { 25 | return innerClassName; 26 | } 27 | 28 | public String getOuterClassName() { 29 | return outerClassName; 30 | } 31 | 32 | public boolean isAnonymousClass() { 33 | return anonymousClass; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/classes/Node4ClassExtendsMethod.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.classes; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2021/6/27 6 | * @description: 处理涉及继承的类的方法时使用的栈的节点 7 | */ 8 | 9 | public class Node4ClassExtendsMethod { 10 | // 父类类名 11 | private final String superClassName; 12 | 13 | // 当前处理的子类序号 14 | private int childClassIndex; 15 | 16 | public Node4ClassExtendsMethod(String superClassName, int childClassIndex) { 17 | this.superClassName = superClassName; 18 | this.childClassIndex = childClassIndex; 19 | } 20 | 21 | // get 22 | public String getSuperClassName() { 23 | return superClassName; 24 | } 25 | 26 | public int getChildClassIndex() { 27 | return childClassIndex; 28 | } 29 | 30 | // set 31 | public void setChildClassIndex(int childClassIndex) { 32 | this.childClassIndex = childClassIndex; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/counter/JavaCG2Counter.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.counter; 2 | 3 | /** 4 | * @author Adrninistrator 5 | * @date 2021/8/10 6 | * @description: 计数器 7 | */ 8 | public class JavaCG2Counter { 9 | private int count; 10 | 11 | public JavaCG2Counter() { 12 | this(0); 13 | } 14 | 15 | public JavaCG2Counter(int count) { 16 | this.count = count; 17 | } 18 | 19 | // 计数加1后返回 20 | public int addAndGet() { 21 | return ++count; 22 | } 23 | 24 | // 计数增加指定数量后返回 25 | public int addAndGet(int num) { 26 | return count += num; 27 | } 28 | 29 | // 计数减 1后返回 30 | public int minusAndGet() { 31 | return --count; 32 | } 33 | 34 | // 35 | public int getCount() { 36 | return count; 37 | } 38 | 39 | public void setCount(int count) { 40 | this.count = count; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "count=" + count; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/element/constant/ConstElement.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.element.constant; 2 | 3 | import com.adrninistrator.javacg2.common.enums.JavaCG2ConstantTypeEnum; 4 | import com.adrninistrator.javacg2.dto.element.BaseElement; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2022/5/13 9 | * @description: 常量基类 10 | */ 11 | public abstract class ConstElement extends BaseElement { 12 | 13 | ConstElement(Object value) { 14 | if (value != null) { 15 | this.value = value; 16 | } 17 | } 18 | 19 | /** 20 | * 返回当前常量的类型 21 | * 22 | * @return 23 | */ 24 | public JavaCG2ConstantTypeEnum getConstantTypeEnum() { 25 | return null; 26 | } 27 | 28 | @Override 29 | public String getType() { 30 | JavaCG2ConstantTypeEnum javaCG2ConstantTypeEnum = getConstantTypeEnum(); 31 | if (javaCG2ConstantTypeEnum == null) { 32 | return null; 33 | } 34 | return javaCG2ConstantTypeEnum.getType(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/element/constant/ConstElementByte.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.element.constant; 2 | 3 | import com.adrninistrator.javacg2.common.enums.JavaCG2ConstantTypeEnum; 4 | import com.adrninistrator.javacg2.dto.element.BaseElement; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2022/5/14 9 | * @description: 10 | */ 11 | public class ConstElementByte extends ConstElement { 12 | 13 | public ConstElementByte(Object value) { 14 | super(value); 15 | } 16 | 17 | @Override 18 | public JavaCG2ConstantTypeEnum getConstantTypeEnum() { 19 | return JavaCG2ConstantTypeEnum.CONSTTE_BYTE; 20 | } 21 | 22 | @Override 23 | public BaseElement copyElement() { 24 | return new ConstElementByte(value); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/element/constant/ConstElementDouble.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.element.constant; 2 | 3 | import com.adrninistrator.javacg2.common.enums.JavaCG2ConstantTypeEnum; 4 | import com.adrninistrator.javacg2.dto.element.BaseElement; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2022/5/13 9 | * @description: 10 | */ 11 | public class ConstElementDouble extends ConstElement { 12 | 13 | public ConstElementDouble(Object value) { 14 | super(value); 15 | } 16 | 17 | @Override 18 | public JavaCG2ConstantTypeEnum getConstantTypeEnum() { 19 | return JavaCG2ConstantTypeEnum.CONSTTE_DOUBLE; 20 | } 21 | 22 | @Override 23 | public BaseElement copyElement() { 24 | return new ConstElementDouble(value); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/element/constant/ConstElementFloat.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.element.constant; 2 | 3 | import com.adrninistrator.javacg2.common.enums.JavaCG2ConstantTypeEnum; 4 | import com.adrninistrator.javacg2.dto.element.BaseElement; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2022/5/13 9 | * @description: 10 | */ 11 | public class ConstElementFloat extends ConstElement { 12 | 13 | public ConstElementFloat(Object value) { 14 | super(value); 15 | } 16 | 17 | @Override 18 | public JavaCG2ConstantTypeEnum getConstantTypeEnum() { 19 | return JavaCG2ConstantTypeEnum.CONSTTE_FLOAT; 20 | } 21 | 22 | @Override 23 | public BaseElement copyElement() { 24 | return new ConstElementFloat(value); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/element/constant/ConstElementInt.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.element.constant; 2 | 3 | import com.adrninistrator.javacg2.common.enums.JavaCG2ConstantTypeEnum; 4 | import com.adrninistrator.javacg2.dto.element.BaseElement; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2022/5/13 9 | * @description: 10 | */ 11 | public class ConstElementInt extends ConstElement { 12 | 13 | public ConstElementInt(Object value) { 14 | super(value); 15 | } 16 | 17 | @Override 18 | public JavaCG2ConstantTypeEnum getConstantTypeEnum() { 19 | return JavaCG2ConstantTypeEnum.CONSTTE_INT; 20 | } 21 | 22 | @Override 23 | public BaseElement copyElement() { 24 | return new ConstElementInt(value); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/element/constant/ConstElementLong.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.element.constant; 2 | 3 | import com.adrninistrator.javacg2.common.enums.JavaCG2ConstantTypeEnum; 4 | import com.adrninistrator.javacg2.dto.element.BaseElement; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2022/5/13 9 | * @description: 10 | */ 11 | public class ConstElementLong extends ConstElement { 12 | 13 | public ConstElementLong(Object value) { 14 | super(value); 15 | } 16 | 17 | @Override 18 | public JavaCG2ConstantTypeEnum getConstantTypeEnum() { 19 | return JavaCG2ConstantTypeEnum.CONSTTE_LONG; 20 | } 21 | 22 | @Override 23 | public BaseElement copyElement() { 24 | return new ConstElementLong(value); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/element/constant/ConstElementNull.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.element.constant; 2 | 3 | import com.adrninistrator.javacg2.common.enums.JavaCG2ConstantTypeEnum; 4 | import com.adrninistrator.javacg2.dto.element.BaseElement; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2022/5/13 9 | * @description: 10 | */ 11 | public class ConstElementNull extends ConstElement { 12 | public ConstElementNull() { 13 | super(null); 14 | } 15 | 16 | @Override 17 | public JavaCG2ConstantTypeEnum getConstantTypeEnum() { 18 | return JavaCG2ConstantTypeEnum.CONSTTE_NULL; 19 | } 20 | 21 | @Override 22 | public BaseElement copyElement() { 23 | return new ConstElementNull(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/element/constant/ConstElementShort.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.element.constant; 2 | 3 | import com.adrninistrator.javacg2.common.enums.JavaCG2ConstantTypeEnum; 4 | import com.adrninistrator.javacg2.dto.element.BaseElement; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2022/5/14 9 | * @description: 10 | */ 11 | public class ConstElementShort extends ConstElement { 12 | 13 | public ConstElementShort(Object value) { 14 | super(value); 15 | } 16 | 17 | @Override 18 | public JavaCG2ConstantTypeEnum getConstantTypeEnum() { 19 | return JavaCG2ConstantTypeEnum.CONSTTE_SHORT; 20 | } 21 | 22 | @Override 23 | public BaseElement copyElement() { 24 | return new ConstElementShort(value); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/element/constant/ConstElementString.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.element.constant; 2 | 3 | import com.adrninistrator.javacg2.common.enums.JavaCG2ConstantTypeEnum; 4 | import com.adrninistrator.javacg2.dto.element.BaseElement; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2022/5/14 9 | * @description: 10 | */ 11 | public class ConstElementString extends ConstElement { 12 | 13 | public ConstElementString(Object value) { 14 | super(value); 15 | } 16 | 17 | @Override 18 | public JavaCG2ConstantTypeEnum getConstantTypeEnum() { 19 | return JavaCG2ConstantTypeEnum.CONSTTE_STRING; 20 | } 21 | 22 | @Override 23 | public BaseElement copyElement() { 24 | return new ConstElementString(value); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/element/variable/FieldElement.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.element.variable; 2 | 3 | import com.adrninistrator.javacg2.common.JavaCG2Constants; 4 | import com.adrninistrator.javacg2.dto.element.BaseElement; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2022/10/5 9 | * @description: 字段 10 | */ 11 | public class FieldElement extends LocalVariableElement { 12 | 13 | // 类名或this 14 | protected final String className; 15 | 16 | public FieldElement(String type, int addArrayDimensions, Object value, String name, String className) { 17 | super(type, addArrayDimensions, value, JavaCG2Constants.LOCAL_VARIABLE_INDEX_NOT_USED, name); 18 | this.className = className; 19 | } 20 | 21 | public FieldElement(String type, int addArrayDimensions, Object value, int index, String name, String className) { 22 | super(type, addArrayDimensions, value, index, name); 23 | this.className = className; 24 | } 25 | 26 | @Override 27 | public BaseElement copyElement() { 28 | FieldElement fieldElementCopy = new FieldElement(getType(), 0, value, getIndex(), getName(), className); 29 | fieldElementCopy.copyVariableDataSource(this); 30 | fieldElementCopy.setArrayValueMap(getArrayValueMap()); 31 | return fieldElementCopy; 32 | } 33 | 34 | public String getClassName() { 35 | return className; 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return "FieldElement{" + 41 | "type='" + getType() + '\'' + 42 | ", value=" + value + 43 | ", name='" + getName() + '\'' + 44 | ", className='" + className + '\''; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/element/variable/JSRElement.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.element.variable; 2 | 3 | import com.adrninistrator.javacg2.common.JavaCG2Constants; 4 | import org.apache.bcel.generic.InstructionHandle; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2022/9/20 9 | * @description: JSR指令向操作数栈添加的元素 10 | */ 11 | public class JSRElement extends LocalVariableElement { 12 | 13 | // 使用value保存JSR下一条指令 14 | public JSRElement(InstructionHandle nextIh) { 15 | super(JavaCG2Constants.JSR_TYPE, 0, nextIh, JavaCG2Constants.LOCAL_VARIABLE_INDEX_NOT_USED, null); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/element/variable/LocalVariableElement.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.element.variable; 2 | 3 | import com.adrninistrator.javacg2.dto.element.BaseElement; 4 | 5 | /** 6 | * @author adrninistrator 7 | * @date 2022/10/5 8 | * @description: 本地变量 9 | */ 10 | public class LocalVariableElement extends VariableElement { 11 | 12 | // 本地变量索引 13 | private final int index; 14 | 15 | // 名称 16 | private final String name; 17 | 18 | public LocalVariableElement(String type, int addArrayDimensions, Object value, int index, String name) { 19 | super(type, addArrayDimensions); 20 | this.value = value; 21 | this.index = index; 22 | this.name = name; 23 | } 24 | 25 | @Override 26 | public BaseElement copyElement() { 27 | LocalVariableElement localVariableElementCopy = new LocalVariableElement(getType(), 0, value, index, name); 28 | localVariableElementCopy.copyVariableDataSource(this); 29 | localVariableElementCopy.setArrayValueMap(getArrayValueMap()); 30 | return localVariableElementCopy; 31 | } 32 | 33 | // 复制一个值为null,其他字段相同的本地变量 34 | public LocalVariableElement copyWithNullValue() { 35 | LocalVariableElement localVariableElementCopy = new LocalVariableElement(getType(), 0, null, index, name); 36 | localVariableElementCopy.setArrayValueMap(getArrayValueMap()); 37 | return localVariableElementCopy; 38 | } 39 | 40 | // 判断是否为this 41 | public boolean isThis() { 42 | return index == 0; 43 | } 44 | 45 | public int getIndex() { 46 | return index; 47 | } 48 | 49 | public String getName() { 50 | return name; 51 | } 52 | 53 | @Override 54 | public String toString() { 55 | return "LocalVariableElement{" + 56 | "type='" + getType() + '\'' + 57 | ", value=" + value + 58 | ", index=" + index + 59 | ", name='" + name + '\'' + 60 | '}'; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/element/variable/StaticFieldElement.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.element.variable; 2 | 3 | import com.adrninistrator.javacg2.dto.element.BaseElement; 4 | 5 | /** 6 | * @author adrninistrator 7 | * @date 2022/10/5 8 | * @description: 静态字段 9 | */ 10 | public class StaticFieldElement extends FieldElement { 11 | 12 | public StaticFieldElement(String type, int addArrayDimensions, Object value, String variableName, String className) { 13 | super(type, addArrayDimensions, value, variableName, className); 14 | } 15 | 16 | public StaticFieldElement(String type, int addArrayDimensions, Object value, int index, String variableName, String className) { 17 | super(type, addArrayDimensions, value, index, variableName, className); 18 | } 19 | 20 | @Override 21 | public BaseElement copyElement() { 22 | StaticFieldElement staticFieldElementCopy = new StaticFieldElement(getType(), 0, value, getIndex(), getName(), className); 23 | staticFieldElementCopy.copyVariableDataSource(this); 24 | staticFieldElementCopy.setArrayValueMap(getArrayValueMap()); 25 | return staticFieldElementCopy; 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | return "StaticFieldElement{" + 31 | "simpleClassName='" + simpleClassName + '\'' + 32 | ", type='" + getType() + '\'' + 33 | ", value=" + value + 34 | ", name='" + getName() + '\'' + 35 | ", className='" + className + '\''; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/element/variable/StaticFieldMethodCallElement.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.element.variable; 2 | 3 | import com.adrninistrator.javacg2.dto.element.BaseElement; 4 | import com.adrninistrator.javacg2.util.JavaCG2ClassMethodUtil; 5 | import org.apache.bcel.generic.Type; 6 | 7 | import java.util.Arrays; 8 | 9 | /** 10 | * @author adrninistrator 11 | * @date 2022/11/11 12 | * @description: 静态字段的方法调用 13 | */ 14 | public class StaticFieldMethodCallElement extends VariableElement { 15 | 16 | // 被调用的类名 17 | private final String className; 18 | 19 | // 被调用的字段名称 20 | private final String fieldName; 21 | 22 | // 被调用的方法名称 23 | private final String methodName; 24 | 25 | // 被调用的方法参数类型 26 | private final Type[] argTypes; 27 | 28 | // type字段为被调用的方法返回类型 29 | 30 | public StaticFieldMethodCallElement(String type, int addArrayDimensions, String className, String fieldName, String methodName, Type[] argTypes) { 31 | super(type, addArrayDimensions); 32 | this.className = className; 33 | this.fieldName = fieldName; 34 | this.methodName = methodName; 35 | this.argTypes = argTypes; 36 | } 37 | 38 | @Override 39 | public BaseElement copyElement() { 40 | StaticFieldMethodCallElement staticFieldMethodCallElementCopy = new StaticFieldMethodCallElement(getType(), 0, className, fieldName, methodName, argTypes); 41 | staticFieldMethodCallElementCopy.copyVariableDataSource(this); 42 | staticFieldMethodCallElementCopy.setArrayValueMap(getArrayValueMap()); 43 | return staticFieldMethodCallElementCopy; 44 | } 45 | 46 | public String getInfo() { 47 | return JavaCG2ClassMethodUtil.formatClassFieldMethodArgTypes(className, fieldName, methodName, argTypes, getType()); 48 | } 49 | 50 | @Override 51 | public String toString() { 52 | return "StaticFieldMethodCallElement{" + 53 | "simpleClassName='" + simpleClassName + '\'' + 54 | ", type='" + getType() + '\'' + 55 | ", value=" + value + 56 | ", className='" + className + '\'' + 57 | ", fieldName='" + fieldName + '\'' + 58 | ", methodName='" + methodName + '\'' + 59 | ", argTypes='" + Arrays.toString(argTypes) + '\'' + 60 | '}'; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/exception/CatchAndFinallyInfo.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.exception; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2023/12/28 9 | * @description: Exception table中某个try对应的catch、finally信息 10 | */ 11 | public class CatchAndFinallyInfo { 12 | 13 | private final List catchInfoList = new ArrayList<>(); 14 | 15 | private FinallyInfo finallyInfo; 16 | 17 | public List getCatchInfoList() { 18 | return catchInfoList; 19 | } 20 | 21 | public FinallyInfo getFinallyInfo() { 22 | return finallyInfo; 23 | } 24 | 25 | public void setFinallyInfo(FinallyInfo finallyInfo) { 26 | this.finallyInfo = finallyInfo; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/exception/CatchInfo.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.exception; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2023/12/28 9 | * @description: Exception table中的catch信息 10 | */ 11 | public class CatchInfo extends FinallyInfo { 12 | 13 | private final List catchExceptionTypeList; 14 | 15 | public CatchInfo(int fromPosition, int toPosition, int endPosition, int targetPosition, String catchExceptionType) { 16 | super(fromPosition, toPosition, endPosition, targetPosition); 17 | catchExceptionTypeList = new ArrayList<>(1); 18 | catchExceptionTypeList.add(catchExceptionType); 19 | } 20 | 21 | public void addCatchExceptionType(String catchExceptionType) { 22 | catchExceptionTypeList.add(catchExceptionType); 23 | } 24 | 25 | public List getCatchExceptionTypeList() { 26 | return catchExceptionTypeList; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/exception/ExceptionTargetInfo.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.exception; 2 | 3 | import org.apache.bcel.generic.InstructionHandle; 4 | 5 | /** 6 | * @author adrninistrator 7 | * @date 2022/10/30 8 | * @description: Exception table的target指令及异常类型 9 | */ 10 | public class ExceptionTargetInfo { 11 | 12 | // Exception table的target指令 13 | private final InstructionHandle target; 14 | 15 | // 异常类型 16 | private final String exceptionType; 17 | 18 | public ExceptionTargetInfo(InstructionHandle target, String exceptionType) { 19 | this.target = target; 20 | this.exceptionType = exceptionType; 21 | } 22 | 23 | public InstructionHandle getTarget() { 24 | return target; 25 | } 26 | 27 | public String getExceptionType() { 28 | return exceptionType; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/exception/FinallyInfo.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.exception; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2023/12/28 6 | * @description: Exception table中的finally信息 7 | */ 8 | public class FinallyInfo { 9 | protected final int fromPosition; 10 | protected final int toPosition; 11 | protected final int endPosition; 12 | protected final int targetPosition; 13 | 14 | public FinallyInfo(int fromPosition, int toPosition, int endPosition, int targetPosition) { 15 | this.fromPosition = fromPosition; 16 | this.toPosition = toPosition; 17 | this.endPosition = endPosition; 18 | this.targetPosition = targetPosition; 19 | } 20 | 21 | public int getFromPosition() { 22 | return fromPosition; 23 | } 24 | 25 | public int getToPosition() { 26 | return toPosition; 27 | } 28 | 29 | public int getEndPosition() { 30 | return endPosition; 31 | } 32 | 33 | public int getTargetPosition() { 34 | return targetPosition; 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return "FinallyInfo{" + 40 | "fromPosition=" + fromPosition + 41 | ", toPosition=" + toPosition + 42 | ", endPosition=" + endPosition + 43 | ", targetPosition=" + targetPosition + 44 | '}'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/exception/ThrowInfo.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.exception; 2 | 3 | import java.util.Objects; 4 | 5 | /** 6 | * @author adrninistrator 7 | * @date 2024/1/2 8 | * @description: 方法中抛出的异常信息 9 | */ 10 | public class ThrowInfo { 11 | 12 | // 抛出的异常类型 13 | private final String throwExceptionType; 14 | 15 | // 抛出异常的标志 16 | private final String throwFlag; 17 | 18 | // 抛出异常属于catch的异常对象时,对应的catch代码块开始指令偏移量 19 | private final Integer catchStartPosition; 20 | 21 | // 抛出异常属于catch的异常对象时,对应catch的异常对象变量名称(以下equals、hashCode方法可以不判断该字段) 22 | private final String catchExceptionVariableName; 23 | 24 | // 抛出异常属于方法调用返回值时,对应的方法调用指令偏移量 25 | private final Integer invokeInstructionPosition; 26 | 27 | public ThrowInfo(String throwExceptionType, String throwFlag, Integer catchStartPosition, String catchExceptionVariableName, Integer invokeInstructionPosition) { 28 | this.throwExceptionType = throwExceptionType; 29 | this.throwFlag = throwFlag; 30 | this.catchStartPosition = catchStartPosition; 31 | this.catchExceptionVariableName = catchExceptionVariableName; 32 | this.invokeInstructionPosition = invokeInstructionPosition; 33 | } 34 | 35 | public String getThrowExceptionType() { 36 | return throwExceptionType; 37 | } 38 | 39 | public String getThrowFlag() { 40 | return throwFlag; 41 | } 42 | 43 | public Integer getCatchStartPosition() { 44 | return catchStartPosition; 45 | } 46 | 47 | public String getCatchExceptionVariableName() { 48 | return catchExceptionVariableName; 49 | } 50 | 51 | public Integer getInvokeInstructionPosition() { 52 | return invokeInstructionPosition; 53 | } 54 | 55 | @Override 56 | public boolean equals(Object o) { 57 | if (this == o) return true; 58 | if (o == null || getClass() != o.getClass()) return false; 59 | ThrowInfo throwInfo = (ThrowInfo) o; 60 | return throwExceptionType.equals(throwInfo.throwExceptionType) && throwFlag.equals(throwInfo.throwFlag) && Objects.equals(catchStartPosition, 61 | throwInfo.catchStartPosition) && Objects.equals(invokeInstructionPosition, throwInfo.invokeInstructionPosition); 62 | } 63 | 64 | @Override 65 | public int hashCode() { 66 | return Objects.hash(throwExceptionType, throwFlag, catchStartPosition, invokeInstructionPosition); 67 | } 68 | 69 | @Override 70 | public String toString() { 71 | return "ThrowInfo{" + 72 | "throwExceptionType='" + throwExceptionType + '\'' + 73 | ", throwFlag='" + throwFlag + '\'' + 74 | ", catchStartPosition=" + catchStartPosition + 75 | ", invokeInstructionPosition=" + invokeInstructionPosition + 76 | '}'; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/exception/ThrowInfoList.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.exception; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2024/1/2 9 | * @description: 代码中抛出的可能的异常信息列表 10 | */ 11 | public class ThrowInfoList { 12 | 13 | private final List throwInfoList = new ArrayList<>(1); 14 | 15 | public void addThrowInfo(ThrowInfo throwInfo) { 16 | if (!throwInfoList.contains(throwInfo)) { 17 | throwInfoList.add(throwInfo); 18 | } 19 | } 20 | 21 | public int size() { 22 | return throwInfoList.size(); 23 | } 24 | 25 | public ThrowInfo get(int i) { 26 | return throwInfoList.get(i); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/field/ClassField.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.field; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2025/2/21 6 | * @description: 类中的字段 7 | */ 8 | public class ClassField { 9 | 10 | // 类名 11 | private String className; 12 | 13 | // 字段名称 14 | private String fieldName; 15 | 16 | public String getClassName() { 17 | return className; 18 | } 19 | 20 | public void setClassName(String className) { 21 | this.className = className; 22 | } 23 | 24 | public String getFieldName() { 25 | return fieldName; 26 | } 27 | 28 | public void setFieldName(String fieldName) { 29 | this.fieldName = fieldName; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/field/ClassFieldMethodCall.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.field; 2 | 3 | import com.adrninistrator.javacg2.util.JavaCG2ClassMethodUtil; 4 | 5 | /** 6 | * @author adrninistrator 7 | * @date 2025/2/19 8 | * @description: 对类中字段的方法调用 9 | */ 10 | public class ClassFieldMethodCall extends ClassField { 11 | 12 | // 被调用的方法名称 13 | private String methodName; 14 | 15 | // 被调用的方法参数类型 16 | private String[] argTypes; 17 | 18 | // 被调用的方法返回类型 19 | private String returnType; 20 | 21 | public String genFullMethod() { 22 | return JavaCG2ClassMethodUtil.formatFullMethodStr(getClassName(), methodName, argTypes); 23 | } 24 | 25 | // 26 | public String getMethodName() { 27 | return methodName; 28 | } 29 | 30 | public void setMethodName(String methodName) { 31 | this.methodName = methodName; 32 | } 33 | 34 | public String[] getArgTypes() { 35 | return argTypes; 36 | } 37 | 38 | public void setArgTypes(String[] argTypes) { 39 | this.argTypes = argTypes; 40 | } 41 | 42 | public String getReturnType() { 43 | return returnType; 44 | } 45 | 46 | public void setReturnType(String returnType) { 47 | this.returnType = returnType; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/field/FieldPossibleTypes.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.field; 2 | 3 | import com.adrninistrator.javacg2.util.JavaCG2ByteCodeUtil; 4 | 5 | import java.util.ArrayList; 6 | import java.util.HashMap; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | /** 11 | * @author adrninistrator 12 | * @date 2023/1/4 13 | * @description: 字段所有可能的类型 14 | */ 15 | public class FieldPossibleTypes { 16 | /* 17 | 记录字段所有可能的类型 18 | key 19 | 字段名称 20 | value 21 | 字段所有可能的类型列表 22 | */ 23 | private final Map> possibleTypeMap = new HashMap<>(); 24 | 25 | /** 26 | * 为字段添加可能的类型 27 | * 28 | * @param fieldName 29 | * @param possibleType 30 | */ 31 | public void addPossibleType(String fieldName, String possibleType) { 32 | if (JavaCG2ByteCodeUtil.isNullType(possibleType)) { 33 | return; 34 | } 35 | 36 | List possibleTypeList = possibleTypeMap.computeIfAbsent(fieldName, k -> new ArrayList<>()); 37 | if (!possibleTypeList.contains(possibleType)) { 38 | possibleTypeList.add(possibleType); 39 | } 40 | } 41 | 42 | /** 43 | * 获取字段可能的类型 44 | * 45 | * @param fieldName 46 | * @return 47 | */ 48 | public List getPossibleTypeList(String fieldName) { 49 | return possibleTypeMap.get(fieldName); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/field/FieldTypeAndName.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.field; 2 | 3 | import java.util.Objects; 4 | 5 | /** 6 | * @author adrninistrator 7 | * @date 2022/11/3 8 | * @description: 字段类型及名称 9 | */ 10 | public class FieldTypeAndName { 11 | 12 | // 字段类型 13 | protected final String fieldType; 14 | 15 | // 字段名称 16 | protected final String fieldName; 17 | 18 | public FieldTypeAndName(String fieldType, String fieldName) { 19 | this.fieldType = fieldType; 20 | this.fieldName = fieldName; 21 | } 22 | 23 | @Override 24 | public boolean equals(Object o) { 25 | if (this == o) return true; 26 | if (o == null || getClass() != o.getClass()) return false; 27 | FieldTypeAndName that = (FieldTypeAndName) o; 28 | return fieldName.equals(that.fieldName); 29 | } 30 | 31 | @Override 32 | public int hashCode() { 33 | return Objects.hash(fieldName); 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | return "fieldType=" + fieldType + 39 | ", fieldName=" + fieldName; 40 | } 41 | 42 | // 43 | public String getFieldType() { 44 | return fieldType; 45 | } 46 | 47 | public String getFieldName() { 48 | return fieldName; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/field/StaticFieldTypeAndName.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.field; 2 | 3 | import com.adrninistrator.javacg2.util.JavaCG2ClassMethodUtil; 4 | 5 | import java.util.Objects; 6 | 7 | /** 8 | * @author adrninistrator 9 | * @date 2024/2/2 10 | * @description: 类中的静态字段类型及名称 11 | */ 12 | public class StaticFieldTypeAndName extends FieldTypeAndName { 13 | 14 | // 类名 15 | private final String className; 16 | 17 | public StaticFieldTypeAndName(String fieldType, String fieldName, String className) { 18 | super(fieldType, fieldName); 19 | this.className = className; 20 | } 21 | 22 | /** 23 | * 获取类名+字段名 24 | * 25 | * @return 类名:字段名 26 | */ 27 | public String getClassAndFieldName() { 28 | return JavaCG2ClassMethodUtil.formatClassAndField(className, fieldName); 29 | } 30 | 31 | @Override 32 | public boolean equals(Object o) { 33 | if (this == o) return true; 34 | if (o == null || getClass() != o.getClass()) return false; 35 | if (!super.equals(o)) return false; 36 | StaticFieldTypeAndName that = (StaticFieldTypeAndName) o; 37 | return fieldName.equals(that.fieldName) && className.equals(that.className); 38 | } 39 | 40 | @Override 41 | public int hashCode() { 42 | return Objects.hash(fieldName, className); 43 | } 44 | 45 | public String getClassName() { 46 | return className; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/fieldrelationship/GetSetFieldRelationship.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.fieldrelationship; 2 | 3 | import com.adrninistrator.javacg2.common.enums.JavaCG2FieldRelationshipTypeEnum; 4 | 5 | /** 6 | * @author adrninistrator 7 | * @date 2023/10/16 8 | * @description: get/set方法对应的字段关系 9 | */ 10 | public class GetSetFieldRelationship { 11 | 12 | // 记录ID 13 | private int recordId; 14 | 15 | // set方法调用的指令位置 16 | private Integer setInvokeInstructionPosition; 17 | 18 | // get方法调用的指令位置 19 | private Integer getInvokeInstructionPosition; 20 | 21 | // 调用方,源代码行号 22 | private int callerLineNumber; 23 | 24 | // get方法完整类名 25 | private String getClassName; 26 | 27 | // get方法方法名 28 | private String getMethodName; 29 | 30 | // set方法完整类名 31 | private String setClassName; 32 | 33 | // set方法方法名 34 | private String setMethodName; 35 | 36 | // 关联关系是否有效 37 | private String valid; 38 | 39 | // 关联关系类型 40 | private JavaCG2FieldRelationshipTypeEnum type; 41 | 42 | public int getRecordId() { 43 | return recordId; 44 | } 45 | 46 | public void setRecordId(int recordId) { 47 | this.recordId = recordId; 48 | } 49 | 50 | public Integer getSetInvokeInstructionPosition() { 51 | return setInvokeInstructionPosition; 52 | } 53 | 54 | public void setSetInvokeInstructionPosition(Integer setInvokeInstructionPosition) { 55 | this.setInvokeInstructionPosition = setInvokeInstructionPosition; 56 | } 57 | 58 | public Integer getGetInvokeInstructionPosition() { 59 | return getInvokeInstructionPosition; 60 | } 61 | 62 | public void setGetInvokeInstructionPosition(Integer getInvokeInstructionPosition) { 63 | this.getInvokeInstructionPosition = getInvokeInstructionPosition; 64 | } 65 | 66 | public int getCallerLineNumber() { 67 | return callerLineNumber; 68 | } 69 | 70 | public void setCallerLineNumber(int callerLineNumber) { 71 | this.callerLineNumber = callerLineNumber; 72 | } 73 | 74 | public String getGetClassName() { 75 | return getClassName; 76 | } 77 | 78 | public void setGetClassName(String getClassName) { 79 | this.getClassName = getClassName; 80 | } 81 | 82 | public String getGetMethodName() { 83 | return getMethodName; 84 | } 85 | 86 | public void setGetMethodName(String getMethodName) { 87 | this.getMethodName = getMethodName; 88 | } 89 | 90 | public String getSetClassName() { 91 | return setClassName; 92 | } 93 | 94 | public void setSetClassName(String setClassName) { 95 | this.setClassName = setClassName; 96 | } 97 | 98 | public String getSetMethodName() { 99 | return setMethodName; 100 | } 101 | 102 | public void setSetMethodName(String setMethodName) { 103 | this.setMethodName = setMethodName; 104 | } 105 | 106 | public String getValid() { 107 | return valid; 108 | } 109 | 110 | public void setValid(String valid) { 111 | this.valid = valid; 112 | } 113 | 114 | public JavaCG2FieldRelationshipTypeEnum getType() { 115 | return type; 116 | } 117 | 118 | public void setType(JavaCG2FieldRelationshipTypeEnum type) { 119 | this.type = type; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/frame/FieldInformationMap.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.frame; 2 | 3 | import com.adrninistrator.javacg2.dto.element.variable.FieldElement; 4 | import com.adrninistrator.javacg2.util.JavaCG2ClassMethodUtil; 5 | import com.adrninistrator.javacg2.util.JavaCG2ElementUtil; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | import java.util.Set; 10 | 11 | /** 12 | * @author adrninistrator 13 | * @date 2022/10/31 14 | * @description: 字段信息Map 15 | */ 16 | public class FieldInformationMap { 17 | 18 | /* 19 | key 20 | 字段名称 21 | value 22 | 字段信息 23 | */ 24 | private Map map; 25 | 26 | public FieldInformationMap() { 27 | map = new HashMap<>(); 28 | } 29 | 30 | public void put(String fieldName, FieldElement fieldElement) { 31 | map.put(fieldName, fieldElement); 32 | } 33 | 34 | public void putStatic(String className, String fieldName, FieldElement fieldElement) { 35 | map.put(getStaticKey(className, fieldName), fieldElement); 36 | } 37 | 38 | public FieldElement get(String fieldName) { 39 | return map.get(fieldName); 40 | } 41 | 42 | public FieldElement getStatic(String className, String fieldName) { 43 | return map.get(getStaticKey(className, fieldName)); 44 | } 45 | 46 | private String getStaticKey(String className, String fieldName) { 47 | return JavaCG2ClassMethodUtil.formatClassAndField(className, fieldName); 48 | } 49 | 50 | public FieldInformationMap copy() { 51 | FieldInformationMap fieldInformationMapCopy = new FieldInformationMap(); 52 | fieldInformationMapCopy.map = new HashMap<>(this.map.size()); 53 | for (Map.Entry entry : this.map.entrySet()) { 54 | fieldInformationMapCopy.map.put(entry.getKey(), (FieldElement) entry.getValue().copyElement()); 55 | } 56 | return fieldInformationMapCopy; 57 | } 58 | 59 | public int size() { 60 | return map.size(); 61 | } 62 | 63 | /** 64 | * 比较本地变量,宽松模式 65 | * 66 | * @param existed 67 | * @param added 68 | * @param sameFieldInfoNameSet 69 | */ 70 | public static void compareLooseMode(FieldInformationMap existed, FieldInformationMap added, Set sameFieldInfoNameSet) { 71 | for (Map.Entry entry : added.map.entrySet()) { 72 | String addedFieldName = entry.getKey(); 73 | FieldElement addedFieldElement = entry.getValue(); 74 | FieldElement existedFieldElement = existed.get(addedFieldName); 75 | 76 | if (existedFieldElement != null && JavaCG2ElementUtil.compare(existedFieldElement, addedFieldElement)) { 77 | sameFieldInfoNameSet.add(addedFieldName); 78 | } 79 | } 80 | } 81 | 82 | @Override 83 | public String toString() { 84 | return "num: " + map.size(); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/frame/FrameSnapshotEntry.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.frame; 2 | 3 | import com.adrninistrator.javacg2.exceptions.JavaCG2RuntimeException; 4 | 5 | /** 6 | * @author adrninistrator 7 | * @date 2022/10/21 8 | * @description: 栈桢对应的信息快照 9 | */ 10 | public class FrameSnapshotEntry { 11 | 12 | // 操作数栈 13 | private final JavaCG2OperandStack stackSnapshot; 14 | 15 | // 本地变量 16 | private final JavaCG2LocalVariables localsSnapshot; 17 | 18 | // 非静态变量 19 | private final FieldInformationMap nonStaticFieldInfoMap; 20 | 21 | // 静态变量 22 | private final FieldInformationMap staticFieldInfoMap; 23 | 24 | public FrameSnapshotEntry(JavaCG2OperandStack stackSnapshot, 25 | JavaCG2LocalVariables localsSnapshot, 26 | FieldInformationMap nonStaticFieldInfoMap, 27 | FieldInformationMap staticFieldInfoMap) { 28 | if (stackSnapshot == null || localsSnapshot == null || nonStaticFieldInfoMap == null || staticFieldInfoMap == null) { 29 | throw new JavaCG2RuntimeException("传入参数为空"); 30 | } 31 | 32 | this.stackSnapshot = stackSnapshot; 33 | this.localsSnapshot = localsSnapshot; 34 | this.nonStaticFieldInfoMap = nonStaticFieldInfoMap; 35 | this.staticFieldInfoMap = staticFieldInfoMap; 36 | } 37 | 38 | public JavaCG2OperandStack getStackSnapshot() { 39 | return stackSnapshot; 40 | } 41 | 42 | public JavaCG2LocalVariables getLocalsSnapshot() { 43 | return localsSnapshot; 44 | } 45 | 46 | public FieldInformationMap getNonStaticFieldInfoMap() { 47 | return nonStaticFieldInfoMap; 48 | } 49 | 50 | public FieldInformationMap getStaticFieldInfoMap() { 51 | return staticFieldInfoMap; 52 | } 53 | 54 | public JavaCG2OperandStack copyStackSnapshot() { 55 | return stackSnapshot.copy(); 56 | } 57 | 58 | public JavaCG2LocalVariables copyLocalsSnapshot() { 59 | return localsSnapshot.copy(); 60 | } 61 | 62 | public FieldInformationMap copyNonStaticFieldInfo() { 63 | return nonStaticFieldInfoMap.copy(); 64 | } 65 | 66 | public FieldInformationMap copyStaticFieldInfo() { 67 | return staticFieldInfoMap.copy(); 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | return "localsHash " + localsSnapshot.genHash() + 73 | " stackSnapshot.size() " + stackSnapshot.size() + 74 | " localsSnapshot.size() " + localsSnapshot.size() + 75 | " nonStaticFieldInfo.size() " + nonStaticFieldInfoMap.size() + 76 | " staticFieldInfo.size() " + staticFieldInfoMap.size(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/frame/InstructionStepList.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.frame; 2 | 3 | import com.adrninistrator.javacg2.common.JavaCG2Constants; 4 | import com.adrninistrator.javacg2.util.JavaCG2InstructionUtil; 5 | import org.apache.bcel.generic.InstructionHandle; 6 | import org.apache.commons.codec.digest.DigestUtils; 7 | import org.apache.commons.lang3.StringUtils; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | /** 13 | * @author adrninistrator 14 | * @date 2022/10/28 15 | * @description: 指令执行的步骤列表 16 | */ 17 | public class InstructionStepList { 18 | 19 | // 指令偏移量列表 20 | private List positionList = new ArrayList<>(); 21 | 22 | // 用于打印的指令信息列表 23 | private List instructionPrintInfoList = new ArrayList<>(); 24 | 25 | /** 26 | * 记录指令执行的步骤 27 | * 28 | * @param ih 指令对象 29 | * @param lineNumber 代码行号 30 | */ 31 | public void add(InstructionHandle ih, int lineNumber) { 32 | String instructionInfo4Print = JavaCG2InstructionUtil.getInstructionHandlePrintInfo(ih) + " (" + lineNumber + ")"; 33 | positionList.add(ih.getPosition()); 34 | instructionPrintInfoList.add(instructionInfo4Print); 35 | } 36 | 37 | public void clear() { 38 | positionList.clear(); 39 | instructionPrintInfoList.clear(); 40 | } 41 | 42 | public InstructionStepList copy() { 43 | InstructionStepList instructionStepCopy = new InstructionStepList(); 44 | instructionStepCopy.positionList = new ArrayList<>(this.positionList); 45 | instructionStepCopy.instructionPrintInfoList = new ArrayList<>(this.instructionPrintInfoList); 46 | return instructionStepCopy; 47 | } 48 | 49 | /** 50 | * 生成当前指令执行步骤的HASH 51 | * 52 | * @return 53 | */ 54 | public String genInstructionStepHash() { 55 | String instructionPositionStr = StringUtils.join(positionList, " "); 56 | return DigestUtils.md5Hex(instructionPositionStr); 57 | } 58 | 59 | @Override 60 | public String toString() { 61 | StringBuilder stringBuilder = new StringBuilder(); 62 | for (String instructionPrintInfo : instructionPrintInfoList) { 63 | stringBuilder.append(instructionPrintInfo).append(JavaCG2Constants.NEW_LINE); 64 | } 65 | return stringBuilder.toString(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/inputoutput/JavaCG2InputAndOutput.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.inputoutput; 2 | 3 | import com.adrninistrator.javacg2.conf.JavaCG2ConfInfo; 4 | import com.adrninistrator.javacg2.conf.JavaCG2ConfigureWrapper; 5 | import com.adrninistrator.javacg2.dto.output.JavaCG2OtherRunResult; 6 | import com.adrninistrator.javacg2.dto.output.JavaCG2OutputInfo; 7 | import com.adrninistrator.javacg2.el.manager.JavaCG2ElManager; 8 | 9 | /** 10 | * @author adrninistrator 11 | * @date 2025/2/2 12 | * @description: 保存需要传递的输入与输出数据 13 | */ 14 | public class JavaCG2InputAndOutput { 15 | 16 | private JavaCG2ConfInfo javaCG2ConfInfo; 17 | 18 | private JavaCG2ConfigureWrapper javaCG2ConfigureWrapper; 19 | 20 | private JavaCG2ElManager javaCG2ElManager; 21 | 22 | private JavaCG2OutputInfo javaCG2OutputInfo; 23 | 24 | private JavaCG2OtherRunResult javaCG2OtherRunResult; 25 | 26 | public JavaCG2ConfInfo getJavaCG2ConfInfo() { 27 | return javaCG2ConfInfo; 28 | } 29 | 30 | public void setJavaCG2ConfInfo(JavaCG2ConfInfo javaCG2ConfInfo) { 31 | this.javaCG2ConfInfo = javaCG2ConfInfo; 32 | } 33 | 34 | public JavaCG2ConfigureWrapper getJavaCG2ConfigureWrapper() { 35 | return javaCG2ConfigureWrapper; 36 | } 37 | 38 | public void setJavaCG2ConfigureWrapper(JavaCG2ConfigureWrapper javaCG2ConfigureWrapper) { 39 | this.javaCG2ConfigureWrapper = javaCG2ConfigureWrapper; 40 | } 41 | 42 | public JavaCG2ElManager getJavaCG2ElManager() { 43 | return javaCG2ElManager; 44 | } 45 | 46 | public void setJavaCG2ElManager(JavaCG2ElManager javaCG2ElManager) { 47 | this.javaCG2ElManager = javaCG2ElManager; 48 | } 49 | 50 | public JavaCG2OutputInfo getJavaCG2OutputInfo() { 51 | return javaCG2OutputInfo; 52 | } 53 | 54 | public void setJavaCG2OutputInfo(JavaCG2OutputInfo javaCG2OutputInfo) { 55 | this.javaCG2OutputInfo = javaCG2OutputInfo; 56 | } 57 | 58 | public JavaCG2OtherRunResult getJavaCG2OtherRunResult() { 59 | return javaCG2OtherRunResult; 60 | } 61 | 62 | public void setJavaCG2OtherRunResult(JavaCG2OtherRunResult javaCG2OtherRunResult) { 63 | this.javaCG2OtherRunResult = javaCG2OtherRunResult; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/instruction/InvokeInstructionPosAndCallee.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.instruction; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2023/8/4 6 | * @description: 方法调用指令位置及被调用方法 7 | */ 8 | public class InvokeInstructionPosAndCallee { 9 | 10 | // 方法调用序号 11 | private final int invokeInstructionPosition; 12 | 13 | // 被调用者类名 14 | private final String calleeClassName; 15 | 16 | // 被调用者方法名 17 | private final String calleeMethodName; 18 | 19 | public InvokeInstructionPosAndCallee(int invokeInstructionPosition, String calleeClassName, String calleeMethodName) { 20 | this.invokeInstructionPosition = invokeInstructionPosition; 21 | this.calleeClassName = calleeClassName; 22 | this.calleeMethodName = calleeMethodName; 23 | } 24 | 25 | public int getInvokeInstructionPosition() { 26 | return invokeInstructionPosition; 27 | } 28 | 29 | public String getCalleeClassName() { 30 | return calleeClassName; 31 | } 32 | 33 | public String getCalleeMethodName() { 34 | return calleeMethodName; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/instruction/parseresult/AThrowNullParseResult.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.instruction.parseresult; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2024/1/15 6 | * @description: ATHROW指令解析结果,抛出异常为null(throw null是合法的写法) 7 | */ 8 | public class AThrowNullParseResult extends AThrowParseResult { 9 | 10 | public AThrowNullParseResult() { 11 | super(null); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/instruction/parseresult/AThrowParseResult.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.instruction.parseresult; 2 | 3 | import com.adrninistrator.javacg2.dto.element.variable.VariableElement; 4 | 5 | /** 6 | * @author adrninistrator 7 | * @date 2024/1/2 8 | * @description: ATHROW指令解析结果 9 | */ 10 | public class AThrowParseResult extends BaseInstructionParseResult { 11 | 12 | // 抛出的异常 13 | private final VariableElement throwElement; 14 | 15 | public AThrowParseResult(VariableElement throwElement) { 16 | this.throwElement = throwElement; 17 | } 18 | 19 | public VariableElement getThrowElement() { 20 | return throwElement; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/instruction/parseresult/BaseInstructionParseResult.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.instruction.parseresult; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2022/10/5 6 | * @description: 指令解析结果基类 7 | */ 8 | public abstract class BaseInstructionParseResult { 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/instruction/parseresult/MethodCallParseResult.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.instruction.parseresult; 2 | 3 | import com.adrninistrator.javacg2.dto.element.BaseElement; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @author adrninistrator 9 | * @date 2022/5/22 10 | * @description: 方法调用指令解析结果 11 | */ 12 | public class MethodCallParseResult extends BaseInstructionParseResult { 13 | 14 | // 方法调用对应的被调用对象 15 | private final BaseElement objectElement; 16 | 17 | // 方法调用对应的参数 18 | private final List argumentList; 19 | 20 | public MethodCallParseResult(BaseElement objectElement, List argumentList) { 21 | this.objectElement = objectElement; 22 | this.argumentList = argumentList; 23 | } 24 | 25 | public BaseElement getObjectElement() { 26 | return objectElement; 27 | } 28 | 29 | public List getArgumentList() { 30 | return argumentList; 31 | } 32 | 33 | @Override 34 | public String toString() { 35 | return "MethodCallObjRefAndArgs{" + 36 | "objectReference=" + objectElement + 37 | ", argumentList=" + argumentList + 38 | '}'; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/instruction/parseresult/PutFieldParseResult.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.instruction.parseresult; 2 | 3 | import com.adrninistrator.javacg2.dto.element.BaseElement; 4 | 5 | /** 6 | * @author adrninistrator 7 | * @date 2023/7/16 8 | * @description: PUTFIELD指令解析结果 9 | */ 10 | public class PutFieldParseResult extends BaseInstructionParseResult { 11 | 12 | // 字段名称 13 | private final String fieldName; 14 | 15 | // 字段类型 16 | private final String fieldType; 17 | 18 | // 对应的值 19 | private final BaseElement value; 20 | 21 | // 对应的对象 22 | private final BaseElement object; 23 | 24 | public PutFieldParseResult(String fieldName, String fieldType, BaseElement value, BaseElement object) { 25 | this.fieldName = fieldName; 26 | this.fieldType = fieldType; 27 | this.value = value; 28 | this.object = object; 29 | } 30 | 31 | public String getFieldName() { 32 | return fieldName; 33 | } 34 | 35 | public String getFieldType() { 36 | return fieldType; 37 | } 38 | 39 | public BaseElement getValue() { 40 | return value; 41 | } 42 | 43 | public BaseElement getObject() { 44 | return object; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/instruction/parseresult/PutStaticParseResult.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.instruction.parseresult; 2 | 3 | import com.adrninistrator.javacg2.dto.element.BaseElement; 4 | 5 | /** 6 | * @author adrninistrator 7 | * @date 2023/8/3 8 | * @description: PUTSTATIC指令解析结果 9 | */ 10 | public class PutStaticParseResult extends BaseInstructionParseResult { 11 | 12 | // 类名 13 | private final String className; 14 | 15 | // 字段名称 16 | private final String fieldName; 17 | 18 | // 字段类型 19 | private final String fieldType; 20 | 21 | // 对应的值 22 | private final BaseElement value; 23 | 24 | public PutStaticParseResult(String className, String fieldName, String fieldType, BaseElement value) { 25 | this.className = className; 26 | this.fieldName = fieldName; 27 | this.fieldType = fieldType; 28 | this.value = value; 29 | } 30 | 31 | public String getClassName() { 32 | return className; 33 | } 34 | 35 | public String getFieldName() { 36 | return fieldName; 37 | } 38 | 39 | public String getFieldType() { 40 | return fieldType; 41 | } 42 | 43 | public BaseElement getValue() { 44 | return value; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/instruction/parseresult/RetParseResult.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.instruction.parseresult; 2 | 3 | import org.apache.bcel.generic.InstructionHandle; 4 | 5 | /** 6 | * @author adrninistrator 7 | * @date 2022/10/29 8 | * @description: RET指令的解析结果 9 | */ 10 | public class RetParseResult extends BaseInstructionParseResult { 11 | 12 | // 对应的jsr指令的下一条指令 13 | private final InstructionHandle jsrNextIh; 14 | 15 | public RetParseResult(InstructionHandle jsrNextIh) { 16 | this.jsrNextIh = jsrNextIh; 17 | } 18 | 19 | public InstructionHandle getJsrNextIh() { 20 | return jsrNextIh; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/instruction/parseresult/ReturnParseResult.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.instruction.parseresult; 2 | 3 | import com.adrninistrator.javacg2.dto.element.BaseElement; 4 | 5 | /** 6 | * @author adrninistrator 7 | * @date 2022/11/4 8 | * @description: RETURN类指令的解析结果 9 | */ 10 | public class ReturnParseResult extends BaseInstructionParseResult { 11 | 12 | // 返回元素 13 | private final BaseElement returnElement; 14 | 15 | public ReturnParseResult(BaseElement returnElement) { 16 | this.returnElement = returnElement; 17 | } 18 | 19 | public BaseElement getReturnElement() { 20 | return returnElement; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/jar/ClassAndJarNum.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.jar; 2 | 3 | import com.adrninistrator.javacg2.common.JavaCG2Constants; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | /** 9 | * @author adrninistrator 10 | * @date 2023/4/18 11 | * @description: 类名及对应的Jar包序号 12 | */ 13 | public class ClassAndJarNum { 14 | 15 | private final Map classAndJarNumMap = new HashMap<>(JavaCG2Constants.SIZE_100); 16 | 17 | /** 18 | * 根据类名获取对应的Jar包序号,若不存在则返回代表为空的Jar包序号 19 | * 20 | * @param className 21 | * @return 22 | */ 23 | public String getJarNum(String className) { 24 | Integer classJarNum = classAndJarNumMap.get(className); 25 | return classJarNum == null ? JavaCG2Constants.EMPTY_JAR_NUM : String.valueOf(classJarNum); 26 | } 27 | 28 | /** 29 | * 记录类名及对应的Jar包序号 30 | * 31 | * @param className 32 | * @param jarNum 33 | */ 34 | public void put(String className, Integer jarNum) { 35 | // 只记录每个类所出现的最靠前的Jar包序号,不覆盖现有值 36 | classAndJarNumMap.putIfAbsent(className, jarNum); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/jar/OuterInnerJarPath.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.jar; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2025/1/27 6 | * @description: jar/war文件及其中的jar文件 7 | */ 8 | public class OuterInnerJarPath { 9 | 10 | // 外层jar/war文件路径 11 | private String outerJarPath; 12 | 13 | // 内层jar文件路径 14 | private String innerJarPath; 15 | 16 | public String getOuterJarPath() { 17 | return outerJarPath; 18 | } 19 | 20 | public void setOuterJarPath(String outerJarPath) { 21 | this.outerJarPath = outerJarPath; 22 | } 23 | 24 | public String getInnerJarPath() { 25 | return innerJarPath; 26 | } 27 | 28 | public void setInnerJarPath(String innerJarPath) { 29 | this.innerJarPath = innerJarPath; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/method/JavaCG2MethodInfo.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.method; 2 | 3 | import org.apache.bcel.generic.Type; 4 | 5 | /** 6 | * @author adrninistrator 7 | * @date 2021/8/22 8 | * @description: 方法信息 9 | */ 10 | public class JavaCG2MethodInfo { 11 | // 类名 12 | private final String className; 13 | 14 | // 方法名 15 | private final String methodName; 16 | 17 | // 方法参数类型 18 | private final Type[] methodArgumentTypes; 19 | 20 | // 方法返回类型 21 | private final Type methodReturnType; 22 | 23 | // 类的数组维,0代表非数组 24 | private final int arrayDimensions; 25 | 26 | public JavaCG2MethodInfo(String className, String methodName, Type[] methodArgumentTypes, Type methodReturnType, int arrayDimensions) { 27 | this.className = className; 28 | this.methodName = methodName; 29 | this.methodArgumentTypes = methodArgumentTypes; 30 | this.methodReturnType = methodReturnType; 31 | this.arrayDimensions = arrayDimensions; 32 | } 33 | 34 | public JavaCG2MethodInfo(String className, String methodName, Type[] methodArgumentTypes, Type methodReturnType) { 35 | this.className = className; 36 | this.methodName = methodName; 37 | this.methodArgumentTypes = methodArgumentTypes; 38 | this.methodReturnType = methodReturnType; 39 | this.arrayDimensions = 0; 40 | } 41 | 42 | public String getClassName() { 43 | return className; 44 | } 45 | 46 | public String getMethodName() { 47 | return methodName; 48 | } 49 | 50 | public Type[] getMethodArgumentTypes() { 51 | return methodArgumentTypes; 52 | } 53 | 54 | public Type getMethodReturnType() { 55 | return methodReturnType; 56 | } 57 | 58 | public int getArrayDimensions() { 59 | return arrayDimensions; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/method/MethodArgReturnTypes.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.method; 2 | 3 | import com.adrninistrator.javacg2.util.JavaCG2ClassMethodUtil; 4 | import org.apache.bcel.generic.Type; 5 | 6 | import java.util.Objects; 7 | 8 | /** 9 | * @author adrninistrator 10 | * @date 2022/10/1 11 | * @description: 方法名称、方法参数与返回类型 12 | */ 13 | public class MethodArgReturnTypes { 14 | // 方法名称 15 | private final String methodName; 16 | 17 | // 方法参数类型字符串 18 | private final String methodArgTypes; 19 | 20 | // 方法返回类型 21 | private final String methodReturnType; 22 | 23 | public MethodArgReturnTypes(String methodName, Type[] argTypes, Type returnType) { 24 | this.methodName = methodName; 25 | this.methodArgTypes = JavaCG2ClassMethodUtil.getArgTypeStr(argTypes); 26 | this.methodReturnType = returnType.toString(); 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "MethodArgReturnTypes{" + 32 | "methodName='" + methodName + '\'' + 33 | ", methodArgTypes='" + methodArgTypes + '\'' + 34 | ", methodReturnType='" + methodReturnType + '\'' + 35 | '}'; 36 | } 37 | 38 | @Override 39 | public boolean equals(Object o) { 40 | if (this == o) return true; 41 | if (o == null || getClass() != o.getClass()) return false; 42 | MethodArgReturnTypes that = (MethodArgReturnTypes) o; 43 | return methodName.equals(that.methodName) && methodArgTypes.equals(that.methodArgTypes) && methodReturnType.equals(that.methodReturnType); 44 | } 45 | 46 | @Override 47 | public int hashCode() { 48 | return Objects.hash(methodName, methodArgTypes, methodReturnType); 49 | } 50 | 51 | public String getMethodName() { 52 | return methodName; 53 | } 54 | 55 | public String getMethodArgTypes() { 56 | return methodArgTypes; 57 | } 58 | 59 | public String getMethodReturnType() { 60 | return methodReturnType; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/methodcode/MethodCodeInstruction.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.methodcode; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2025/3/18 6 | * @description: 方法代码指令 7 | */ 8 | public class MethodCodeInstruction { 9 | 10 | // 指令偏移量 11 | private int offset; 12 | 13 | // 指令名称 14 | private String instructionName; 15 | 16 | public int getOffset() { 17 | return offset; 18 | } 19 | 20 | public void setOffset(int offset) { 21 | this.offset = offset; 22 | } 23 | 24 | public String getInstructionName() { 25 | return instructionName; 26 | } 27 | 28 | public void setInstructionName(String instructionName) { 29 | this.instructionName = instructionName; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/methodcode/MethodCodeInstructionArg.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.methodcode; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2025/3/21 6 | * @description: 方法代码指令,包含一个参数 7 | */ 8 | public class MethodCodeInstructionArg extends MethodCodeInstruction { 9 | 10 | // 参数 11 | private String arg; 12 | 13 | public String getArg() { 14 | return arg; 15 | } 16 | 17 | public void setArg(String arg) { 18 | this.arg = arg; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/methodcode/MethodCodeInstructionJump.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.methodcode; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2025/3/21 6 | * @description: 方法代码指令,跳转 7 | */ 8 | public class MethodCodeInstructionJump extends MethodCodeInstruction { 9 | 10 | // 跳转目标指令偏移量 11 | private int targetOffset; 12 | 13 | public int getTargetOffset() { 14 | return targetOffset; 15 | } 16 | 17 | public void setTargetOffset(int targetOffset) { 18 | this.targetOffset = targetOffset; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/methodcode/MethodCodeInstructionLookupSwitch.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.methodcode; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * @author adrninistrator 7 | * @date 2025/3/20 8 | * @description: 方法代码指令,lookupswitch 9 | */ 10 | public class MethodCodeInstructionLookupSwitch extends MethodCodeInstruction { 11 | 12 | // 默认跳转目标指令偏移量 13 | private int defaultTargetOffset; 14 | 15 | // 键值对数量 16 | private int pairsNum; 17 | 18 | // 跳转目标列表 19 | private List jumpList; 20 | 21 | public int getDefaultTargetOffset() { 22 | return defaultTargetOffset; 23 | } 24 | 25 | public void setDefaultTargetOffset(int defaultTargetOffset) { 26 | this.defaultTargetOffset = defaultTargetOffset; 27 | } 28 | 29 | public int getPairsNum() { 30 | return pairsNum; 31 | } 32 | 33 | public void setPairsNum(int pairsNum) { 34 | this.pairsNum = pairsNum; 35 | } 36 | 37 | public List getJumpList() { 38 | return jumpList; 39 | } 40 | 41 | public void setJumpList(List jumpList) { 42 | this.jumpList = jumpList; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/methodcode/MethodCodeInstructionLookupSwitchJump.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.methodcode; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2025/3/21 6 | * @description: lookupswitch指令中的数据 7 | */ 8 | public class MethodCodeInstructionLookupSwitchJump { 9 | 10 | // 索引 11 | private int index; 12 | 13 | // 跳转目标指令偏移量 14 | private int targetOffset; 15 | 16 | public int getIndex() { 17 | return index; 18 | } 19 | 20 | public void setIndex(int index) { 21 | this.index = index; 22 | } 23 | 24 | public int getTargetOffset() { 25 | return targetOffset; 26 | } 27 | 28 | public void setTargetOffset(int targetOffset) { 29 | this.targetOffset = targetOffset; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/methodcode/MethodCodeInstructionTableSwitch.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.methodcode; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * @author adrninistrator 7 | * @date 2025/3/21 8 | * @description: 方法代码指令,tableswitch 9 | */ 10 | public class MethodCodeInstructionTableSwitch extends MethodCodeInstruction { 11 | 12 | // 默认跳转目标指令偏移量 13 | private int defaultTargetOffset; 14 | 15 | // case最小值 16 | private int low; 17 | 18 | // case最大值 19 | private int high; 20 | 21 | // 跳转目标列表 22 | private List jumpTargetOffsetList; 23 | 24 | public int getDefaultTargetOffset() { 25 | return defaultTargetOffset; 26 | } 27 | 28 | public void setDefaultTargetOffset(int defaultTargetOffset) { 29 | this.defaultTargetOffset = defaultTargetOffset; 30 | } 31 | 32 | public int getLow() { 33 | return low; 34 | } 35 | 36 | public void setLow(int low) { 37 | this.low = low; 38 | } 39 | 40 | public int getHigh() { 41 | return high; 42 | } 43 | 44 | public void setHigh(int high) { 45 | this.high = high; 46 | } 47 | 48 | public List getJumpTargetOffsetList() { 49 | return jumpTargetOffsetList; 50 | } 51 | 52 | public void setJumpTargetOffsetList(List jumpTargetOffsetList) { 53 | this.jumpTargetOffsetList = jumpTargetOffsetList; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/output/JavaCG2OtherRunResult.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.output; 2 | 3 | import java.util.Collections; 4 | import java.util.HashSet; 5 | import java.util.Set; 6 | 7 | /** 8 | * @author adrninistrator 9 | * @date 2024/11/4 10 | * @description: 其他执行结果 11 | */ 12 | public class JavaCG2OtherRunResult { 13 | 14 | // 栈桢信息快照数量超过允许的最大数量的方法Set 15 | private final Set frameSnapshotNumExceedMethodSet = new HashSet<>(); 16 | 17 | public void addFrameSnapshotNumExceedMethod(String frameSnapshotNumExceedMethod) { 18 | frameSnapshotNumExceedMethodSet.add(frameSnapshotNumExceedMethod); 19 | } 20 | 21 | public void addFrameSnapshotNumExceedMethodSet(Set frameSnapshotNumExceedMethodSet) { 22 | this.frameSnapshotNumExceedMethodSet.addAll(frameSnapshotNumExceedMethodSet); 23 | } 24 | 25 | public Set getFrameSnapshotNumExceedMethodSetReadOnly() { 26 | return Collections.unmodifiableSet(frameSnapshotNumExceedMethodSet); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/output/JavaCG2OutputInfo.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.output; 2 | 3 | import com.adrninistrator.javacg2.common.enums.JavaCG2OutPutFileTypeEnum; 4 | import com.adrninistrator.javacg2.util.JavaCG2Util; 5 | 6 | import java.util.Collections; 7 | import java.util.HashMap; 8 | import java.util.HashSet; 9 | import java.util.Map; 10 | import java.util.Set; 11 | 12 | /** 13 | * @author adrninistrator 14 | * @date 2022/11/5 15 | * @description: java-callgraph2处理结果信息 16 | */ 17 | public class JavaCG2OutputInfo { 18 | 19 | // 保存当前的输出目录路径 20 | private final String outputDirPath; 21 | 22 | // 保存输出文件后缀名 23 | private final String outputFileExt; 24 | 25 | /* 26 | 保存其他文件的信息 27 | key 28 | 文件名,不需要指定文件后缀 29 | value 30 | 文件路径 31 | */ 32 | private final Map otherFilePathMap = new HashMap<>(); 33 | 34 | // 栈桢信息快照数量超过允许的最大数量的方法Set 35 | private final Set frameSnapshotNumExceedMethodSet = new HashSet<>(); 36 | 37 | public JavaCG2OutputInfo(String outputDirPath, String outputFileExt) { 38 | // 路径后面增加路径分隔符 39 | this.outputDirPath = JavaCG2Util.addSeparator4FilePath(outputDirPath); 40 | this.outputFileExt = outputFileExt; 41 | } 42 | 43 | /** 44 | * 增加其他文件信息,返回对应的文件路径 45 | * 46 | * @param fileName 文件名,不需要指定文件后缀 47 | * @return 文件路径 48 | */ 49 | public String addOtherFileInfo(String fileName) { 50 | String filePath = outputDirPath + fileName + outputFileExt; 51 | otherFilePathMap.put(fileName, filePath); 52 | return filePath; 53 | } 54 | 55 | /** 56 | * 获取其他文件路径 57 | * 58 | * @param fileName 59 | * @return 60 | */ 61 | public String getOtherFilePath(String fileName) { 62 | return otherFilePathMap.get(fileName); 63 | } 64 | 65 | /** 66 | * 获取其他文件名集合 67 | * 68 | * @return 69 | */ 70 | public Set getOtherFileNameSet() { 71 | return otherFilePathMap.keySet(); 72 | } 73 | 74 | /** 75 | * 获取当前生成文件的目录 76 | * 77 | * @return 78 | */ 79 | public String getOutputDirPath() { 80 | return outputDirPath; 81 | } 82 | 83 | /** 84 | * 获取指定类型的生成文件的路径 85 | * 86 | * @param javaCG2OutPutFileTypeEnum 87 | * @return 88 | */ 89 | public String getMainFilePath(JavaCG2OutPutFileTypeEnum javaCG2OutPutFileTypeEnum) { 90 | return outputDirPath + javaCG2OutPutFileTypeEnum.getFileName() + outputFileExt; 91 | } 92 | 93 | public void addFrameSnapshotNumExceedMethod(String frameSnapshotNumExceedMethod) { 94 | frameSnapshotNumExceedMethodSet.add(frameSnapshotNumExceedMethod); 95 | } 96 | 97 | public void addFrameSnapshotNumExceedMethodSet(Set frameSnapshotNumExceedMethodSet) { 98 | this.frameSnapshotNumExceedMethodSet.addAll(frameSnapshotNumExceedMethodSet); 99 | } 100 | 101 | public Set getFrameSnapshotNumExceedMethodSetReadOnly() { 102 | return Collections.unmodifiableSet(frameSnapshotNumExceedMethodSet); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/stack/ListAsStack.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.stack; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2022/12/1 9 | * @description: 当作栈使用的List 10 | */ 11 | public class ListAsStack { 12 | // 栈的当前位置,初始值-1 13 | private int head = -1; 14 | 15 | private final List list = new ArrayList<>(); 16 | 17 | /** 18 | * 出棧 19 | * 20 | * @return 21 | */ 22 | public E pop() { 23 | E element = list.get(head); 24 | head--; 25 | return element; 26 | } 27 | 28 | /** 29 | * 删除栈顶元素 30 | */ 31 | public void removeTop() { 32 | head--; 33 | } 34 | 35 | /** 36 | * 獲取棧頂元素 37 | * 38 | * @return 39 | */ 40 | public E peek() { 41 | return list.get(head); 42 | } 43 | 44 | /** 45 | * 入棧 46 | * 47 | * @param element 48 | */ 49 | public void push(E element) { 50 | head++; 51 | if (head >= list.size()) { 52 | // head对应的记录不存在,则添加 53 | list.add(element); 54 | } else { 55 | // head对应的记录已存在,则设置 56 | list.set(head, element); 57 | } 58 | } 59 | 60 | /** 61 | * 获取指定序号的元素 62 | * 63 | * @param index 64 | * @return 65 | */ 66 | public E getElementAt(int index) { 67 | return list.get(index); 68 | } 69 | 70 | /** 71 | * 判断栈是否为空 72 | * 73 | * @return 74 | */ 75 | public boolean isEmpty() { 76 | return head < 0; 77 | } 78 | 79 | /** 80 | * 判断栈是否处在最下面的位置(有一个元素) 81 | * 82 | * @return 83 | */ 84 | public boolean atBottom() { 85 | return head == 0; 86 | } 87 | 88 | /** 89 | * 获取头的位置 90 | * 91 | * @return 92 | */ 93 | public int getHead() { 94 | return head; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/type/JavaCG2GenericsType.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.type; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2024/10/24 6 | * @description: 泛型相关的类型信息 7 | */ 8 | public class JavaCG2GenericsType extends JavaCG2Type { 9 | 10 | // 泛型类型变量名称 11 | private String typeVariablesName; 12 | 13 | // 通配符 14 | private String wildcard; 15 | 16 | // 通配符引用的类型,如extends xxx,super xxx 17 | private String referenceType; 18 | 19 | public String getTypeVariablesName() { 20 | return typeVariablesName; 21 | } 22 | 23 | public void setTypeVariablesName(String typeVariablesName) { 24 | this.typeVariablesName = typeVariablesName; 25 | } 26 | 27 | public String getWildcard() { 28 | return wildcard; 29 | } 30 | 31 | public void setWildcard(String wildcard) { 32 | this.wildcard = wildcard; 33 | } 34 | 35 | public String getReferenceType() { 36 | return referenceType; 37 | } 38 | 39 | public void setReferenceType(String referenceType) { 40 | this.referenceType = referenceType; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "JavaCG2GenericsType{" + 46 | "typeVariablesName='" + typeVariablesName + '\'' + 47 | ", wildcard='" + wildcard + '\'' + 48 | ", referenceType='" + referenceType + '\'' + 49 | ", type='" + type + '\'' + 50 | ", arrayDimensions=" + arrayDimensions + 51 | '}'; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/type/JavaCG2Type.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.type; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2024/11/14 6 | * @description: 包含数组维度的类型 7 | */ 8 | public class JavaCG2Type { 9 | 10 | // 类型 11 | protected String type; 12 | 13 | // 属于数组类型时的数组维度,0代表不是数组 14 | protected int arrayDimensions; 15 | 16 | public String getType() { 17 | return type; 18 | } 19 | 20 | public void setType(String type) { 21 | this.type = type; 22 | } 23 | 24 | public int getArrayDimensions() { 25 | return arrayDimensions; 26 | } 27 | 28 | public void setArrayDimensions(int arrayDimensions) { 29 | this.arrayDimensions = arrayDimensions; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/variabledatasource/AbstractVariableDataSource.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.variabledatasource; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2023/6/12 6 | * @description: 变量的数据来源,基类 7 | */ 8 | public abstract class AbstractVariableDataSource { 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/variabledatasource/VariableDataSourceArithmeticOperation.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.variabledatasource; 2 | 3 | import com.adrninistrator.javacg2.common.enums.JavaCG2ArithmeticOperationTypeEnum; 4 | import com.adrninistrator.javacg2.dto.element.BaseElement; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2023/8/5 9 | * @description: 变量的数据来源,算术运算 10 | */ 11 | public class VariableDataSourceArithmeticOperation extends AbstractVariableDataSource { 12 | 13 | // 算术运算指令位置 14 | private final int operationInstructionPosition; 15 | 16 | // 算术运算类型 17 | private final JavaCG2ArithmeticOperationTypeEnum arithmeticOperationTypeEnum; 18 | 19 | // 参与运算的第1个元素 20 | private final BaseElement element1; 21 | 22 | // 参与运算的第2个元素 23 | private final BaseElement element2; 24 | 25 | public VariableDataSourceArithmeticOperation(int operationInstructionPosition, JavaCG2ArithmeticOperationTypeEnum arithmeticOperationTypeEnum, BaseElement element1, 26 | BaseElement element2) { 27 | this.operationInstructionPosition = operationInstructionPosition; 28 | this.arithmeticOperationTypeEnum = arithmeticOperationTypeEnum; 29 | this.element1 = element1; 30 | this.element2 = element2; 31 | } 32 | 33 | /** 34 | * 比较与另一个对象是否相同 35 | * 36 | * @param added 37 | * @return false: 不相同 true: 相同 38 | */ 39 | public boolean compare(VariableDataSourceArithmeticOperation added) { 40 | // 每次处理的方法调用在同一个调用方法内,只需要比较方法调用指令位置 41 | return this.operationInstructionPosition == added.operationInstructionPosition; 42 | } 43 | 44 | public int getOperationInstructionPosition() { 45 | return operationInstructionPosition; 46 | } 47 | 48 | public JavaCG2ArithmeticOperationTypeEnum getArithmeticOperationTypeEnum() { 49 | return arithmeticOperationTypeEnum; 50 | } 51 | 52 | public BaseElement getElement1() { 53 | return element1; 54 | } 55 | 56 | public BaseElement getElement2() { 57 | return element2; 58 | } 59 | 60 | @Override 61 | public String toString() { 62 | return "VariableDataSourceArithmeticOperation{" + 63 | "invokeInstructionPosition=" + operationInstructionPosition + 64 | ", arithmeticOperationTypeEnum=" + arithmeticOperationTypeEnum + 65 | ", element1=" + element1 + 66 | ", element2=" + element2 + 67 | '}'; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/variabledatasource/VariableDataSourceField.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.variabledatasource; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2024/6/10 6 | * @description: 变量的数据来源,使用字段 7 | */ 8 | public class VariableDataSourceField extends AbstractVariableDataSource { 9 | 10 | // 类名 11 | private String className; 12 | 13 | // 字段名称 14 | private String fieldName; 15 | 16 | // 字段类型 17 | private String fieldType; 18 | 19 | public String getClassName() { 20 | return className; 21 | } 22 | 23 | public void setClassName(String className) { 24 | this.className = className; 25 | } 26 | 27 | public String getFieldName() { 28 | return fieldName; 29 | } 30 | 31 | public void setFieldName(String fieldName) { 32 | this.fieldName = fieldName; 33 | } 34 | 35 | public String getFieldType() { 36 | return fieldType; 37 | } 38 | 39 | public void setFieldType(String fieldType) { 40 | this.fieldType = fieldType; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/variabledatasource/VariableDataSourceMethodArg.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.variabledatasource; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2023/6/12 6 | * @description: 变量的数据来源,使用方法参数 7 | */ 8 | public class VariableDataSourceMethodArg extends AbstractVariableDataSource { 9 | 10 | // 参数的序号(从1开始) 11 | private final int argSeq; 12 | 13 | // 参数的类型 14 | private final String argType; 15 | 16 | public VariableDataSourceMethodArg(int argSeq, String argType) { 17 | this.argSeq = argSeq; 18 | this.argType = argType; 19 | } 20 | 21 | /** 22 | * 比较与另一个对象是否相同 23 | * 24 | * @param added 25 | * @return false: 不相同 true: 相同 26 | */ 27 | public boolean compare(VariableDataSourceMethodArg added) { 28 | return this.argSeq == added.argSeq && 29 | this.argType.equals(added.argType); 30 | } 31 | 32 | public int getArgSeq() { 33 | return argSeq; 34 | } 35 | 36 | public String getArgType() { 37 | return argType; 38 | } 39 | 40 | @Override 41 | public String toString() { 42 | return "VariableDataSourceMethodArg{" + 43 | "argSeq=" + argSeq + 44 | ", argType='" + argType + '\'' + 45 | '}'; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/dto/variabledatasource/VariableDataSourceMethodCallReturn.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.dto.variabledatasource; 2 | 3 | import com.adrninistrator.javacg2.dto.element.BaseElement; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @author adrninistrator 9 | * @date 2023/6/13 10 | * @description: 变量的数据来源,方法调用返回值 11 | */ 12 | public class VariableDataSourceMethodCallReturn extends AbstractVariableDataSource { 13 | 14 | // 方法调用指令位置 15 | private final int invokeInstructionPosition; 16 | 17 | // 方法调用指令类型的名称(简单类名) 18 | private final String invokeInstructionType; 19 | 20 | // 被调用类名 21 | private final String calleeClassName; 22 | 23 | // 被调用方法名称 24 | private final String calleeMethodName; 25 | 26 | // 被调用方法参数类型字符串(包括括号) 27 | private final String calleeArgTypeStr; 28 | 29 | // 返回类型 30 | private final String returnType; 31 | 32 | // 被调用对象对应的元素,可能为null 33 | private final BaseElement objectElement; 34 | 35 | // 方法调用参数对应的元素列表 36 | private final List argElementList; 37 | 38 | public VariableDataSourceMethodCallReturn(int invokeInstructionPosition, String invokeInstructionType, String calleeClassName, String calleeMethodName, 39 | String calleeArgTypeStr, String returnType, BaseElement objectElement, List argElementList) { 40 | this.invokeInstructionPosition = invokeInstructionPosition; 41 | this.invokeInstructionType = invokeInstructionType; 42 | this.calleeClassName = calleeClassName; 43 | this.calleeMethodName = calleeMethodName; 44 | this.calleeArgTypeStr = calleeArgTypeStr; 45 | this.returnType = returnType; 46 | this.objectElement = objectElement; 47 | this.argElementList = argElementList; 48 | } 49 | 50 | /** 51 | * 比较与另一个对象是否相同 52 | * 53 | * @param added 54 | * @return false: 不相同 true: 相同 55 | */ 56 | public boolean compare(VariableDataSourceMethodCallReturn added) { 57 | // 每次处理的方法调用在同一个调用方法内,只需要比较方法调用指令位置 58 | return this.invokeInstructionPosition == added.invokeInstructionPosition; 59 | } 60 | 61 | // 62 | public int getInvokeInstructionPosition() { 63 | return invokeInstructionPosition; 64 | } 65 | 66 | public String getInvokeInstructionType() { 67 | return invokeInstructionType; 68 | } 69 | 70 | public String getCalleeClassName() { 71 | return calleeClassName; 72 | } 73 | 74 | public String getCalleeMethodName() { 75 | return calleeMethodName; 76 | } 77 | 78 | public String getCalleeArgTypeStr() { 79 | return calleeArgTypeStr; 80 | } 81 | 82 | public String getReturnType() { 83 | return returnType; 84 | } 85 | 86 | public BaseElement getObjectElement() { 87 | return objectElement; 88 | } 89 | 90 | public List getArgElementList() { 91 | return argElementList; 92 | } 93 | 94 | @Override 95 | public String toString() { 96 | return "VariableDataSourceMethodCallReturn{" + 97 | "invokeInstructionType='" + invokeInstructionType + '\'' + 98 | ", calleeClassName='" + calleeClassName + '\'' + 99 | ", calleeMethodName='" + calleeMethodName + '\'' + 100 | ", calleeArgTypeStr='" + calleeArgTypeStr + '\'' + 101 | '}'; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/el/checker/ElChecker.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.el.checker; 2 | 3 | import com.adrninistrator.javacg2.el.enums.interfaces.ElConfigInterface; 4 | import com.adrninistrator.javacg2.el.manager.ElManager; 5 | import com.adrninistrator.javacg2.exceptions.JavaCG2RuntimeException; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | /** 10 | * @author adrninistrator 11 | * @date 2025/2/13 12 | * @description: 表达式检查抽象父类 13 | */ 14 | public abstract class ElChecker { 15 | 16 | private static final Logger logger = LoggerFactory.getLogger(ElChecker.class); 17 | 18 | /** 19 | * 执行检查表达式 20 | * 21 | * @param elManager 22 | * @param elConfig 23 | */ 24 | protected abstract void doCheck(ElManager elManager, ElConfigInterface elConfig); 25 | 26 | /** 27 | * 检查表达式 28 | * 29 | * @param elManager 30 | * @param elConfig 31 | * @return 32 | */ 33 | public void check(ElManager elManager, ElConfigInterface elConfig) { 34 | try { 35 | doCheck(elManager, elConfig); 36 | } catch (Exception e) { 37 | logger.error("执行表达式进行检查时失败,需要修改对应的表达式 {} ", elConfig.getKey(), e); 38 | throw new JavaCG2RuntimeException("执行表达式进行检查时失败,需要修改对应的表达式"); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/el/checker/JavaCG2ElChecker.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.el.checker; 2 | 3 | import com.adrninistrator.javacg2.el.enums.JavaCG2ElConfigEnum; 4 | import com.adrninistrator.javacg2.el.enums.interfaces.ElConfigInterface; 5 | import com.adrninistrator.javacg2.el.manager.ElManager; 6 | import com.adrninistrator.javacg2.el.manager.JavaCG2ElManager; 7 | import com.adrninistrator.javacg2.el.util.ElUtil; 8 | 9 | /** 10 | * @author adrninistrator 11 | * @date 2025/2/13 12 | * @description: 当前项目使用的表达式检查抽象父类 13 | */ 14 | public abstract class JavaCG2ElChecker extends ElChecker { 15 | 16 | @Override 17 | protected void doCheck(ElManager elManager, ElConfigInterface elConfig) { 18 | try { 19 | // 设置执行用于检测的表达式标志 20 | ElUtil.setRunInCheckerFlag(); 21 | javaCG2DoCheck((JavaCG2ElManager) elManager, (JavaCG2ElConfigEnum) elConfig); 22 | } finally { 23 | // 清理执行用于检测的表达式标志 24 | ElUtil.clearRunInCheckerFlag(); 25 | } 26 | } 27 | 28 | /** 29 | * 执行检查表达式 30 | * 31 | * @param elManager 32 | * @param elConfig 33 | */ 34 | protected abstract void javaCG2DoCheck(JavaCG2ElManager elManager, JavaCG2ElConfigEnum elConfig); 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/el/checker/JavaCG2ElChecker4MergeFileInDir.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.el.checker; 2 | 3 | import com.adrninistrator.javacg2.el.enums.JavaCG2ElConfigEnum; 4 | import com.adrninistrator.javacg2.el.manager.JavaCG2ElManager; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2025/2/13 9 | * @description: 10 | */ 11 | public class JavaCG2ElChecker4MergeFileInDir extends JavaCG2ElChecker { 12 | 13 | @Override 14 | protected void javaCG2DoCheck(JavaCG2ElManager elManager, JavaCG2ElConfigEnum elConfig) { 15 | switch(elConfig){ 16 | case ECE_MERGE_FILE_IGNORE_JAR_IN_DIR: 17 | elManager.checkIgnoreMergeFileInDir("/a/b.jar"); 18 | break; 19 | case ECE_MERGE_FILE_IGNORE_WAR_IN_DIR: 20 | elManager.checkIgnoreMergeFileInDir("/a/b.war"); 21 | break; 22 | case ECE_MERGE_FILE_IGNORE_CLASS_IN_DIR: 23 | elManager.checkIgnoreMergeFileInDir("/a/b.class"); 24 | break; 25 | case ECE_MERGE_FILE_IGNORE_OTHER_IN_DIR: 26 | elManager.checkIgnoreMergeFileInDir("/a/b.xml"); 27 | break; 28 | default: 29 | break; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/el/checker/JavaCG2ElChecker4MergeFileInJarWar.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.el.checker; 2 | 3 | import com.adrninistrator.javacg2.el.enums.JavaCG2ElConfigEnum; 4 | import com.adrninistrator.javacg2.el.manager.JavaCG2ElManager; 5 | import com.adrninistrator.javacg2.util.JavaCG2Util; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | import java.util.Set; 10 | 11 | /** 12 | * @author adrninistrator 13 | * @date 2025/2/13 14 | * @description: 15 | */ 16 | public class JavaCG2ElChecker4MergeFileInJarWar extends JavaCG2ElChecker { 17 | 18 | @Override 19 | protected void javaCG2DoCheck(JavaCG2ElManager elManager, JavaCG2ElConfigEnum elConfig) { 20 | switch (elConfig) { 21 | case ECE_MERGE_FILE_IGNORE_JAR_IN_JAR_WAR: 22 | elManager.checkIgnoreMergeFileInJarWar("a/b.jar"); 23 | break; 24 | case ECE_MERGE_FILE_IGNORE_CLASS_IN_JAR_WAR: 25 | elManager.checkIgnoreMergeFileInJarWar("a/b.class"); 26 | break; 27 | case ECE_MERGE_FILE_IGNORE_OTHER_IN_JAR_WAR: 28 | elManager.checkIgnoreMergeFileInJarWar("a/b.xml"); 29 | break; 30 | case ECE_MERGE_FILE_IGNORE_JAR_WAR_BY_CLASS_DIR_PREFIX: 31 | Map> classDirPrefixMap = new HashMap<>(); 32 | classDirPrefixMap.put(1, JavaCG2Util.genSetFromArray("a1", "a2", "a3")); 33 | classDirPrefixMap.put(2, JavaCG2Util.genSetFromArray("a1.b1", "a2.b2", "a3.b3")); 34 | classDirPrefixMap.put(3, JavaCG2Util.genSetFromArray("a1.b1.c1", "a2.b2.c2", "a3.b3.c3")); 35 | elManager.checkIgnoreJarWarByClassDirPrefix(classDirPrefixMap); 36 | break; 37 | default: 38 | break; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/el/checker/JavaCG2ElChecker4MethodCallEe.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.el.checker; 2 | 3 | import com.adrninistrator.javacg2.common.enums.JavaCG2CallTypeEnum; 4 | import com.adrninistrator.javacg2.el.enums.JavaCG2ElConfigEnum; 5 | import com.adrninistrator.javacg2.el.manager.JavaCG2ElManager; 6 | 7 | /** 8 | * @author adrninistrator 9 | * @date 2025/2/13 10 | * @description: 11 | */ 12 | public class JavaCG2ElChecker4MethodCallEe extends JavaCG2ElChecker { 13 | 14 | @Override 15 | protected void javaCG2DoCheck(JavaCG2ElManager elManager, JavaCG2ElConfigEnum elConfig) { 16 | elManager.checkIgnoreMethodCallByEe(JavaCG2CallTypeEnum.values()[0].getType(), JavaCG2ElChecker4ParseMethod.FULL_METHOD_EXAMPLE); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/el/checker/JavaCG2ElChecker4MethodCallEr.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.el.checker; 2 | 3 | import com.adrninistrator.javacg2.common.enums.JavaCG2CallTypeEnum; 4 | import com.adrninistrator.javacg2.el.enums.JavaCG2ElConfigEnum; 5 | import com.adrninistrator.javacg2.el.manager.JavaCG2ElManager; 6 | 7 | /** 8 | * @author adrninistrator 9 | * @date 2025/2/13 10 | * @description: 11 | */ 12 | public class JavaCG2ElChecker4MethodCallEr extends JavaCG2ElChecker { 13 | 14 | @Override 15 | protected void javaCG2DoCheck(JavaCG2ElManager elManager, JavaCG2ElConfigEnum elConfig) { 16 | elManager.checkIgnoreMethodCallByEr(JavaCG2CallTypeEnum.values()[0].getType(), JavaCG2ElChecker4ParseMethod.FULL_METHOD_EXAMPLE); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/el/checker/JavaCG2ElChecker4MethodCallErEe.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.el.checker; 2 | 3 | import com.adrninistrator.javacg2.common.enums.JavaCG2CallTypeEnum; 4 | import com.adrninistrator.javacg2.el.enums.JavaCG2ElConfigEnum; 5 | import com.adrninistrator.javacg2.el.manager.JavaCG2ElManager; 6 | 7 | /** 8 | * @author adrninistrator 9 | * @date 2025/2/13 10 | * @description: 11 | */ 12 | public class JavaCG2ElChecker4MethodCallErEe extends JavaCG2ElChecker { 13 | 14 | @Override 15 | protected void javaCG2DoCheck(JavaCG2ElManager elManager, JavaCG2ElConfigEnum elConfig) { 16 | elManager.checkIgnoreMethodCallByErEe(JavaCG2CallTypeEnum.values()[0].getType(), JavaCG2ElChecker4ParseMethod.FULL_METHOD_EXAMPLE, 17 | JavaCG2ElChecker4ParseMethod.FULL_METHOD_EXAMPLE); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/el/checker/JavaCG2ElChecker4ParseClass.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.el.checker; 2 | 3 | import com.adrninistrator.javacg2.el.enums.JavaCG2ElConfigEnum; 4 | import com.adrninistrator.javacg2.el.manager.JavaCG2ElManager; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2025/2/13 9 | * @description: 10 | */ 11 | public class JavaCG2ElChecker4ParseClass extends JavaCG2ElChecker { 12 | 13 | @Override 14 | protected void javaCG2DoCheck(JavaCG2ElManager elManager, JavaCG2ElConfigEnum elConfig) { 15 | elManager.checkIgnoreParseClass("a.b.C"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/el/checker/JavaCG2ElChecker4ParseMethod.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.el.checker; 2 | 3 | import com.adrninistrator.javacg2.el.enums.JavaCG2ElConfigEnum; 4 | import com.adrninistrator.javacg2.el.manager.JavaCG2ElManager; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2025/2/13 9 | * @description: 10 | */ 11 | public class JavaCG2ElChecker4ParseMethod extends JavaCG2ElChecker { 12 | 13 | public static final String FULL_METHOD_EXAMPLE = "a.b.C:fun(int)"; 14 | 15 | @Override 16 | protected void javaCG2DoCheck(JavaCG2ElManager elManager, JavaCG2ElConfigEnum elConfig) { 17 | elManager.checkIgnoreParseMethod(FULL_METHOD_EXAMPLE); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/el/enums/ElStringAnyFunctionEnum.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.el.enums; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2025/2/10 6 | * @description: 7 | */ 8 | public enum ElStringAnyFunctionEnum { 9 | CONTAINS_ANY("string.containsAny"), 10 | ENDS_WITH_ANY("string.endsWithAny"), 11 | EQUALS_ANY("string.equalsAny"), 12 | STARTS_WITH_ANY("string.startsWithAny"), 13 | ; 14 | 15 | private final String name; 16 | 17 | ElStringAnyFunctionEnum(String name) { 18 | this.name = name; 19 | } 20 | 21 | public String getName() { 22 | return name; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/el/enums/ElStringFunctionTwoArgsEnum.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.el.enums; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2025/2/22 6 | * @description: 7 | */ 8 | public enum ElStringFunctionTwoArgsEnum { 9 | CONTAINS_IGNORE_CASE("string.containsIC"), 10 | ENDS_WITH_IGNORE_CASE("string.endsWithIC"), 11 | EQUALS_IGNORE_CASE("string.equalsIC"), 12 | STARTS_WITH_IGNORE_CASE("string.startsWithIC"), 13 | ; 14 | 15 | private final String name; 16 | 17 | ElStringFunctionTwoArgsEnum(String name) { 18 | this.name = name; 19 | } 20 | 21 | public String getName() { 22 | return name; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/el/enums/interfaces/ElAllowedVariableInterface.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.el.enums.interfaces; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2025/2/2 6 | * @description: 表达式允许使用的变量接口 7 | */ 8 | public interface ElAllowedVariableInterface { 9 | 10 | // 获取变量名称 11 | String getVariableName(); 12 | 13 | // 获取变量类型 14 | String getType(); 15 | 16 | // 是否为 {名称前缀}{数字} 的形式 17 | boolean isPrefixWithNum(); 18 | 19 | // 获取变量描述 20 | String[] getDescriptions(); 21 | 22 | // 获取变量示例 23 | String[] getValueExamples(); 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/el/enums/interfaces/ElConfigInterface.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.el.enums.interfaces; 2 | 3 | import com.adrninistrator.javacg2.conf.enums.interfaces.ConfigInterface; 4 | import com.adrninistrator.javacg2.el.checker.ElChecker; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2025/2/1 9 | * @description: 表达式配置接口 10 | */ 11 | public interface ElConfigInterface extends ConfigInterface { 12 | 13 | // 获取配置文件允许使用的表达式变量枚举 14 | ElAllowedVariableInterface[] getElAllowedVariableEnums(); 15 | 16 | // 用于提前执行表达式进行检查的类 17 | Class getElCheckClass(); 18 | 19 | // 当前参数是否用于忽略数据 20 | boolean isIgnoreData(); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/el/function/AbstractStringFunctionTwoArgs.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.el.function; 2 | 3 | import com.adrninistrator.javacg2.el.util.ElUtil; 4 | import com.googlecode.aviator.runtime.function.AbstractFunction; 5 | import com.googlecode.aviator.runtime.type.AviatorBoolean; 6 | import com.googlecode.aviator.runtime.type.AviatorObject; 7 | 8 | import java.util.Map; 9 | 10 | /** 11 | * @author adrninistrator 12 | * @date 2025/2/22 13 | * @description: 14 | */ 15 | public abstract class AbstractStringFunctionTwoArgs extends AbstractFunction { 16 | 17 | protected abstract boolean checkString(String argSrc, String argDst); 18 | 19 | @Override 20 | public AviatorObject call(Map env, AviatorObject arg1, AviatorObject arg2) { 21 | String target = ElUtil.getArgStringValue(arg1, env); 22 | String param = ElUtil.getArgStringValue(arg2, env); 23 | 24 | return checkString(target, param) ? AviatorBoolean.TRUE : AviatorBoolean.FALSE; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/el/function/any/AbstractStringAnyFunction.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.el.function.any; 2 | 3 | import com.adrninistrator.javacg2.el.util.ElUtil; 4 | import com.googlecode.aviator.exception.ExpressionRuntimeException; 5 | import com.googlecode.aviator.runtime.function.AbstractVariadicFunction; 6 | import com.googlecode.aviator.runtime.type.AviatorBoolean; 7 | import com.googlecode.aviator.runtime.type.AviatorObject; 8 | import org.apache.commons.lang3.ArrayUtils; 9 | 10 | import java.util.Map; 11 | 12 | /** 13 | * @author adrninistrator 14 | * @date 2025/2/10 15 | * @description: 类似 StringUtils.xxxAny 功能的自定义函数基类 16 | */ 17 | public abstract class AbstractStringAnyFunction extends AbstractVariadicFunction { 18 | 19 | /** 20 | * 比较字符串 21 | * 22 | * @param arg0 第1个参数字符串值 23 | * @param argN 第n(n>1)个参数字符串值 24 | * @return 25 | */ 26 | protected abstract boolean checkString(String arg0, String argN); 27 | 28 | @Override 29 | public AviatorObject variadicCall(Map env, AviatorObject... args) { 30 | if (ArrayUtils.isEmpty(args)) { 31 | throw new ExpressionRuntimeException("参数不允许为空"); 32 | } 33 | 34 | if (args.length < 2) { 35 | throw new ExpressionRuntimeException("至少需要有两个参数"); 36 | } 37 | 38 | String arg0String = ElUtil.getArgStringValue(args[0], env); 39 | for (int i = 1; i < args.length; i++) { 40 | String argString = ElUtil.getArgStringValue(args[i], env); 41 | if (checkString(arg0String, argString)) { 42 | return AviatorBoolean.TRUE; 43 | } 44 | } 45 | return AviatorBoolean.FALSE; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/el/function/any/StringContainsAnyFunction.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.el.function.any; 2 | 3 | import com.adrninistrator.javacg2.el.enums.ElStringAnyFunctionEnum; 4 | 5 | /** 6 | * @author adrninistrator 7 | * @date 2025/2/8 8 | * @description: 9 | */ 10 | public class StringContainsAnyFunction extends AbstractStringAnyFunction { 11 | 12 | @Override 13 | public String getName() { 14 | return ElStringAnyFunctionEnum.CONTAINS_ANY.getName(); 15 | } 16 | 17 | @Override 18 | protected boolean checkString(String arg0, String argN) { 19 | return arg0.contains(argN); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/el/function/any/StringEndsWithAnyFunction.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.el.function.any; 2 | 3 | import com.adrninistrator.javacg2.el.enums.ElStringAnyFunctionEnum; 4 | 5 | /** 6 | * @author adrninistrator 7 | * @date 2025/2/8 8 | * @description: 9 | */ 10 | public class StringEndsWithAnyFunction extends AbstractStringAnyFunction { 11 | 12 | @Override 13 | public String getName() { 14 | return ElStringAnyFunctionEnum.ENDS_WITH_ANY.getName(); 15 | } 16 | 17 | @Override 18 | protected boolean checkString(String arg0, String argN) { 19 | return arg0.endsWith(argN); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/el/function/any/StringEqualsAnyFunction.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.el.function.any; 2 | 3 | import com.adrninistrator.javacg2.el.enums.ElStringAnyFunctionEnum; 4 | 5 | /** 6 | * @author adrninistrator 7 | * @date 2025/2/8 8 | * @description: 9 | */ 10 | public class StringEqualsAnyFunction extends AbstractStringAnyFunction { 11 | 12 | @Override 13 | public String getName() { 14 | return ElStringAnyFunctionEnum.EQUALS_ANY.getName(); 15 | } 16 | 17 | @Override 18 | protected boolean checkString(String arg0, String argN) { 19 | return arg0.equals(argN); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/el/function/any/StringStartsWithAnyFunction.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.el.function.any; 2 | 3 | import com.adrninistrator.javacg2.el.enums.ElStringAnyFunctionEnum; 4 | 5 | /** 6 | * @author adrninistrator 7 | * @date 2025/2/8 8 | * @description: 9 | */ 10 | public class StringStartsWithAnyFunction extends AbstractStringAnyFunction { 11 | 12 | @Override 13 | public String getName() { 14 | return ElStringAnyFunctionEnum.STARTS_WITH_ANY.getName(); 15 | } 16 | 17 | @Override 18 | protected boolean checkString(String arg0, String argN) { 19 | return arg0.startsWith(argN); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/el/function/ignorecase/StringContainsICFunction.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.el.function.ignorecase; 2 | 3 | import com.adrninistrator.javacg2.el.enums.ElStringFunctionTwoArgsEnum; 4 | import com.adrninistrator.javacg2.el.function.AbstractStringFunctionTwoArgs; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2025/2/22 9 | * @description: 10 | */ 11 | public class StringContainsICFunction extends AbstractStringFunctionTwoArgs { 12 | @Override 13 | protected boolean checkString(String argSrc, String argDst) { 14 | return false; 15 | } 16 | 17 | @Override 18 | public String getName() { 19 | return ElStringFunctionTwoArgsEnum.CONTAINS_IGNORE_CASE.getName(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/el/function/ignorecase/StringEndsWithICFunction.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.el.function.ignorecase; 2 | 3 | import com.adrninistrator.javacg2.el.enums.ElStringFunctionTwoArgsEnum; 4 | import com.adrninistrator.javacg2.el.function.AbstractStringFunctionTwoArgs; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2025/2/22 9 | * @description: 10 | */ 11 | public class StringEndsWithICFunction extends AbstractStringFunctionTwoArgs { 12 | @Override 13 | protected boolean checkString(String argSrc, String argDst) { 14 | return false; 15 | } 16 | 17 | @Override 18 | public String getName() { 19 | return ElStringFunctionTwoArgsEnum.ENDS_WITH_IGNORE_CASE.getName(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/el/function/ignorecase/StringEqualsICFunction.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.el.function.ignorecase; 2 | 3 | import com.adrninistrator.javacg2.el.enums.ElStringFunctionTwoArgsEnum; 4 | import com.adrninistrator.javacg2.el.function.AbstractStringFunctionTwoArgs; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2025/2/22 9 | * @description: 10 | */ 11 | public class StringEqualsICFunction extends AbstractStringFunctionTwoArgs { 12 | @Override 13 | protected boolean checkString(String argSrc, String argDst) { 14 | return false; 15 | } 16 | 17 | @Override 18 | public String getName() { 19 | return ElStringFunctionTwoArgsEnum.EQUALS_IGNORE_CASE.getName(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/el/function/ignorecase/StringStartsWithICFunction.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.el.function.ignorecase; 2 | 3 | import com.adrninistrator.javacg2.el.enums.ElStringFunctionTwoArgsEnum; 4 | import com.adrninistrator.javacg2.el.function.AbstractStringFunctionTwoArgs; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2025/2/22 9 | * @description: 10 | */ 11 | public class StringStartsWithICFunction extends AbstractStringFunctionTwoArgs { 12 | @Override 13 | protected boolean checkString(String argSrc, String argDst) { 14 | return false; 15 | } 16 | 17 | @Override 18 | public String getName() { 19 | return ElStringFunctionTwoArgsEnum.STARTS_WITH_IGNORE_CASE.getName(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/el/util/ElUtil.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.el.util; 2 | 3 | import com.googlecode.aviator.exception.ExpressionRuntimeException; 4 | import com.googlecode.aviator.runtime.type.AviatorObject; 5 | 6 | import java.util.Map; 7 | 8 | /** 9 | * @author adrninistrator 10 | * @date 2025/2/22 11 | * @description: 表达式工具类 12 | */ 13 | public class ElUtil { 14 | 15 | // 判断是否是执行用于检测的表达式 16 | private static final ThreadLocal RUN_IN_CHECKER_FLAG = new ThreadLocal<>(); 17 | 18 | /** 19 | * 获取参数的字符串类型的值 20 | * 21 | * @param arg 22 | * @param env 23 | * @return 24 | */ 25 | public static String getArgStringValue(AviatorObject arg, Map env) { 26 | Object argValue = arg.getValue(env); 27 | if (!(argValue instanceof String)) { 28 | throw new ExpressionRuntimeException("只允许使用字符串类型参数"); 29 | } 30 | return (String) argValue; 31 | } 32 | 33 | // 设置执行用于检测的表达式标志 34 | public static void setRunInCheckerFlag() { 35 | RUN_IN_CHECKER_FLAG.set(Boolean.TRUE); 36 | } 37 | 38 | // 清理执行用于检测的表达式标志 39 | public static void clearRunInCheckerFlag() { 40 | RUN_IN_CHECKER_FLAG.remove(); 41 | } 42 | 43 | // 检查执行用于检测的表达式标志 44 | public static boolean checkRunInCheckerFlag() { 45 | return Boolean.TRUE.equals(RUN_IN_CHECKER_FLAG.get()); 46 | } 47 | 48 | private ElUtil() { 49 | throw new IllegalStateException("illegal"); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/exceptions/JavaCG2Error.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.exceptions; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2023/4/2 6 | * @description: 7 | */ 8 | public class JavaCG2Error extends Error { 9 | public JavaCG2Error() { 10 | } 11 | 12 | public JavaCG2Error(String message) { 13 | super(message); 14 | } 15 | 16 | public JavaCG2Error(String message, Throwable cause) { 17 | super(message, cause); 18 | } 19 | 20 | public JavaCG2Error(Throwable cause) { 21 | super(cause); 22 | } 23 | 24 | public JavaCG2Error(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 25 | super(message, cause, enableSuppression, writableStackTrace); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/exceptions/JavaCG2RuntimeException.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.exceptions; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2023/2/13 6 | * @description: 7 | */ 8 | public class JavaCG2RuntimeException extends RuntimeException { 9 | public JavaCG2RuntimeException() { 10 | } 11 | 12 | public JavaCG2RuntimeException(String message) { 13 | super(message); 14 | } 15 | 16 | public JavaCG2RuntimeException(String message, Throwable cause) { 17 | super(message, cause); 18 | } 19 | 20 | public JavaCG2RuntimeException(Throwable cause) { 21 | super(cause); 22 | } 23 | 24 | public JavaCG2RuntimeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 25 | super(message, cause, enableSuppression, writableStackTrace); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/extensions/annotationattributes/AnnotationAttributesFormatterInterface.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.extensions.annotationattributes; 2 | 3 | import org.apache.bcel.classfile.ElementValuePair; 4 | 5 | /** 6 | * @author adrninistrator 7 | * @date 2022/8/28 8 | * @description: 对注解属性的元素值进行格式化的接口 9 | */ 10 | public interface AnnotationAttributesFormatterInterface { 11 | 12 | String format(ElementValuePair elementValuePair); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/extensions/annotationattributes/DefaultAnnotationAttributesFormatter.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.extensions.annotationattributes; 2 | 3 | import com.adrninistrator.javacg2.common.JavaCG2Constants; 4 | import org.apache.bcel.classfile.ElementValuePair; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2022/8/28 9 | * @description: 10 | */ 11 | public class DefaultAnnotationAttributesFormatter implements AnnotationAttributesFormatterInterface { 12 | 13 | @Override 14 | public String format(ElementValuePair elementValuePair) { 15 | return encodeAnnotationValue(elementValuePair.getValue().toString()); 16 | } 17 | 18 | public static String encodeAnnotationValue(String value) { 19 | return value.replace('\r', JavaCG2Constants.ANNOTATION_ATTRIBUTE_VALUE_REPLACE_CARRIAGE_RETURN) 20 | .replace('\n', JavaCG2Constants.ANNOTATION_ATTRIBUTE_VALUE_REPLACE_LINE_FEED); 21 | } 22 | 23 | public static String decodeAnnotationValue(String value) { 24 | return value.replace(JavaCG2Constants.ANNOTATION_ATTRIBUTE_VALUE_REPLACE_CARRIAGE_RETURN, '\r') 25 | .replace(JavaCG2Constants.ANNOTATION_ATTRIBUTE_VALUE_REPLACE_LINE_FEED, '\n'); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/extensions/codeparser/AbstractSaveData2FileParser.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.extensions.codeparser; 2 | 3 | import com.adrninistrator.javacg2.util.JavaCG2FileUtil; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import java.io.Writer; 8 | 9 | /** 10 | * @author adrninistrator 11 | * @date 2023/3/13 12 | * @description: 解析并将结果保存在文件的类(对jar包中的其他文件解析) 13 | */ 14 | public abstract class AbstractSaveData2FileParser implements JarEntryOtherFileParser { 15 | private static final Logger logger = LoggerFactory.getLogger(AbstractSaveData2FileParser.class); 16 | 17 | protected Writer writer; 18 | 19 | /** 20 | * 返回当前生成的文件名 21 | * 22 | * @return 23 | */ 24 | public abstract String chooseFileName(); 25 | 26 | /** 27 | * 初始化 28 | * 29 | * @param outputFilePath 输出文件路径 30 | */ 31 | public boolean init(String outputFilePath) { 32 | try { 33 | writer = JavaCG2FileUtil.genBufferedWriter(outputFilePath); 34 | return true; 35 | } catch (Exception e) { 36 | logger.error("error ", e); 37 | return false; 38 | } 39 | } 40 | 41 | /** 42 | * 关闭 43 | */ 44 | public void close() { 45 | try { 46 | writer.close(); 47 | } catch (Exception e) { 48 | logger.error("error ", e); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/extensions/codeparser/CodeParserInterface.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.extensions.codeparser; 2 | 3 | /** 4 | * @author Adrninistrator 5 | * @date 2021/8/10 6 | * @description: 对jar包中的文件或字节码解析类的基础接口 7 | */ 8 | public interface CodeParserInterface { 9 | 10 | /** 11 | * 初始化,整个执行过程中只执行一次 12 | */ 13 | default void initCodeParser() { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/extensions/codeparser/JarEntryOtherFileParser.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.extensions.codeparser; 2 | 3 | import java.io.InputStream; 4 | 5 | /** 6 | * @author adrninistrator 7 | * @date 2023/2/16 8 | * @description: 对jar包中的其他文件解析类的接口 9 | */ 10 | public interface JarEntryOtherFileParser extends CodeParserInterface { 11 | 12 | /** 13 | * 返回需要处理jar包中的其他文件的后缀数组(除.class文件外),忽略大小写,不需要以"."开头,例如"xml" 14 | * 若需要使以下 parseJarEntryOtherFile() 方法被调用,则当前方法需要返回对应的文件后缀数组 15 | */ 16 | String[] chooseJarEntryOtherFileExt(); 17 | 18 | /** 19 | * 处理jar包中的文件(除class文件外) 20 | * 仅当以上 chooseJarEntryOtherFileExt() 方法返回的数组中包含当前文件后缀时,才会调用当前方法 21 | * 22 | * @param inputStream 当前文件对应的输入流 23 | * @param jarEntryPath 当前文件在jar包中的路径 24 | */ 25 | void parseJarEntryOtherFile(InputStream inputStream, String jarEntryPath); 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/extensions/codeparser/MethodAnnotationParser.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.extensions.codeparser; 2 | 3 | import com.adrninistrator.javacg2.dto.call.MethodCallList; 4 | import org.apache.bcel.classfile.AnnotationEntry; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2023/2/16 9 | * @description: 对方法注解解析类的接口 10 | */ 11 | public interface MethodAnnotationParser extends CodeParserInterface { 12 | 13 | /** 14 | * 返回需要处理方法注解的注解类名 15 | * 若需要使以下 parseMethodAnnotation() 方法被调用,则当前方法需要返回对应的方法注解的注解类名 16 | */ 17 | String[] chooseMethodAnnotationClassName(); 18 | 19 | /** 20 | * 处理方法注解 21 | * 仅当以上 chooseMethodAnnotationClassName() 方法返回的数组中包含当前方法注解的注解类名时,才会调用当前方法 22 | * 23 | * @param callerClassName 当前方法的类名 24 | * @param callerMethodName 当前方法的方法名 25 | * @param callerMethodArgTypes 当前方法的参数类型 26 | * @param callerReturnType 当前方法的返回类型 27 | * @param annotationClassName 当前处理的注解类名 28 | * @param annotationEntry 当前处理的注解信息 29 | * @param methodCallList 方法调用信息列表 30 | */ 31 | void parseMethodAnnotation(String callerClassName, 32 | String callerMethodName, 33 | String callerMethodArgTypes, 34 | String callerReturnType, 35 | String annotationClassName, 36 | AnnotationEntry annotationEntry, 37 | MethodCallList methodCallList); 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/extensions/codeparser/SpringXmlBeanParserInterface.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.extensions.codeparser; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * @author adrninistrator 7 | * @date 2023/3/13 8 | * @description: 对Spring XML文件中的bean解析的接口 9 | */ 10 | public interface SpringXmlBeanParserInterface extends JarEntryOtherFileParser { 11 | 12 | /** 13 | * 根据Spring Bean的id获取对应的类名 14 | * 15 | * @param beanId 16 | * @return 17 | */ 18 | String getBeanClass(String beanId); 19 | 20 | /** 21 | * 获取Spring Bean对应的Map 22 | * key Bean名称 23 | * value Bean的类名 24 | * 25 | * @return 26 | */ 27 | Map getBeanMap(); 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/extensions/methodcall/JavaCG2MethodCallExtensionInterface.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.extensions.methodcall; 2 | 3 | import com.adrninistrator.javacg2.dto.call.MethodCall; 4 | import com.adrninistrator.javacg2.dto.call.MethodCallList; 5 | import com.adrninistrator.javacg2.dto.counter.JavaCG2Counter; 6 | 7 | /** 8 | * @author adrninistrator 9 | * @date 2025/2/15 10 | * @description: 方法调用处理扩展类接口 11 | */ 12 | public interface JavaCG2MethodCallExtensionInterface { 13 | 14 | /** 15 | * 处理方法调用 16 | * 17 | * @param methodCall 当前的方法调用 18 | * @param callIdCounter 方法调用计数器 19 | * @param methodCallList 方法调用列表 20 | */ 21 | void handle(MethodCall methodCall, JavaCG2Counter callIdCounter, MethodCallList methodCallList); 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/markdown/MarkdownConstants.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.markdown; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2023/2/17 6 | * @description: markdown相关常量 7 | */ 8 | public class MarkdownConstants { 9 | 10 | public static final String FLAG_TITLE = "#"; 11 | public static final String FLAG_SPACE = " "; 12 | public static final String FLAG_CODE = "```"; 13 | public static final String FLAG_LIST = "- "; 14 | public static final String FLAG_DOT = "."; 15 | public static final String FLAG_VERTICAL_BAR = "|"; 16 | public static final String FLAG_TABLE_LINE = "---"; 17 | public static final String FLAG_HTML_NEW_LINE = "
"; 18 | 19 | private MarkdownConstants() { 20 | throw new IllegalStateException("illegal"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/markdown/enums/MDCodeBlockTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.markdown.enums; 2 | 3 | /** 4 | * @author adrninistrator 5 | * @date 2022/11/27 6 | * @description: markdown代码块类型枚举 7 | */ 8 | public enum MDCodeBlockTypeEnum { 9 | MDCBTE_SQL("sql"), 10 | MDCBTE_JAVA("java"), 11 | ; 12 | 13 | private final String type; 14 | 15 | MDCodeBlockTypeEnum(String type) { 16 | this.type = type; 17 | } 18 | 19 | public String getType() { 20 | return type; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/targz/TarGzUnpacker.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.targz; 2 | 3 | import com.adrninistrator.javacg2.util.JavaCG2FileUtil; 4 | import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream; 5 | import org.apache.commons.lang3.ArrayUtils; 6 | import org.apache.tools.tar.TarEntry; 7 | import org.apache.tools.tar.TarInputStream; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import java.io.BufferedInputStream; 12 | import java.io.File; 13 | import java.io.FileInputStream; 14 | 15 | /** 16 | * @author adrninistrator 17 | * @date 2024/1/18 18 | * @description: 用于解压.tar.gz中的war包、jar包及配置文件 19 | */ 20 | public class TarGzUnpacker { 21 | private static final Logger logger = LoggerFactory.getLogger(TarGzUnpacker.class); 22 | 23 | // 需要解压的tar.gz文件路径 24 | protected final String tarGzFilePath; 25 | 26 | // 保存解压出文件的目录路径 27 | private final String unpackDstDirPath; 28 | 29 | private String tarGzFileName; 30 | 31 | /** 32 | * @param tarGzFilePath 需要解压的tar.gz文件路径 33 | * @param unpackDstDirPath 保存解压出文件的目录路径,需要保证执行前该目录不存在或为空 34 | */ 35 | public TarGzUnpacker(String tarGzFilePath, 36 | String unpackDstDirPath) { 37 | this.tarGzFilePath = tarGzFilePath; 38 | this.unpackDstDirPath = unpackDstDirPath; 39 | } 40 | 41 | /** 42 | * 执行解压的方法 43 | * 44 | * @return true: 成功 false: 失败 45 | */ 46 | public boolean unpack() { 47 | logger.info("开始处理文件 {}", tarGzFilePath); 48 | File tarGzFile = new File(tarGzFilePath); 49 | if (!tarGzFile.exists()) { 50 | logger.error("文件不存在 {}", tarGzFilePath); 51 | return false; 52 | } 53 | tarGzFileName = tarGzFile.getName(); 54 | 55 | if (!JavaCG2FileUtil.isDirectoryExists(unpackDstDirPath, true)) { 56 | logger.error("输出目录不存在且无法创建 {} {}", tarGzFileName, unpackDstDirPath); 57 | return false; 58 | } 59 | File[] files = new File(unpackDstDirPath).listFiles(); 60 | if (!ArrayUtils.isEmpty(files)) { 61 | logger.error("保存解压后文件的目录非空,请先清空该目录 {}", unpackDstDirPath); 62 | return false; 63 | } 64 | 65 | try (TarInputStream tarInput = new TarInputStream(new GzipCompressorInputStream(new BufferedInputStream(new FileInputStream(tarGzFile))))) { 66 | TarEntry tarEntry; 67 | while ((tarEntry = tarInput.getNextEntry()) != null) { 68 | if (!tarEntry.isFile()) { 69 | continue; 70 | } 71 | 72 | handleFileInTar(tarInput, tarEntry); 73 | } 74 | return true; 75 | } catch (Exception e) { 76 | logger.error("error {} ", tarGzFileName, e); 77 | return false; 78 | } 79 | } 80 | 81 | protected boolean handleFileInTar(TarInputStream inputStream, TarEntry tarEntry) { 82 | String tarEntryName = tarEntry.getName(); 83 | // 生成的文件目录保持原有形式 84 | String filePath = unpackDstDirPath + File.separator + tarEntryName; 85 | logger.info("保存文件 {} {} {}", tarGzFileName, tarEntryName, filePath); 86 | File file = new File(filePath); 87 | if (!JavaCG2FileUtil.isDirectoryExists(file.getParent(), true)) { 88 | logger.error("创建文件所在目录失败 {}", file.getParent()); 89 | return false; 90 | } 91 | return JavaCG2FileUtil.saveInputToFileNoClose(inputStream, file); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/thread/JavaCG2UncaughtExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.thread; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2024/3/23 9 | * @description: 10 | */ 11 | public class JavaCG2UncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { 12 | 13 | private static final Logger logger = LoggerFactory.getLogger(JavaCG2UncaughtExceptionHandler.class); 14 | 15 | private int exceptionCount; 16 | 17 | @Override 18 | public void uncaughtException(Thread t, Throwable e) { 19 | if (e != null) { 20 | exceptionCount++; 21 | logger.error("线程池执行出现未捕获的异常 {} ", t.getName(), e); 22 | } 23 | } 24 | 25 | public int getExceptionCount() { 26 | return exceptionCount; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/thread/ThreadFactory4TPE.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.thread; 2 | 3 | import java.util.concurrent.ThreadFactory; 4 | import java.util.concurrent.atomic.AtomicInteger; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2021/6/21 9 | * @description: 10 | */ 11 | 12 | public class ThreadFactory4TPE implements ThreadFactory { 13 | 14 | private static final AtomicInteger ai = new AtomicInteger(0); 15 | 16 | private final JavaCG2UncaughtExceptionHandler javaCG2UncaughtExceptionHandler = new JavaCG2UncaughtExceptionHandler(); 17 | 18 | private final String threadNamePrefix; 19 | 20 | public ThreadFactory4TPE(String threadNamePrefix) { 21 | this.threadNamePrefix = threadNamePrefix; 22 | } 23 | 24 | @Override 25 | public Thread newThread(Runnable r) { 26 | Thread thread = new Thread(r); 27 | thread.setName(threadNamePrefix + "-" + ai.addAndGet(1)); 28 | thread.setUncaughtExceptionHandler(javaCG2UncaughtExceptionHandler); 29 | // 设置线程为非守护线程 30 | thread.setDaemon(false); 31 | 32 | return thread; 33 | } 34 | 35 | public int getExceptionCount() { 36 | return javaCG2UncaughtExceptionHandler.getExceptionCount(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/adrninistrator/javacg2/writer/WriterSupportSkip.java: -------------------------------------------------------------------------------- 1 | package com.adrninistrator.javacg2.writer; 2 | 3 | import com.adrninistrator.javacg2.util.JavaCG2FileUtil; 4 | 5 | import java.io.Closeable; 6 | import java.io.IOException; 7 | import java.io.Writer; 8 | 9 | /** 10 | * @author adrninistrator 11 | * @date 2023/4/26 12 | * @description: 包装后的Writer,若未写文件则不创建文件 13 | */ 14 | public class WriterSupportSkip implements Closeable { 15 | 16 | private final String filePath; 17 | private final boolean buffered; 18 | 19 | private Writer writer; 20 | 21 | public WriterSupportSkip(String filePath) { 22 | this(filePath, true); 23 | } 24 | 25 | public WriterSupportSkip(String filePath, boolean buffered) { 26 | this.filePath = filePath; 27 | this.buffered = buffered; 28 | } 29 | 30 | @Override 31 | public void close() throws IOException { 32 | if (writer != null) { 33 | writer.close(); 34 | } 35 | } 36 | 37 | public void write(String data) throws IOException { 38 | if (writer == null) { 39 | writer = JavaCG2FileUtil.genBufferedWriter(filePath); 40 | } 41 | writer.write(data); 42 | if (!buffered) { 43 | // 不缓存时,每次写文件后flush 44 | writer.flush(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/copy/javassist/bytecode/BadBytecode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Javassist, a Java-bytecode translator toolkit. 3 | * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. 4 | * 5 | * The contents of this file are subject to the Mozilla Public License Version 6 | * 1.1 (the "License"); you may not use this file except in compliance with 7 | * the License. Alternatively, the contents of this file may be used under 8 | * the terms of the GNU Lesser General Public License Version 2.1 or later, 9 | * or the Apache License Version 2.0. 10 | * 11 | * Software distributed under the License is distributed on an "AS IS" basis, 12 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 13 | * for the specific language governing rights and limitations under the 14 | * License. 15 | */ 16 | 17 | package copy.javassist.bytecode; 18 | 19 | /** 20 | * Signals that a bad bytecode sequence has been found. 21 | */ 22 | public class BadBytecode extends Exception { 23 | /** 24 | * default serialVersionUID 25 | */ 26 | private static final long serialVersionUID = 1L; 27 | 28 | public BadBytecode(String msg) { 29 | super(msg); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/copy/javassist/bytecode/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author adrninistrator 3 | * @date 2022/12/6 4 | * @description: javassist-3.28.0-GA 5 | */ 6 | package copy.javassist.bytecode; 7 | -------------------------------------------------------------------------------- /src/main/resources/_javacg2_config/config.properties: -------------------------------------------------------------------------------- 1 | # 处理方法调用时是否解析被调用对象和参数可能的类型与值 2 | parse.method.call.type.value=true 3 | 4 | # 处理类的方法前是否需要先解析构造函数以获取非静态字段可能的类型,仅当parse.method.call.type.value参数为true时才可以生效 5 | first.parse.init.method.type=true 6 | 7 | # 是否需要分析dto的字段之间的关联关系,仅当parse.method.call.type.value参数为true时才可以生效 8 | analyse.field.relationship=false 9 | 10 | # 解析方法出现异常时,是否要继续。true: 继续;false: 不继续 11 | continue.when.error=false 12 | 13 | # 记录方法分析耗时的开关(开启后会在输出目录中生成相关文件)。true: 开启;false: 关闭 14 | log.method.spend.time=true 15 | 16 | # 生成文件的根目录,以"/"或"\\"作为分隔符,末尾是否为分隔符不影响(默认为jar包所在目录) 17 | output.root.path= 18 | 19 | # 生成文件后缀名 20 | output.file.ext=.txt 21 | 22 | # 表达式执行时是否开启调试模式,若开启会在应用日志中输出表达式执行时的详细信息 23 | el.debug.mode=false 24 | 25 | # 解析方法调用时,通过new创建的被调用类型使用原始类型还是实际类型 26 | # 例如 Super1 obj = new Child1(); obj.func1(); ,则被调用对象的原始类型为Super1,实际类型为Child1 27 | # only_raw 仅记录原始类型 only_actual 仅记录实际类型 raw_actual 记录原始类型+实际类型 28 | handle.callee.new.raw.actual=only_actual 29 | 30 | # 解析方法调用时,被调用对象为Spring Bean,类型使用原始类型还是实际类型(支持字段注入、getBean()方法) 31 | # 例如Spring Bean字段定义的类型为Super1,实际注入的类型为Child1,则被调用对象的原始类型为Super1,实际类型为Child1 32 | # only_raw 仅记录原始类型 only_actual 仅记录实际类型 raw_actual 记录原始类型+实际类型 33 | handle.callee.spring.bean.raw.actual=only_actual 34 | 35 | -------------------------------------------------------------------------------- /src/main/resources/_javacg2_config/fr_eq_conversion_method.properties: -------------------------------------------------------------------------------- 1 | # (作用) 在处理通过get/set方法的字段关联关系时使用,指定方法返回值与被调用对象或参数认为是等值转换的方法(每行代表一条记录,支持多行) 2 | # (内容) key指定对应的方法,包含{完整类名}:{方法名} 3 | # (内容) value指定与方法返回值等值的被调用对象(使用0表示)或方法参数(从1开始)序号 4 | # (格式) {完整类名}:{方法名}={被调用对象或方法参数序号} 5 | java.lang.Boolean:=1 6 | java.lang.Boolean:valueOf=1 7 | java.lang.Boolean:parseBoolean=1 8 | java.lang.Integer:=1 9 | java.lang.Integer:valueOf=1 10 | java.lang.Integer:parseInt=1 11 | java.lang.Long:=1 12 | java.lang.Long:valueOf=1 13 | java.lang.Long:parseLong=1 14 | java.lang.Float:=1 15 | java.lang.Float:valueOf=1 16 | java.lang.Float:parseFloat=1 17 | java.lang.Double:=1 18 | java.lang.Double:valueOf=1 19 | java.lang.Double:parseDouble=1 20 | java.lang.String:=1 21 | java.lang.String:valueOf=1 22 | java.lang.String:trim=0 23 | java.math.BigDecimal:=1 24 | java.math.BigDecimal:valueOf=1 25 | java.math.BigDecimal:toString=0 26 | java.math.BigDecimal:=0 27 | org.apache.commons.lang3.StringUtils:defaultIfBlank=1 28 | org.apache.commons.lang3.StringUtils:defaultIfEmpty=1 29 | org.apache.commons.lang3.StringUtils:defaultString=1 30 | org.apache.commons.lang3.StringUtils:trim=1 31 | org.apache.commons.lang.StringUtils:defaultIfBlank=1 32 | org.apache.commons.lang.StringUtils:defaultIfEmpty=1 33 | org.apache.commons.lang.StringUtils:defaultString=1 34 | org.apache.commons.lang.StringUtils:trim=1 35 | org.apache.commons.lang3.math.NumberUtils:createBigDecimal=1 36 | org.apache.commons.lang3.math.NumberUtils:createBigInteger=1 37 | org.apache.commons.lang3.math.NumberUtils:createDouble=1 38 | org.apache.commons.lang3.math.NumberUtils:createFloat=1 39 | org.apache.commons.lang3.math.NumberUtils:createInteger=1 40 | org.apache.commons.lang3.math.NumberUtils:createLong=1 41 | org.apache.commons.lang3.math.NumberUtils:createNumber=1 42 | org.apache.commons.lang.math.NumberUtils:createBigDecimal=1 43 | org.apache.commons.lang.math.NumberUtils:createBigInteger=1 44 | org.apache.commons.lang.math.NumberUtils:createDouble=1 45 | org.apache.commons.lang.math.NumberUtils:createFloat=1 46 | org.apache.commons.lang.math.NumberUtils:createInteger=1 47 | org.apache.commons.lang.math.NumberUtils:createLong=1 48 | org.apache.commons.lang.math.NumberUtils:createNumber=1 49 | -------------------------------------------------------------------------------- /src/main/resources/_javacg2_config/jar_dir.properties: -------------------------------------------------------------------------------- 1 | # (作用) 指定需要处理的jar、war包路径,或保存class、jar、war文件的目录路径(每行代表一条记录,支持多行) 2 | # (格式) 路径中的分隔符使用/或\均可,目录最后指定或不指定分隔符均可 3 | # (示例) build/ 4 | # (示例) build/test.jar 5 | # (示例) D:/test/build/test.jar 6 | -------------------------------------------------------------------------------- /src/main/resources/_javacg2_merge_file_switch/ignore_class_in_dir.av: -------------------------------------------------------------------------------- 1 | ## (作用)在 合并需要解析的目录或jar/war文件时 使用的表达式 2 | ## (作用)若当前配置文件中的表达式执行结果为 true,则跳过合并(及解析)对应的文件 3 | ## (作用)若表达式执行结果为 false,或未指定表达式,则当前配置不会跳过对应的文件 4 | ## (范围)指定是否跳过合并目录中的class文件 5 | ## (表达式使用示例文件)请参考 el_example.md 6 | ## (允许使用的变量){变量名称} {变量类型} {变量描述} {变量值示例} 7 | ## {file_path} {String} {目录中的文件绝对路径, 以斜杠/为分隔符} {D:/a/b.jar, /tmp/a/b.jar} 8 | ## {file_dir_path} {String} {目录中的文件所在目录绝对路径, 以斜杠/为分隔符,不以分隔符结尾} {D:/a, /tmp/a} 9 | ## {file_name} {String} {文件名称} {a.class, a.xml} 10 | -------------------------------------------------------------------------------- /src/main/resources/_javacg2_merge_file_switch/ignore_class_in_jar_war.av: -------------------------------------------------------------------------------- 1 | ## (作用)在 合并需要解析的目录或jar/war文件时 使用的表达式 2 | ## (作用)若当前配置文件中的表达式执行结果为 true,则跳过合并(及解析)对应的文件 3 | ## (作用)若表达式执行结果为 false,或未指定表达式,则当前配置不会跳过对应的文件 4 | ## (范围)指定是否跳过合并jar/war中的class文件 5 | ## (表达式使用示例文件)请参考 el_example.md 6 | ## (允许使用的变量){变量名称} {变量类型} {变量描述} {变量值示例} 7 | ## {file_path} {String} {jar/war文件中的文件相对路径, 相对根目录的路径, 以斜杠/为分隔符,不以分隔符开头} {a/b/c.jar, a/b/c.xml} 8 | ## {file_dir_path} {String} {jar/war文件中的文件所在目录相对路径, 相对根目录的路径, 以斜杠/为分隔符,不以分隔符开头或结尾} {a/b, a/b} 9 | ## {file_name} {String} {文件名称} {a.class, a.xml} 10 | ## {class_file_path} {String} {jar/war文件中的class文件的相对路径, 相对根目录,或WEB-INF/classes、BOOT-INF/classes目录的路径, 以斜杠/为分隔符,不以分隔符开头} {a/b/c.class} 11 | -------------------------------------------------------------------------------- /src/main/resources/_javacg2_merge_file_switch/ignore_jar_in_dir.av: -------------------------------------------------------------------------------- 1 | ## (作用)在 合并需要解析的目录或jar/war文件时 使用的表达式 2 | ## (作用)若当前配置文件中的表达式执行结果为 true,则跳过合并(及解析)对应的文件 3 | ## (作用)若表达式执行结果为 false,或未指定表达式,则当前配置不会跳过对应的文件 4 | ## (范围)指定是否跳过合并目录中的jar文件 5 | ## (表达式使用示例文件)请参考 el_example.md 6 | ## (允许使用的变量){变量名称} {变量类型} {变量描述} {变量值示例} 7 | ## {file_path} {String} {目录中的文件绝对路径, 以斜杠/为分隔符} {D:/a/b.jar, /tmp/a/b.jar} 8 | ## {file_dir_path} {String} {目录中的文件所在目录绝对路径, 以斜杠/为分隔符,不以分隔符结尾} {D:/a, /tmp/a} 9 | ## {file_name} {String} {文件名称} {a.class, a.xml} 10 | -------------------------------------------------------------------------------- /src/main/resources/_javacg2_merge_file_switch/ignore_jar_in_jar_war.av: -------------------------------------------------------------------------------- 1 | ## (作用)在 合并需要解析的目录或jar/war文件时 使用的表达式 2 | ## (作用)若当前配置文件中的表达式执行结果为 true,则跳过合并(及解析)对应的文件 3 | ## (作用)若表达式执行结果为 false,或未指定表达式,则当前配置不会跳过对应的文件 4 | ## (范围)指定是否跳过合并jar/war中的jar文件 5 | ## (表达式使用示例文件)请参考 el_example.md 6 | ## (允许使用的变量){变量名称} {变量类型} {变量描述} {变量值示例} 7 | ## {file_path} {String} {jar/war文件中的文件相对路径, 相对根目录的路径, 以斜杠/为分隔符,不以分隔符开头} {a/b/c.jar, a/b/c.xml} 8 | ## {file_dir_path} {String} {jar/war文件中的文件所在目录相对路径, 相对根目录的路径, 以斜杠/为分隔符,不以分隔符开头或结尾} {a/b, a/b} 9 | ## {file_name} {String} {文件名称} {a.class, a.xml} 10 | -------------------------------------------------------------------------------- /src/main/resources/_javacg2_merge_file_switch/ignore_jar_war_by_class_dir_prefix.av: -------------------------------------------------------------------------------- 1 | ## (作用)在 合并需要解析的目录或jar/war文件时 使用的表达式 2 | ## (作用)若当前配置文件中的表达式执行结果为 true,则跳过合并(及解析)对应的文件 3 | ## (作用)若表达式执行结果为 false,或未指定表达式,则当前配置不会跳过对应的文件 4 | ## (范围)通过class文件目录的不同层级的路径前缀判断是否跳过合并当前jar/war文件 5 | ## (范围)相当于通过jar/war文件中类的包名控制是否跳过合并当前jar/war文件 6 | ## (范围)以下参数为jar/war文件中的class文件目录的不同层级的路径前缀集合 7 | ## (范围)集合中的元素类型为字符串,以/作为分隔符,不会以分隔符开头或结尾 8 | ## (范围)例如jar文件中有a1/c1.class、a2/b2/c2.class,则该jar文件中的class文件目录1级路径前缀有a1、a2,2级路径前缀有a2/b2,没有大于2级的路径前缀 9 | ## (范围)在使用以下 class_dir_prefix_level_ 参数时,需要以 class_dir_prefix_level_ 开头,后续通过数字指定class文件路径层级 10 | ## (范围)例如 class_dir_prefix_level_3 代表第3级class文件路径集合 11 | ## (范围)以下的 file_name file_dir_path 均代表需要判断是否需要跳过合并的jar/war文件 12 | ## (表达式使用示例文件)请参考 el_example.md 13 | ## (允许使用的变量){变量名称} {变量类型} {变量描述} {变量值示例} 14 | ## {class_dir_prefix_level_} {Set} {jar/war文件中的class文件目录的不同层级的路径前缀集合} {集合:('a'), 集合:('a', 'a/b')} 15 | ## {file_name} {String} {文件名称} {a.class, a.xml} 16 | ## {file_dir_path} {String} {目录中的文件所在目录绝对路径, 以斜杠/为分隔符,不以分隔符结尾} {D:/a, /tmp/a} 17 | -------------------------------------------------------------------------------- /src/main/resources/_javacg2_merge_file_switch/ignore_other_in_dir.av: -------------------------------------------------------------------------------- 1 | ## (作用)在 合并需要解析的目录或jar/war文件时 使用的表达式 2 | ## (作用)若当前配置文件中的表达式执行结果为 true,则跳过合并(及解析)对应的文件 3 | ## (作用)若表达式执行结果为 false,或未指定表达式,则当前配置不会跳过对应的文件 4 | ## (范围)指定是否跳过合并目录中的非jar、war、class文件 5 | ## (表达式使用示例文件)请参考 el_example.md 6 | ## (允许使用的变量){变量名称} {变量类型} {变量描述} {变量值示例} 7 | ## {file_path} {String} {目录中的文件绝对路径, 以斜杠/为分隔符} {D:/a/b.jar, /tmp/a/b.jar} 8 | ## {file_dir_path} {String} {目录中的文件所在目录绝对路径, 以斜杠/为分隔符,不以分隔符结尾} {D:/a, /tmp/a} 9 | ## {file_name} {String} {文件名称} {a.class, a.xml} 10 | ## {file_ext} {String} {非jar、war、class文件后缀, 以.开头} {.xml, .properties} 11 | -------------------------------------------------------------------------------- /src/main/resources/_javacg2_merge_file_switch/ignore_other_in_jar_war.av: -------------------------------------------------------------------------------- 1 | ## (作用)在 合并需要解析的目录或jar/war文件时 使用的表达式 2 | ## (作用)若当前配置文件中的表达式执行结果为 true,则跳过合并(及解析)对应的文件 3 | ## (作用)若表达式执行结果为 false,或未指定表达式,则当前配置不会跳过对应的文件 4 | ## (范围)指定是否跳过合并jar/war中的非jar、war、class文件 5 | ## (表达式使用示例文件)请参考 el_example.md 6 | ## (允许使用的变量){变量名称} {变量类型} {变量描述} {变量值示例} 7 | ## {file_path} {String} {jar/war文件中的文件相对路径, 相对根目录的路径, 以斜杠/为分隔符,不以分隔符开头} {a/b/c.jar, a/b/c.xml} 8 | ## {file_dir_path} {String} {jar/war文件中的文件所在目录相对路径, 相对根目录的路径, 以斜杠/为分隔符,不以分隔符开头或结尾} {a/b, a/b} 9 | ## {file_name} {String} {文件名称} {a.class, a.xml} 10 | ## {file_ext} {String} {非jar、war、class文件后缀, 以.开头} {.xml, .properties} 11 | -------------------------------------------------------------------------------- /src/main/resources/_javacg2_merge_file_switch/ignore_war_in_dir.av: -------------------------------------------------------------------------------- 1 | ## (作用)在 合并需要解析的目录或jar/war文件时 使用的表达式 2 | ## (作用)若当前配置文件中的表达式执行结果为 true,则跳过合并(及解析)对应的文件 3 | ## (作用)若表达式执行结果为 false,或未指定表达式,则当前配置不会跳过对应的文件 4 | ## (范围)指定是否跳过合并目录中的war文件 5 | ## (表达式使用示例文件)请参考 el_example.md 6 | ## (允许使用的变量){变量名称} {变量类型} {变量描述} {变量值示例} 7 | ## {file_path} {String} {目录中的文件绝对路径, 以斜杠/为分隔符} {D:/a/b.jar, /tmp/a/b.jar} 8 | ## {file_dir_path} {String} {目录中的文件所在目录绝对路径, 以斜杠/为分隔符,不以分隔符结尾} {D:/a, /tmp/a} 9 | ## {file_name} {String} {文件名称} {a.class, a.xml} 10 | -------------------------------------------------------------------------------- /src/main/resources/_javacg2_parse_class_method_switch/parse_ignore_class.av: -------------------------------------------------------------------------------- 1 | ## (作用)在 解析类或方法时 使用的表达式 2 | ## (作用)若当前配置文件中的表达式执行结果为 true,则跳过解析对应的类或方法 3 | ## (作用)若表达式执行结果为 false,或未指定表达式,则当前配置不会跳过对应的类或方法 4 | ## (范围)指定是否跳过解析类 5 | ## (表达式使用示例文件)请参考 el_example.md 6 | ## (允许使用的变量){变量名称} {变量类型} {变量描述} {变量值示例} 7 | ## {class_name} {String} {完整类名} {a.b.Class1} 8 | ## {package_name} {String} {完整包名, 不会以.结束} {a.b} 9 | ## {simple_class_name} {String} {简单类名} {Class1} 10 | -------------------------------------------------------------------------------- /src/main/resources/_javacg2_parse_class_method_switch/parse_ignore_method.av: -------------------------------------------------------------------------------- 1 | ## (作用)在 解析类或方法时 使用的表达式 2 | ## (作用)若当前配置文件中的表达式执行结果为 true,则跳过解析对应的类或方法 3 | ## (作用)若表达式执行结果为 false,或未指定表达式,则当前配置不会跳过对应的类或方法 4 | ## (范围)指定是否跳过解析方法 5 | ## (表达式使用示例文件)请参考 el_example.md 6 | ## (允许使用的变量){变量名称} {变量类型} {变量描述} {变量值示例} 7 | ## {class_name} {String} {完整类名} {a.b.Class1} 8 | ## {package_name} {String} {完整包名, 不会以.结束} {a.b} 9 | ## {simple_class_name} {String} {简单类名} {Class1} 10 | ## {method_name} {String} {方法名称, 不包括括号及方法参数} {method1} 11 | -------------------------------------------------------------------------------- /src/main/resources/_javacg2_parse_method_call_switch/parse_ignore_method_call_ee.av: -------------------------------------------------------------------------------- 1 | ## (作用)在 解析方法调用时 使用的表达式 2 | ## (作用)若当前配置文件中的表达式执行结果为 true,则跳过解析对应的方法调用 3 | ## (作用)若表达式执行结果为 false,或未指定表达式,则当前配置不会跳过对应的方法调用 4 | ## (范围)指定是否跳过解析方法调用,只通过被调用方法判断 5 | ## (表达式使用示例文件)请参考 el_example.md 6 | ## (允许使用的变量){变量名称} {变量类型} {变量描述} {变量值示例} 7 | ## {method_call_type} {String} {方法调用类型, 参考 JavaCG2CallTypeEnum 类} {VIR INT SPE STA DYN _SPR_ACT_I _SPR_ACT_C _ACT_I _ACT_C _ITF _LM _RIR1 _RIR2 _CIC1 _CIC2 _TCID1 _TCID2 _TCWRID1 _TCWRID2 _TSR _SCC _CCS _CCS_SPE _CCS_I _CCID _ICID _MA _MAA ILLEGAL} 8 | ## {ee_class_name} {String} {被调用方完整类名} {a.b.Class1} 9 | ## {ee_package_name} {String} {被调用方完整包名, 不会以.结束} {a.b} 10 | ## {ee_simple_class_name} {String} {被调用方简单类名} {Class1} 11 | ## {ee_method_name} {String} {被调用方方法名称, 不包括括号及方法参数} {method1} 12 | ## {ee_method_arg_num} {int} {被调用方方法参数数量} {0, 1} 13 | ## {ee_full_method} {String} {被调用方完整方法, 包括括号及方法参数} {a.b.Class1:method1(int)} 14 | -------------------------------------------------------------------------------- /src/main/resources/_javacg2_parse_method_call_switch/parse_ignore_method_call_er.av: -------------------------------------------------------------------------------- 1 | ## (作用)在 解析方法调用时 使用的表达式 2 | ## (作用)若当前配置文件中的表达式执行结果为 true,则跳过解析对应的方法调用 3 | ## (作用)若表达式执行结果为 false,或未指定表达式,则当前配置不会跳过对应的方法调用 4 | ## (范围)指定是否跳过解析方法调用,只通过调用方法判断 5 | ## (表达式使用示例文件)请参考 el_example.md 6 | ## (允许使用的变量){变量名称} {变量类型} {变量描述} {变量值示例} 7 | ## {method_call_type} {String} {方法调用类型, 参考 JavaCG2CallTypeEnum 类} {VIR INT SPE STA DYN _SPR_ACT_I _SPR_ACT_C _ACT_I _ACT_C _ITF _LM _RIR1 _RIR2 _CIC1 _CIC2 _TCID1 _TCID2 _TCWRID1 _TCWRID2 _TSR _SCC _CCS _CCS_SPE _CCS_I _CCID _ICID _MA _MAA ILLEGAL} 8 | ## {er_class_name} {String} {调用方完整类名} {a.b.Class1} 9 | ## {er_package_name} {String} {调用方完整包名, 不会以.结束} {a.b} 10 | ## {er_simple_class_name} {String} {调用方简单类名} {Class1} 11 | ## {er_method_name} {String} {调用方方法名称, 不包括括号及方法参数} {method1} 12 | ## {er_method_arg_num} {int} {调用方方法参数数量} {0, 1} 13 | ## {er_full_method} {String} {调用方完整方法, 包括括号及方法参数} {a.b.Class1:method1(int)} 14 | -------------------------------------------------------------------------------- /src/main/resources/_javacg2_parse_method_call_switch/parse_ignore_method_call_er_ee.av: -------------------------------------------------------------------------------- 1 | ## (作用)在 解析方法调用时 使用的表达式 2 | ## (作用)若当前配置文件中的表达式执行结果为 true,则跳过解析对应的方法调用 3 | ## (作用)若表达式执行结果为 false,或未指定表达式,则当前配置不会跳过对应的方法调用 4 | ## (范围)指定是否跳过解析方法调用,通过调用方法与被调用方法一起判断 5 | ## (表达式使用示例文件)请参考 el_example.md 6 | ## (允许使用的变量){变量名称} {变量类型} {变量描述} {变量值示例} 7 | ## {method_call_type} {String} {方法调用类型, 参考 JavaCG2CallTypeEnum 类} {VIR INT SPE STA DYN _SPR_ACT_I _SPR_ACT_C _ACT_I _ACT_C _ITF _LM _RIR1 _RIR2 _CIC1 _CIC2 _TCID1 _TCID2 _TCWRID1 _TCWRID2 _TSR _SCC _CCS _CCS_SPE _CCS_I _CCID _ICID _MA _MAA ILLEGAL} 8 | ## {er_class_name} {String} {调用方完整类名} {a.b.Class1} 9 | ## {er_package_name} {String} {调用方完整包名, 不会以.结束} {a.b} 10 | ## {er_simple_class_name} {String} {调用方简单类名} {Class1} 11 | ## {er_method_name} {String} {调用方方法名称, 不包括括号及方法参数} {method1} 12 | ## {er_method_arg_num} {int} {调用方方法参数数量} {0, 1} 13 | ## {er_full_method} {String} {调用方完整方法, 包括括号及方法参数} {a.b.Class1:method1(int)} 14 | ## {ee_class_name} {String} {被调用方完整类名} {a.b.Class1} 15 | ## {ee_package_name} {String} {被调用方完整包名, 不会以.结束} {a.b} 16 | ## {ee_simple_class_name} {String} {被调用方简单类名} {Class1} 17 | ## {ee_method_name} {String} {被调用方方法名称, 不包括括号及方法参数} {method1} 18 | ## {ee_method_arg_num} {int} {被调用方方法参数数量} {0, 1} 19 | ## {ee_full_method} {String} {被调用方完整方法, 包括括号及方法参数} {a.b.Class1:method1(int)} 20 | -------------------------------------------------------------------------------- /src/test/java/test/base/TestBase.java: -------------------------------------------------------------------------------- 1 | package test.base; 2 | 3 | import com.adrninistrator.javacg2.conf.JavaCG2ConfigureWrapper; 4 | import com.adrninistrator.javacg2.conf.enums.JavaCG2ConfigKeyEnum; 5 | import com.adrninistrator.javacg2.conf.enums.JavaCG2OtherConfigFileUseListEnum; 6 | import com.adrninistrator.javacg2.entry.JavaCG2Entry; 7 | import com.adrninistrator.javacg2.exceptions.JavaCG2RuntimeException; 8 | import com.adrninistrator.javacg2.util.JavaCG2FileUtil; 9 | import org.apache.commons.lang3.ArrayUtils; 10 | import org.junit.Assert; 11 | import org.junit.Before; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | 15 | import java.io.File; 16 | 17 | /** 18 | * @author adrninistrator 19 | * @date 2025/2/1 20 | * @description: 测试基类 21 | */ 22 | public abstract class TestBase { 23 | 24 | private static final Logger logger = LoggerFactory.getLogger(TestBase.class); 25 | protected String jacgTestListPath; 26 | 27 | @Before 28 | public void initTestBase() { 29 | jacgTestListPath = getJacgTestLibPath(); 30 | } 31 | 32 | /** 33 | * 获取 java-all-call-graph 项目中的 test.jar 文件路径 34 | * 35 | * @return 36 | */ 37 | protected String getJacgTestLibPath() { 38 | File parentDir = new File(".."); 39 | String jacgDirPath = JavaCG2FileUtil.getCanonicalPath(parentDir) + File.separator + "java-all-call-graph"; 40 | String jacgTestLibPath1 = jacgDirPath + "/build/test.jar"; 41 | if (new File(jacgTestLibPath1).exists()) { 42 | return jacgTestLibPath1; 43 | } 44 | String jacgTestLibPath2 = jacgDirPath + "/java-all-call-graph/build/test.jar"; 45 | if (new File(jacgTestLibPath2).exists()) { 46 | return jacgTestLibPath2; 47 | } 48 | 49 | throw new JavaCG2RuntimeException("在目录 " + jacgTestLibPath1 + " " + jacgTestLibPath2 + " 中未找到 java-all-call-graph 项目的 test.jar"); 50 | } 51 | 52 | protected JavaCG2ConfigureWrapper genJavaCG2ConfigureWrapper(String... inputFiles) { 53 | JavaCG2ConfigureWrapper javaCG2ConfigureWrapper = new JavaCG2ConfigureWrapper(); 54 | if (ArrayUtils.isEmpty(inputFiles)) { 55 | javaCG2ConfigureWrapper.setOtherConfigList(JavaCG2OtherConfigFileUseListEnum.OCFULE_JAR_DIR, jacgTestListPath); 56 | } else { 57 | javaCG2ConfigureWrapper.setOtherConfigList(JavaCG2OtherConfigFileUseListEnum.OCFULE_JAR_DIR, inputFiles); 58 | } 59 | javaCG2ConfigureWrapper.setMainConfig(JavaCG2ConfigKeyEnum.CKE_PARSE_METHOD_CALL_TYPE_VALUE, Boolean.TRUE.toString()); 60 | javaCG2ConfigureWrapper.setMainConfig(JavaCG2ConfigKeyEnum.CKE_FIRST_PARSE_INIT_METHOD_TYPE, Boolean.TRUE.toString()); 61 | javaCG2ConfigureWrapper.setMainConfig(JavaCG2ConfigKeyEnum.CKE_ANALYSE_FIELD_RELATIONSHIP, Boolean.TRUE.toString()); 62 | javaCG2ConfigureWrapper.setMainConfig(JavaCG2ConfigKeyEnum.CKE_CONTINUE_WHEN_ERROR, Boolean.FALSE.toString()); 63 | javaCG2ConfigureWrapper.setMainConfig(JavaCG2ConfigKeyEnum.CKE_LOG_METHOD_SPEND_TIME, Boolean.TRUE.toString()); 64 | // javaCG2ConfigureWrapper.setMainConfig(JavaCG2ConfigKeyEnum.CKE_OUTPUT_ROOT_PATH,""); 65 | javaCG2ConfigureWrapper.setMainConfig(JavaCG2ConfigKeyEnum.CKE_OUTPUT_FILE_EXT, ".md"); 66 | return javaCG2ConfigureWrapper; 67 | } 68 | 69 | protected void run(boolean success, String... inputFiles) { 70 | JavaCG2ConfigureWrapper javaCG2ConfigureWrapper = genJavaCG2ConfigureWrapper(inputFiles); 71 | JavaCG2Entry javaCG2Entry = new JavaCG2Entry(javaCG2ConfigureWrapper); 72 | if (success) { 73 | Assert.assertTrue(javaCG2Entry.run()); 74 | } else { 75 | Exception e = Assert.assertThrows(Exception.class, javaCG2Entry::run); 76 | logger.error("error ", e); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/test/java/test/config/TestCalleeRawActual.java: -------------------------------------------------------------------------------- 1 | package test.config; 2 | 3 | import com.adrninistrator.javacg2.common.enums.JavaCG2CalleeRawActualEnum; 4 | import com.adrninistrator.javacg2.conf.JavaCG2ConfigureWrapper; 5 | import com.adrninistrator.javacg2.conf.enums.JavaCG2ConfigKeyEnum; 6 | import com.adrninistrator.javacg2.entry.JavaCG2Entry; 7 | import org.junit.Assert; 8 | import org.junit.Test; 9 | import test.base.TestBase; 10 | 11 | /** 12 | * @author adrninistrator 13 | * @date 2025/3/24 14 | * @description: 15 | */ 16 | public class TestCalleeRawActual extends TestBase { 17 | 18 | @Test 19 | public void test() { 20 | for (JavaCG2CalleeRawActualEnum javaCG2CalleeRawActualEnumNew : JavaCG2CalleeRawActualEnum.values()) { 21 | for (JavaCG2CalleeRawActualEnum javaCG2CalleeRawActualEnumSpringBean : JavaCG2CalleeRawActualEnum.values()) { 22 | doTest(javaCG2CalleeRawActualEnumNew, javaCG2CalleeRawActualEnumSpringBean); 23 | } 24 | } 25 | } 26 | 27 | @Test 28 | public void test2() { 29 | doTest(JavaCG2CalleeRawActualEnum.CRAE_ONLY_ACTUAL, JavaCG2CalleeRawActualEnum.CRAE_ONLY_RAW); 30 | } 31 | 32 | private void doTest(JavaCG2CalleeRawActualEnum javaCG2CalleeRawActualEnumNew, JavaCG2CalleeRawActualEnum javaCG2CalleeRawActualEnumSpringBean) { 33 | JavaCG2ConfigureWrapper javaCG2ConfigureWrapper = genJavaCG2ConfigureWrapper(); 34 | String outRootPath = String.format("build/callee_raw_actual@new_%s_spb_%s", javaCG2CalleeRawActualEnumNew.getType(), javaCG2CalleeRawActualEnumSpringBean.getType()); 35 | javaCG2ConfigureWrapper.setMainConfig(JavaCG2ConfigKeyEnum.CKE_OUTPUT_ROOT_PATH, outRootPath); 36 | javaCG2ConfigureWrapper.setMainConfig(JavaCG2ConfigKeyEnum.CKE_HANDLE_CALLEE_NEW_RAW_ACTUAL, javaCG2CalleeRawActualEnumNew.getType()); 37 | javaCG2ConfigureWrapper.setMainConfig(JavaCG2ConfigKeyEnum.CKE_HANDLE_CALLEE_SPRING_BEAN_RAW_ACTUAL, javaCG2CalleeRawActualEnumSpringBean.getType()); 38 | JavaCG2Entry javaCG2Entry = new JavaCG2Entry(javaCG2ConfigureWrapper); 39 | Assert.assertTrue(javaCG2Entry.run()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/test/java/test/config/TestConfig.java: -------------------------------------------------------------------------------- 1 | package test.config; 2 | 3 | import com.adrninistrator.javacg2.conf.JavaCG2ConfigureWrapper; 4 | import com.adrninistrator.javacg2.conf.enums.JavaCG2ConfigKeyEnum; 5 | import com.adrninistrator.javacg2.entry.JavaCG2Entry; 6 | import org.junit.Assert; 7 | import org.junit.Before; 8 | import org.junit.Test; 9 | import test.base.TestBase; 10 | 11 | /** 12 | * @author adrninistrator 13 | * @date 2022/11/7 14 | * @description: 15 | */ 16 | public class TestConfig extends TestBase { 17 | 18 | private JavaCG2ConfigureWrapper javaCG2ConfigureWrapper; 19 | 20 | @Before 21 | public void init() { 22 | javaCG2ConfigureWrapper = genJavaCG2ConfigureWrapper(); 23 | } 24 | 25 | @Test 26 | public void testDefault() { 27 | javaCG2ConfigureWrapper.setMainConfig(JavaCG2ConfigKeyEnum.CKE_PARSE_METHOD_CALL_TYPE_VALUE, Boolean.TRUE.toString()); 28 | javaCG2ConfigureWrapper.setMainConfig(JavaCG2ConfigKeyEnum.CKE_FIRST_PARSE_INIT_METHOD_TYPE, Boolean.TRUE.toString()); 29 | javaCG2ConfigureWrapper.setMainConfig(JavaCG2ConfigKeyEnum.CKE_CONTINUE_WHEN_ERROR, Boolean.FALSE.toString()); 30 | javaCG2ConfigureWrapper.setMainConfig(JavaCG2ConfigKeyEnum.CKE_OUTPUT_FILE_EXT, ".md"); 31 | Assert.assertTrue(new JavaCG2Entry(javaCG2ConfigureWrapper).run()); 32 | } 33 | 34 | @Test 35 | public void testDebugPrintOn() { 36 | Assert.assertTrue(new JavaCG2Entry(javaCG2ConfigureWrapper).run()); 37 | } 38 | 39 | @Test 40 | public void testDebugPrintInFile() { 41 | Assert.assertTrue(new JavaCG2Entry(javaCG2ConfigureWrapper).run()); 42 | } 43 | 44 | @Test 45 | public void testParseMethodCallTypeValueOff() { 46 | javaCG2ConfigureWrapper.setMainConfig(JavaCG2ConfigKeyEnum.CKE_PARSE_METHOD_CALL_TYPE_VALUE, Boolean.FALSE.toString()); 47 | Assert.assertTrue(new JavaCG2Entry(javaCG2ConfigureWrapper).run()); 48 | } 49 | 50 | @Test 51 | public void testMultiTimes() { 52 | JavaCG2Entry javaCG2Entry = new JavaCG2Entry(javaCG2ConfigureWrapper); 53 | Assert.assertTrue(javaCG2Entry.run()); 54 | Assert.assertFalse(javaCG2Entry.run()); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/test/java/test/other/TestMd.java: -------------------------------------------------------------------------------- 1 | package test.other; 2 | 3 | import com.adrninistrator.javacg2.markdown.enums.MDCodeBlockTypeEnum; 4 | import com.adrninistrator.javacg2.markdown.writer.MarkdownWriter; 5 | import org.junit.Test; 6 | 7 | import java.io.IOException; 8 | 9 | /** 10 | * @author adrninistrator 11 | * @date 2022/11/27 12 | * @description: 13 | */ 14 | public class TestMd { 15 | @Test 16 | public void test() { 17 | try (MarkdownWriter markdownWriter1 = new MarkdownWriter("build/test-1.md", false); 18 | MarkdownWriter markdownWriter2 = new MarkdownWriter("build/test-2.md", true)) { 19 | doTest(markdownWriter1); 20 | doTest(markdownWriter2); 21 | } catch (Exception e) { 22 | e.printStackTrace(); 23 | } 24 | } 25 | 26 | private void doTest(MarkdownWriter markdownWriter) throws IOException { 27 | markdownWriter.addTitle(1, "@"); 28 | markdownWriter.addTitle(1, "@"); 29 | 30 | markdownWriter.addCodeBlock(MDCodeBlockTypeEnum.MDCBTE_SQL); 31 | markdownWriter.addLine("select"); 32 | markdownWriter.addCodeBlock(); 33 | 34 | markdownWriter.addTitle(2, "@"); 35 | 36 | markdownWriter.addList("1"); 37 | markdownWriter.addList("2"); 38 | markdownWriter.addList("3"); 39 | 40 | markdownWriter.addCodeBlock(); 41 | markdownWriter.addLine("test1"); 42 | markdownWriter.addLine("test2"); 43 | markdownWriter.addCodeBlock(); 44 | 45 | markdownWriter.addTitle(2, "@"); 46 | 47 | markdownWriter.addLineWithNewLine("@"); 48 | markdownWriter.addLineWithNewLine("@"); 49 | markdownWriter.addLineWithNewLine("@"); 50 | 51 | markdownWriter.addTitle(2, "@"); 52 | markdownWriter.addTitle(2, "@"); 53 | markdownWriter.addTitle(3, "@"); 54 | markdownWriter.addTitle(3, "@"); 55 | markdownWriter.addTitle(4, "@"); 56 | markdownWriter.addTitle(5, "@"); 57 | markdownWriter.addTitle(2, "@"); 58 | markdownWriter.addTitle(1, "@"); 59 | markdownWriter.addTitle(2, "@"); 60 | markdownWriter.addTitle(3, "@"); 61 | markdownWriter.addTitle(4, "@"); 62 | markdownWriter.addTitle(5, "@"); 63 | markdownWriter.addTitle(1, "@"); 64 | markdownWriter.addTitle(2, "@"); 65 | markdownWriter.addTitle(3, "@"); 66 | markdownWriter.addTitle(4, "@"); 67 | markdownWriter.addTitle(3, "@"); 68 | markdownWriter.addTitle(2, "@"); 69 | markdownWriter.addTitle(1, "@"); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/test/java/test/parse/TestNotAllowed.java: -------------------------------------------------------------------------------- 1 | package test.parse; 2 | 3 | import org.junit.Test; 4 | import test.base.TestBase; 5 | 6 | /** 7 | * @author adrninistrator 8 | * @date 2025/2/3 9 | * @description: 10 | */ 11 | public class TestNotAllowed extends TestBase { 12 | 13 | @Test 14 | public void testSingleClass() { 15 | run(false, "out/test/classes/test/base/TestBase.class"); 16 | } 17 | 18 | @Test 19 | public void testMultiClass() { 20 | run(false, 21 | "out/test/classes/test/base/TestBase.class", 22 | "out/test/classes/test/simple/TestSimple.class" 23 | ); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/test/java/test/parse/TestParse.java: -------------------------------------------------------------------------------- 1 | package test.parse; 2 | 3 | import com.adrninistrator.javacg2.conf.JavaCG2ConfigureWrapper; 4 | import com.adrninistrator.javacg2.conf.enums.JavaCG2ConfigKeyEnum; 5 | import com.adrninistrator.javacg2.entry.JavaCG2Entry; 6 | import org.junit.Assert; 7 | import org.junit.Test; 8 | import test.base.TestBase; 9 | 10 | /** 11 | * @author adrninistrator 12 | * @date 2025/2/2 13 | * @description: 14 | */ 15 | public class TestParse extends TestBase { 16 | 17 | // 正常解析 18 | @Test 19 | public void testParse() { 20 | run(true); 21 | } 22 | 23 | // 不解析被调用对象和参数可能的类型与值 24 | @Test 25 | public void testParseNoMCTypeValue() { 26 | JavaCG2ConfigureWrapper javaCG2ConfigureWrapper = genJavaCG2ConfigureWrapper(); 27 | javaCG2ConfigureWrapper.setMainConfig(JavaCG2ConfigKeyEnum.CKE_PARSE_METHOD_CALL_TYPE_VALUE, Boolean.FALSE.toString()); 28 | JavaCG2Entry javaCG2Entry = new JavaCG2Entry(javaCG2ConfigureWrapper); 29 | Assert.assertTrue(javaCG2Entry.run()); 30 | } 31 | 32 | /* 33 | 需要先执行 gradlew gen_run_jar gen_jar_in_jar 命令生成对应jar文件 34 | */ 35 | @Test 36 | public void testJarInJar() { 37 | JavaCG2ConfigureWrapper javaCG2ConfigureWrapper = genJavaCG2ConfigureWrapper("build/jar_output_dir.jar"); 38 | Assert.assertTrue(new JavaCG2Entry(javaCG2ConfigureWrapper).run()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/test/parse/TestParseElFixed.java: -------------------------------------------------------------------------------- 1 | package test.parse; 2 | 3 | import com.adrninistrator.javacg2.conf.JavaCG2ConfigureWrapper; 4 | import com.adrninistrator.javacg2.conf.enums.JavaCG2ConfigKeyEnum; 5 | import com.adrninistrator.javacg2.el.enums.JavaCG2ElConfigEnum; 6 | import com.adrninistrator.javacg2.entry.JavaCG2Entry; 7 | import org.junit.Assert; 8 | import org.junit.Test; 9 | import test.base.TestBase; 10 | 11 | /** 12 | * @author adrninistrator 13 | * @date 2025/3/16 14 | * @description: 15 | */ 16 | public class TestParseElFixed extends TestBase { 17 | 18 | // 所有表达式均配置为返回false 19 | @Test 20 | public void testElFalse() { 21 | JavaCG2ConfigureWrapper javaCG2ConfigureWrapper = genJavaCG2ConfigureWrapper(); 22 | for (JavaCG2ElConfigEnum javaCG2ElConfigEnum : JavaCG2ElConfigEnum.values()) { 23 | javaCG2ConfigureWrapper.setElConfigFixedFalse(javaCG2ElConfigEnum); 24 | } 25 | JavaCG2Entry javaCG2Entry = new JavaCG2Entry(javaCG2ConfigureWrapper); 26 | Assert.assertTrue(javaCG2Entry.run()); 27 | } 28 | 29 | // 所有表达式均配置为返回true 30 | @Test 31 | public void testElTrue() { 32 | JavaCG2ConfigureWrapper javaCG2ConfigureWrapper = genJavaCG2ConfigureWrapper(); 33 | javaCG2ConfigureWrapper.setMainConfig(JavaCG2ConfigKeyEnum.CKE_EL_DEBUG_MODE, Boolean.TRUE.toString()); 34 | for (JavaCG2ElConfigEnum javaCG2ElConfigEnum : JavaCG2ElConfigEnum.values()) { 35 | javaCG2ConfigureWrapper.setElConfigFixedTrue(javaCG2ElConfigEnum); 36 | } 37 | JavaCG2Entry javaCG2Entry = new JavaCG2Entry(javaCG2ConfigureWrapper); 38 | Assert.assertTrue(javaCG2Entry.run()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/test/parse/TestParseElMergeFile.java: -------------------------------------------------------------------------------- 1 | package test.parse; 2 | 3 | import com.adrninistrator.javacg2.conf.JavaCG2ConfigureWrapper; 4 | import com.adrninistrator.javacg2.conf.enums.JavaCG2ConfigKeyEnum; 5 | import com.adrninistrator.javacg2.el.enums.JavaCG2ElAllowedVariableEnum; 6 | import com.adrninistrator.javacg2.el.enums.JavaCG2ElConfigEnum; 7 | import com.adrninistrator.javacg2.entry.JavaCG2Entry; 8 | import org.junit.Assert; 9 | import org.junit.Test; 10 | import test.base.TestBase; 11 | 12 | /** 13 | * @author adrninistrator 14 | * @date 2025/3/16 15 | * @description: 16 | */ 17 | public class TestParseElMergeFile extends TestBase { 18 | 19 | /* 20 | 忽略lib目录中的jar文件 21 | 需要先执行 gradlew gen_run_jar 命令生成对应目录及文件 22 | */ 23 | @Test 24 | public void testMergeFileIgnoreLibDir() { 25 | JavaCG2ConfigureWrapper javaCG2ConfigureWrapper = genJavaCG2ConfigureWrapper("jar_output_dir"); 26 | javaCG2ConfigureWrapper.setMainConfig(JavaCG2ConfigKeyEnum.CKE_EL_DEBUG_MODE, Boolean.TRUE.toString()); 27 | javaCG2ConfigureWrapper.setElConfigText(JavaCG2ElConfigEnum.ECE_MERGE_FILE_IGNORE_JAR_IN_DIR, 28 | "string.endsWith(" + JavaCG2ElAllowedVariableEnum.EAVE_MF_ABSOLUTE_FILE_DIR_PATH_IN_DIR.getVariableName() + ", '/lib')" 29 | ); 30 | JavaCG2Entry javaCG2Entry = new JavaCG2Entry(javaCG2ConfigureWrapper); 31 | Assert.assertTrue(javaCG2Entry.run()); 32 | } 33 | 34 | /* 35 | 忽略jar/war文件的lib目录中的jar文件 36 | 需要先执行 gradlew gen_run_jar gen_jar_in_jar 命令生成对应jar文件 37 | */ 38 | @Test 39 | public void testMergeFileIgnoreJarLibDir() { 40 | JavaCG2ConfigureWrapper javaCG2ConfigureWrapper = genJavaCG2ConfigureWrapper("build/jar_output_dir.jar"); 41 | javaCG2ConfigureWrapper.setMainConfig(JavaCG2ConfigKeyEnum.CKE_EL_DEBUG_MODE, Boolean.TRUE.toString()); 42 | javaCG2ConfigureWrapper.setElConfigText(JavaCG2ElConfigEnum.ECE_MERGE_FILE_IGNORE_JAR_IN_JAR_WAR, 43 | JavaCG2ElAllowedVariableEnum.EAVE_MF_FILE_DIR_PATH_IN_JAR_WAR.getVariableName() + " == 'lib'" 44 | ); 45 | JavaCG2Entry javaCG2Entry = new JavaCG2Entry(javaCG2ConfigureWrapper); 46 | Assert.assertTrue(javaCG2Entry.run()); 47 | } 48 | 49 | /* 50 | 忽略class文件包名不包含com.adrninistrator、text的jar文件 51 | 需要先执行 gradlew gen_run_jar gen_jar_in_jar 命令生成对应jar文件 52 | */ 53 | @Test 54 | public void testMergeFileIgnoreByJarClassDirPrefix1() { 55 | JavaCG2ConfigureWrapper javaCG2ConfigureWrapper = genJavaCG2ConfigureWrapper("build/jar_output_dir.jar"); 56 | javaCG2ConfigureWrapper.setMainConfig(JavaCG2ConfigKeyEnum.CKE_EL_DEBUG_MODE, Boolean.TRUE.toString()); 57 | javaCG2ConfigureWrapper.setElConfigText(JavaCG2ElConfigEnum.ECE_MERGE_FILE_IGNORE_JAR_WAR_BY_CLASS_DIR_PREFIX, 58 | "!include(" + JavaCG2ElAllowedVariableEnum.EAVE_MF_CLASS_DIR_PREFIX_LEVEL.getVariableName() + "2, 'com/adrninistrator')" + 59 | " && !include(" + JavaCG2ElAllowedVariableEnum.EAVE_MF_CLASS_DIR_PREFIX_LEVEL.getVariableName() + "1, 'test')" 60 | ); 61 | javaCG2ConfigureWrapper.setElConfigText(JavaCG2ElConfigEnum.ECE_MERGE_FILE_IGNORE_CLASS_IN_JAR_WAR, 62 | "string.startsWith(" + JavaCG2ElAllowedVariableEnum.EAVE_MF_CLASS_FILE_PATH_IN_JAR_WAR.getVariableName() + ", 'test/')" 63 | ); 64 | JavaCG2Entry javaCG2Entry = new JavaCG2Entry(javaCG2ConfigureWrapper); 65 | Assert.assertTrue(javaCG2Entry.run()); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/test/java/test/parse/TestParseElMethodCall.java: -------------------------------------------------------------------------------- 1 | package test.parse; 2 | 3 | import com.adrninistrator.javacg2.conf.JavaCG2ConfigureWrapper; 4 | import com.adrninistrator.javacg2.el.enums.JavaCG2ElAllowedVariableEnum; 5 | import com.adrninistrator.javacg2.el.enums.JavaCG2ElConfigEnum; 6 | import com.adrninistrator.javacg2.entry.JavaCG2Entry; 7 | import org.junit.Assert; 8 | import org.junit.Test; 9 | import test.base.TestBase; 10 | 11 | /** 12 | * @author adrninistrator 13 | * @date 2025/3/16 14 | * @description: 15 | */ 16 | public class TestParseElMethodCall extends TestBase { 17 | 18 | // 处理方法调用时仅处理指定包下的调用类与被调用类 19 | @Test 20 | public void testParseMCEREE1() { 21 | JavaCG2ConfigureWrapper javaCG2ConfigureWrapper = genJavaCG2ConfigureWrapper(); 22 | javaCG2ConfigureWrapper.setElConfigText(JavaCG2ElConfigEnum.ECE_PARSE_IGNORE_METHOD_CALL_ER_EE, 23 | "!string.startsWith(" + JavaCG2ElAllowedVariableEnum.EAVE_MC_ER_PACKAGE_NAME.getVariableName() + ", 'test.callgraph.array')" + 24 | " && !string.startsWith(" + JavaCG2ElAllowedVariableEnum.EAVE_MC_EE_PACKAGE_NAME.getVariableName() + ", 'test.callgraph.array')" 25 | ); 26 | JavaCG2Entry javaCG2Entry = new JavaCG2Entry(javaCG2ConfigureWrapper); 27 | Assert.assertTrue(javaCG2Entry.run()); 28 | } 29 | 30 | // 处理方法调用时仅处理指定包下的调用类与被调用类 31 | @Test 32 | public void testParseMCEREE2() { 33 | JavaCG2ConfigureWrapper javaCG2ConfigureWrapper = genJavaCG2ConfigureWrapper(); 34 | javaCG2ConfigureWrapper.setElConfigText(JavaCG2ElConfigEnum.ECE_PARSE_IGNORE_METHOD_CALL_ER_EE, 35 | "!string.startsWith(" + JavaCG2ElAllowedVariableEnum.EAVE_MC_ER_PACKAGE_NAME.getVariableName() + ", 'test.callgraph')" + 36 | " || !string.startsWith(" + JavaCG2ElAllowedVariableEnum.EAVE_MC_EE_PACKAGE_NAME.getVariableName() + ", 'test.callgraph')" 37 | ); 38 | JavaCG2Entry javaCG2Entry = new JavaCG2Entry(javaCG2ConfigureWrapper); 39 | Assert.assertTrue(javaCG2Entry.run()); 40 | } 41 | 42 | // 处理方法调用时仅处理指定包下的调用类 43 | @Test 44 | public void testParseMCER1() { 45 | JavaCG2ConfigureWrapper javaCG2ConfigureWrapper = genJavaCG2ConfigureWrapper(); 46 | javaCG2ConfigureWrapper.setElConfigText(JavaCG2ElConfigEnum.ECE_PARSE_IGNORE_METHOD_CALL_ER_EE, 47 | "!string.startsWith(" + JavaCG2ElAllowedVariableEnum.EAVE_MC_ER_PACKAGE_NAME.getVariableName() + ", 'test.callgraph.array')"); 48 | JavaCG2Entry javaCG2Entry = new JavaCG2Entry(javaCG2ConfigureWrapper); 49 | Assert.assertTrue(javaCG2Entry.run()); 50 | } 51 | 52 | // 处理方法调用时仅处理指定包下的被调用类 53 | @Test 54 | public void testParseMCEE1() { 55 | JavaCG2ConfigureWrapper javaCG2ConfigureWrapper = genJavaCG2ConfigureWrapper(); 56 | javaCG2ConfigureWrapper.setElConfigText(JavaCG2ElConfigEnum.ECE_PARSE_IGNORE_METHOD_CALL_ER_EE, 57 | "!string.startsWith(" + JavaCG2ElAllowedVariableEnum.EAVE_MC_EE_PACKAGE_NAME.getVariableName() + ", 'test.callgraph.array')" 58 | ); 59 | JavaCG2Entry javaCG2Entry = new JavaCG2Entry(javaCG2ConfigureWrapper); 60 | Assert.assertTrue(javaCG2Entry.run()); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/test/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/test/resources/log4j2_file.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /unittest.gradle: -------------------------------------------------------------------------------- 1 | test { 2 | doFirst { 3 | exclude('test/runlocal') 4 | minHeapSize = "256m" 5 | maxHeapSize = "1g" 6 | 7 | maxParallelForks = 1 8 | 9 | forkEvery = 1 10 | 11 | jvmArgs "-XX:MetaspaceSize=64m", "-XX:MaxMetaspaceSize=256m" 12 | 13 | testLogging { 14 | events "PASSED", "STARTED", "FAILED", "SKIPPED" 15 | } 16 | } 17 | } 18 | 19 | // 生成包含jar文件的jar文件 20 | tasks.register('gen_jar_in_jar', Jar) { 21 | archiveFileName = 'jar_output_dir.jar' 22 | destinationDirectory = file("${buildDir}") 23 | 24 | from(sourceSets.test.output) { 25 | include 'test/**' 26 | into '/' 27 | } 28 | 29 | from(fileTree('jar_output_dir/jar')) { 30 | into 'jar' 31 | } 32 | 33 | from(fileTree('jar_output_dir/lib')) { 34 | into 'lib' 35 | } 36 | } --------------------------------------------------------------------------------