├── .gitignore ├── LICENSE ├── README.md ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src ├── main ├── java │ └── com │ │ └── github │ │ └── setial │ │ └── intellijjavadocs │ │ ├── action │ │ ├── BaseAction.java │ │ ├── JavaDocGenerateAction.java │ │ ├── JavaDocHandler.java │ │ ├── JavaDocRemoveAction.java │ │ ├── JavaDocsGenerateAction.java │ │ └── JavaDocsRemoveAction.java │ │ ├── configuration │ │ ├── JavaDocConfiguration.java │ │ └── impl │ │ │ └── JavaDocConfigurationImpl.java │ │ ├── exception │ │ ├── FileNotValidException.java │ │ ├── NotFoundElementException.java │ │ ├── SetupTemplateException.java │ │ └── TemplateNotFoundException.java │ │ ├── generator │ │ ├── JavaDocGenerator.java │ │ └── impl │ │ │ ├── AbstractJavaDocGenerator.java │ │ │ ├── ClassJavaDocGenerator.java │ │ │ ├── FieldJavaDocGenerator.java │ │ │ └── MethodJavaDocGenerator.java │ │ ├── model │ │ ├── JavaDoc.java │ │ ├── JavaDocElements.java │ │ ├── JavaDocTag.java │ │ └── settings │ │ │ ├── GeneralSettings.java │ │ │ ├── JavaDocSettings.java │ │ │ ├── Level.java │ │ │ ├── Mode.java │ │ │ ├── TemplateSettings.java │ │ │ └── Visibility.java │ │ ├── operation │ │ ├── JavaDocWriter.java │ │ └── impl │ │ │ └── JavaDocWriterImpl.java │ │ ├── template │ │ ├── DocTemplateManager.java │ │ ├── DocTemplateProcessor.java │ │ └── impl │ │ │ ├── DocTemplateManagerImpl.java │ │ │ └── DocTemplateProcessorImpl.java │ │ ├── transformation │ │ └── JavaDocBuilder.java │ │ ├── ui │ │ ├── component │ │ │ ├── TemplateConfigDialog.java │ │ │ └── TemplatesTable.java │ │ └── settings │ │ │ ├── ConfigPanel.java │ │ │ ├── ConfigPanelGUI.form │ │ │ └── ConfigPanelGUI.java │ │ └── utils │ │ ├── JavaDocUtils.java │ │ └── XmlUtils.java └── resources │ ├── META-INF │ └── plugin.xml │ ├── messages.properties │ └── templates.xml └── test └── java └── com └── github └── setial └── intellijjavadocs └── generator └── impl └── MethodJavaDocGeneratorTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | .idea 3 | .gradle 4 | out 5 | build 6 | intellij-community 7 | .intellijPlatform 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright 2015 Sergey Timofiychuk 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | intellij-javadocs 2 | ============ 3 | 4 | Intellij idea javadocs generator plugin. 5 | 6 | Home page: https://tsergey.github.io/intellij-javadocs/ 7 | 8 | Wiki: https://github.com/tsergey/intellij-javadocs/wiki 9 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | import org.jetbrains.intellij.platform.gradle.TestFrameworkType 2 | 3 | plugins { 4 | id("idea") 5 | id("org.jetbrains.intellij.platform") version "2.3.0" 6 | } 7 | group "com.github.setial" 8 | 9 | java { 10 | sourceCompatibility = JavaVersion.VERSION_21 11 | } 12 | 13 | repositories { 14 | mavenCentral() 15 | intellijPlatform { 16 | defaultRepositories() 17 | } 18 | dependencies { 19 | implementation 'commons-beanutils:commons-beanutils:1.9.4' 20 | implementation 'org.apache.commons:commons-collections4:4.4' 21 | implementation 'org.apache.commons:commons-lang3:3.9' 22 | implementation 'commons-logging:commons-logging:1.2' 23 | implementation 'org.freemarker:freemarker:2.3.32' 24 | testImplementation group: 'junit', name: 'junit', version: '4.13.1' 25 | 26 | intellijPlatform { 27 | intellijIdeaCommunity("2024.3.4") 28 | 29 | bundledPlugin("com.intellij.java") 30 | 31 | testFramework(TestFrameworkType.Plugin.Java.INSTANCE) 32 | } 33 | } 34 | } 35 | 36 | 37 | intellijPlatform { 38 | pluginConfiguration { 39 | id = "com.github.setial" 40 | name = "JavaDoc" 41 | version = "4.1.4" 42 | vendor { 43 | email = "s.timofiychuk@gmail.com" 44 | url = "https://tsergey.github.io/intellij-javadocs/" 45 | name = "Sergey Timofiychuk" 46 | } 47 | ideaVersion { 48 | untilBuild = provider { null } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TSergey/intellij-javadocs/3d582979026e2d817e1a216163a73452a57ff4d6/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jan 31 16:29:09 EET 2020 2 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-all.zip 3 | distributionBase=GRADLE_USER_HOME 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS='"-Xmx64m"' 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS="-Xmx64m" 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'intellij-javadocs' 2 | 3 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/action/BaseAction.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.action; 2 | 3 | import com.intellij.codeInsight.CodeInsightActionHandler; 4 | import com.intellij.codeInsight.generation.actions.BaseGenerateAction; 5 | import com.intellij.psi.PsiClass; 6 | 7 | /** 8 | * The type Base action. 9 | * 10 | * @author Sergey Timofiychuk 11 | */ 12 | public class BaseAction extends BaseGenerateAction { 13 | 14 | /** 15 | * Instantiates a new Base action. 16 | * 17 | * @param handler the handler 18 | */ 19 | public BaseAction(CodeInsightActionHandler handler) { 20 | super(handler); 21 | } 22 | 23 | @Override 24 | protected boolean isValidForClass(final PsiClass targetClass) { 25 | return true; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/action/JavaDocGenerateAction.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.action; 2 | 3 | import com.github.setial.intellijjavadocs.exception.SetupTemplateException; 4 | import com.github.setial.intellijjavadocs.exception.TemplateNotFoundException; 5 | import com.github.setial.intellijjavadocs.generator.JavaDocGenerator; 6 | import com.github.setial.intellijjavadocs.generator.impl.ClassJavaDocGenerator; 7 | import com.github.setial.intellijjavadocs.generator.impl.FieldJavaDocGenerator; 8 | import com.github.setial.intellijjavadocs.generator.impl.MethodJavaDocGenerator; 9 | import com.github.setial.intellijjavadocs.operation.JavaDocWriter; 10 | import com.intellij.codeInsight.CodeInsightActionHandler; 11 | import com.intellij.ide.highlighter.JavaFileType; 12 | import com.intellij.openapi.actionSystem.AnActionEvent; 13 | import com.intellij.openapi.actionSystem.CommonDataKeys; 14 | import com.intellij.openapi.actionSystem.DataContext; 15 | import com.intellij.openapi.actionSystem.Presentation; 16 | import com.intellij.openapi.application.ApplicationManager; 17 | import com.intellij.openapi.diagnostic.Logger; 18 | import com.intellij.openapi.editor.Editor; 19 | import com.intellij.openapi.project.DumbService; 20 | import com.intellij.openapi.project.Project; 21 | import com.intellij.openapi.ui.Messages; 22 | import com.intellij.psi.PsiClass; 23 | import com.intellij.psi.PsiDocumentManager; 24 | import com.intellij.psi.PsiElement; 25 | import com.intellij.psi.PsiField; 26 | import com.intellij.psi.PsiFile; 27 | import com.intellij.psi.PsiMethod; 28 | import com.intellij.psi.javadoc.PsiDocComment; 29 | import com.intellij.psi.util.PsiTreeUtil; 30 | import com.intellij.psi.util.PsiUtilCore; 31 | import org.jetbrains.annotations.NotNull; 32 | import org.jetbrains.annotations.Nullable; 33 | 34 | import java.text.MessageFormat; 35 | import java.util.LinkedList; 36 | import java.util.List; 37 | 38 | import static com.github.setial.intellijjavadocs.configuration.impl.JavaDocConfigurationImpl.JAVADOCS_PLUGIN_TITLE_MSG; 39 | 40 | /** 41 | * The type Java doc generate action. 42 | * 43 | * @author Sergey Timofiychuk 44 | */ 45 | public class JavaDocGenerateAction extends BaseAction { 46 | 47 | private static final Logger LOGGER = Logger.getInstance(JavaDocGenerateAction.class); 48 | 49 | private JavaDocWriter writer; 50 | 51 | /** 52 | * Instantiates a new Java doc generate action. 53 | */ 54 | public JavaDocGenerateAction() { 55 | this(new JavaDocHandler()); 56 | } 57 | 58 | /** 59 | * Instantiates a new Java doc generate action. 60 | * 61 | * @param handler the handler 62 | */ 63 | public JavaDocGenerateAction(CodeInsightActionHandler handler) { 64 | super(handler); 65 | writer = ApplicationManager.getApplication().getService(JavaDocWriter.class); 66 | } 67 | 68 | /** 69 | * Action performed. 70 | * 71 | * @param e the Event 72 | */ 73 | @Override 74 | public void actionPerformed(AnActionEvent e) { 75 | DumbService dumbService = DumbService.getInstance(e.getProject()); 76 | if (dumbService.isDumb()) { 77 | dumbService.showDumbModeNotification("Javadocs plugin is not available during indexing"); 78 | return; 79 | } 80 | 81 | Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext()); 82 | if (editor == null) { 83 | LOGGER.error("Cannot get com.intellij.openapi.editor.Editor"); 84 | Messages.showErrorDialog("Javadocs plugin is not available", JAVADOCS_PLUGIN_TITLE_MSG); 85 | return; 86 | } 87 | int startPosition = editor.getSelectionModel().getSelectionStart(); 88 | int endPosition = editor.getSelectionModel().getSelectionEnd(); 89 | PsiFile file = CommonDataKeys.PSI_FILE.getData(e.getDataContext()); 90 | if (file == null) { 91 | LOGGER.error("Cannot get com.intellij.psi.PsiFile"); 92 | Messages.showErrorDialog("Javadocs plugin is not available", JAVADOCS_PLUGIN_TITLE_MSG); 93 | return; 94 | } 95 | List elements = new LinkedList<>(); 96 | PsiElement firstElement = getJavaElement(PsiUtilCore.getElementAtOffset(file, startPosition)); 97 | if (firstElement != null) { 98 | PsiElement element = firstElement; 99 | do { 100 | if (isAllowedElementType(element)) { 101 | elements.add(element); 102 | } 103 | element = element.getNextSibling(); 104 | if (element == null) { 105 | break; 106 | } 107 | } while (isElementInSelection(element, startPosition, endPosition)); 108 | } 109 | for (PsiElement element : elements) { 110 | processElement(element); 111 | } 112 | } 113 | 114 | @Override 115 | public void update(AnActionEvent event) { 116 | Presentation presentation = event.getPresentation(); 117 | presentation.setEnabled(false); 118 | DataContext dataContext = event.getDataContext(); 119 | Project project = CommonDataKeys.PROJECT.getData(dataContext); 120 | if (project == null) { 121 | presentation.setEnabled(false); 122 | return; 123 | } 124 | Editor editor = CommonDataKeys.EDITOR.getData(dataContext); 125 | 126 | if (editor != null) { 127 | PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); 128 | if (file != null && JavaFileType.INSTANCE.equals(file.getFileType())) { 129 | presentation.setEnabled(true); 130 | return; 131 | } else if (file != null && file.isDirectory()) { 132 | presentation.setEnabled(true); 133 | return; 134 | } 135 | } 136 | } 137 | 138 | /** 139 | * Process element. 140 | * 141 | * @param element the Element 142 | */ 143 | protected void processElement(@NotNull PsiElement element) { 144 | JavaDocGenerator generator = getGenerator(element); 145 | if (generator != null) { 146 | try { 147 | @SuppressWarnings("unchecked") 148 | PsiDocComment javaDoc = generator.generate(element); 149 | if (javaDoc != null) { 150 | writer.write(javaDoc, element); 151 | } 152 | } catch (TemplateNotFoundException e) { 153 | LOGGER.warn(e); 154 | String message = "Can not find suitable template for the element:\n{0}"; 155 | Messages.showWarningDialog(MessageFormat.format(message, e.getMessage()), JAVADOCS_PLUGIN_TITLE_MSG); 156 | } catch (SetupTemplateException e) { 157 | LOGGER.warn(e); 158 | String message = "Can not setup provided template:\n{0}"; 159 | Messages.showWarningDialog(MessageFormat.format(message, e.getMessage()), JAVADOCS_PLUGIN_TITLE_MSG); 160 | } 161 | } 162 | } 163 | 164 | /** 165 | * Gets the generator. 166 | * 167 | * @param element the Element 168 | * @return the Generator 169 | */ 170 | @Nullable 171 | protected JavaDocGenerator getGenerator(@NotNull PsiElement element) { 172 | Project project = element.getProject(); 173 | JavaDocGenerator generator = null; 174 | if (PsiClass.class.isAssignableFrom(element.getClass())) { 175 | generator = new ClassJavaDocGenerator(project); 176 | } else if (PsiMethod.class.isAssignableFrom(element.getClass())) { 177 | generator = new MethodJavaDocGenerator(project); 178 | } else if (PsiField.class.isAssignableFrom(element.getClass())) { 179 | generator = new FieldJavaDocGenerator(project); 180 | } 181 | return generator; 182 | } 183 | 184 | /** 185 | * Gets the java element. 186 | * 187 | * @param element the Element 188 | * @return the Java element 189 | */ 190 | @NotNull 191 | private PsiElement getJavaElement(@NotNull PsiElement element) { 192 | PsiElement result = element; 193 | PsiField field = PsiTreeUtil.getParentOfType(element, PsiField.class); 194 | PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class); 195 | PsiClass clazz = PsiTreeUtil.getParentOfType(element, PsiClass.class); 196 | if (field != null) { 197 | result = field; 198 | } else if (method != null) { 199 | result = method; 200 | } else if (clazz != null) { 201 | result = clazz; 202 | } 203 | return result; 204 | } 205 | 206 | private boolean isElementInSelection(@NotNull PsiElement element, int startPosition, int endPosition) { 207 | boolean result = false; 208 | int elementTextOffset = element.getTextRange().getStartOffset(); 209 | if (elementTextOffset >= startPosition && 210 | elementTextOffset <= endPosition) { 211 | result = true; 212 | } 213 | return result; 214 | } 215 | 216 | private boolean isAllowedElementType(@NotNull PsiElement element) { 217 | boolean result = false; 218 | if (element instanceof PsiClass || 219 | element instanceof PsiField || 220 | element instanceof PsiMethod) { 221 | result = true; 222 | } 223 | return result; 224 | } 225 | 226 | } 227 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/action/JavaDocHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.action; 2 | 3 | import com.intellij.codeInsight.generation.ClassMember; 4 | import com.intellij.codeInsight.generation.GenerateMembersHandlerBase; 5 | import com.intellij.codeInsight.generation.GenerationInfo; 6 | import com.intellij.psi.PsiClass; 7 | import com.intellij.util.IncorrectOperationException; 8 | 9 | /** 10 | * The type Java doc handler. 11 | * 12 | * @author Sergey Timofiychuk 13 | */ 14 | public class JavaDocHandler extends GenerateMembersHandlerBase { 15 | 16 | /** 17 | * Instantiates a new Java docs generate handler. 18 | */ 19 | public JavaDocHandler() { 20 | super(""); 21 | } 22 | 23 | @Override 24 | protected ClassMember[] getAllOriginalMembers(PsiClass aClass) { 25 | return new ClassMember[0]; 26 | } 27 | 28 | @Override 29 | protected GenerationInfo[] generateMemberPrototypes(PsiClass aClass, ClassMember originalMember) throws IncorrectOperationException { 30 | return new GenerationInfo[0]; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/action/JavaDocRemoveAction.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.action; 2 | 3 | import com.github.setial.intellijjavadocs.operation.JavaDocWriter; 4 | import com.intellij.codeInsight.CodeInsightActionHandler; 5 | import com.intellij.openapi.application.ApplicationManager; 6 | import com.intellij.psi.PsiElement; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | /** 10 | * The type Java doc remove action. 11 | * 12 | * @author Sergey Timofiychuk 13 | */ 14 | public class JavaDocRemoveAction extends JavaDocGenerateAction { 15 | 16 | private JavaDocWriter writer; 17 | 18 | /** 19 | * Instantiates a new Java doc remove action. 20 | */ 21 | public JavaDocRemoveAction() { 22 | this(new JavaDocHandler()); 23 | writer = ApplicationManager.getApplication().getService(JavaDocWriter.class); 24 | } 25 | 26 | /** 27 | * Instantiates a new Java doc remove action. 28 | * 29 | * @param handler the handler 30 | */ 31 | public JavaDocRemoveAction(CodeInsightActionHandler handler) { 32 | super(handler); 33 | } 34 | 35 | @Override 36 | protected void processElement(@NotNull PsiElement element) { 37 | writer.remove(element); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/action/JavaDocsGenerateAction.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.action; 2 | 3 | import com.intellij.ide.highlighter.JavaFileType; 4 | import com.intellij.openapi.actionSystem.AnActionEvent; 5 | import com.intellij.openapi.actionSystem.CommonDataKeys; 6 | import com.intellij.openapi.actionSystem.DataContext; 7 | import com.intellij.openapi.actionSystem.Presentation; 8 | import com.intellij.openapi.diagnostic.Logger; 9 | import com.intellij.openapi.editor.Editor; 10 | import com.intellij.openapi.project.DumbAware; 11 | import com.intellij.openapi.project.DumbService; 12 | import com.intellij.openapi.project.Project; 13 | import com.intellij.openapi.ui.Messages; 14 | import com.intellij.openapi.vfs.VirtualFile; 15 | import com.intellij.psi.*; 16 | import com.intellij.psi.util.PsiTreeUtil; 17 | 18 | import java.util.LinkedList; 19 | import java.util.List; 20 | 21 | import static com.github.setial.intellijjavadocs.configuration.impl.JavaDocConfigurationImpl.JAVADOCS_PLUGIN_TITLE_MSG; 22 | 23 | /** 24 | * The type Java docs generate action. 25 | * 26 | * @author Sergey Timofiychuk 27 | */ 28 | public class JavaDocsGenerateAction extends JavaDocGenerateAction implements DumbAware { 29 | 30 | private static final Logger LOGGER = Logger.getInstance(JavaDocsGenerateAction.class); 31 | 32 | /** 33 | * Instantiates a new Java docs generate action. 34 | */ 35 | public JavaDocsGenerateAction() { 36 | super(new JavaDocHandler()); 37 | } 38 | 39 | /** 40 | * Action performed. 41 | * 42 | * @param e the Event 43 | */ 44 | @Override 45 | public void actionPerformed(AnActionEvent e) { 46 | DumbService dumbService = DumbService.getInstance(e.getProject()); 47 | if (dumbService.isDumb()) { 48 | dumbService.showDumbModeNotification("Javadocs plugin is not available during indexing"); 49 | return; 50 | } 51 | 52 | final PsiFile file = CommonDataKeys.PSI_FILE.getData(e.getDataContext()); 53 | DataContext dataContext = e.getDataContext(); 54 | 55 | final Project project = CommonDataKeys.PROJECT.getData(dataContext); 56 | final Editor editor = CommonDataKeys.EDITOR.getData(dataContext); 57 | final VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext); 58 | 59 | if (editor != null && file != null) { 60 | processFile(file); 61 | } else if (project != null && files != null) { 62 | processFiles(files, project); 63 | } else { 64 | LOGGER.error("Cannot get com.intellij.openapi.editor.Editor, com.intellij.openapi.project.Project, " + 65 | "com.intellij.openapi.vfs.VirtualFile"); 66 | Messages.showErrorDialog("Javadocs plugin is not available", JAVADOCS_PLUGIN_TITLE_MSG); 67 | } 68 | 69 | } 70 | 71 | private void processFiles(VirtualFile[] files, Project project) { 72 | for (VirtualFile virtualFile : files) { 73 | if (virtualFile.isDirectory()) { 74 | processFiles(virtualFile.getChildren(), project); 75 | } else { 76 | PsiFile file = convertToPsiFile(virtualFile, project); 77 | processFile(file); 78 | } 79 | } 80 | } 81 | 82 | private PsiFile convertToPsiFile(VirtualFile file, Project project) { 83 | PsiManager manager = PsiManager.getInstance(project); 84 | return manager.findFile(file); 85 | } 86 | 87 | private void processFile(PsiFile file) { 88 | List elements = new LinkedList<>(); 89 | // Find all class elements 90 | List classElements = getClasses(file); 91 | elements.addAll(classElements); 92 | for (PsiClass classElement : classElements) { 93 | elements.addAll(PsiTreeUtil.getChildrenOfTypeAsList(classElement, PsiMethod.class)); 94 | elements.addAll(PsiTreeUtil.getChildrenOfTypeAsList(classElement, PsiField.class)); 95 | } 96 | for (PsiElement element : elements) { 97 | processElement(element); 98 | } 99 | } 100 | 101 | @Override 102 | public void update(AnActionEvent event) { 103 | Presentation presentation = event.getPresentation(); 104 | presentation.setEnabled(false); 105 | DataContext dataContext = event.getDataContext(); 106 | Project project = CommonDataKeys.PROJECT.getData(dataContext); 107 | if (project == null) { 108 | presentation.setEnabled(false); 109 | return; 110 | } 111 | Editor editor = CommonDataKeys.EDITOR.getData(dataContext); 112 | 113 | final VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext); 114 | 115 | if (editor != null) { 116 | PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); 117 | if (file != null && JavaFileType.INSTANCE.equals(file.getFileType())) { 118 | presentation.setEnabled(true); 119 | return; 120 | } else if (file != null && file.isDirectory()) { 121 | presentation.setEnabled(true); 122 | return; 123 | } 124 | } 125 | if (files != null && containsJavaFiles(files)) { 126 | presentation.setEnabled(true); 127 | return; 128 | } 129 | } 130 | 131 | private boolean containsJavaFiles(VirtualFile[] files) { 132 | if (files == null) { 133 | return false; 134 | } 135 | if (files.length < 1) { 136 | return false; 137 | } 138 | boolean result = false; 139 | for (VirtualFile file : files) { 140 | if (file.isDirectory()) { 141 | result = result || containsJavaFiles(file.getChildren()); 142 | } else if (JavaFileType.INSTANCE.equals(file.getFileType())) { 143 | result = true; 144 | } 145 | } 146 | return result; 147 | } 148 | 149 | /** 150 | * Gets the classes. 151 | * 152 | * @param element the Element 153 | * @return the Classes 154 | */ 155 | private List getClasses(PsiElement element) { 156 | List elements = new LinkedList<>(); 157 | List classElements = PsiTreeUtil.getChildrenOfTypeAsList(element, PsiClass.class); 158 | elements.addAll(classElements); 159 | for (PsiClass classElement : classElements) { 160 | elements.addAll(getClasses(classElement)); 161 | } 162 | return elements; 163 | } 164 | 165 | } 166 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/action/JavaDocsRemoveAction.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.action; 2 | 3 | import com.github.setial.intellijjavadocs.operation.JavaDocWriter; 4 | import com.intellij.openapi.application.ApplicationManager; 5 | import com.intellij.psi.PsiElement; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | /** 9 | * The type Java docs remove action. 10 | * 11 | * @author Sergey Timofiychuk 12 | */ 13 | public class JavaDocsRemoveAction extends JavaDocsGenerateAction { 14 | 15 | private JavaDocWriter writer; 16 | 17 | /** 18 | * Instantiates a new Java docs remove action. 19 | */ 20 | public JavaDocsRemoveAction() { 21 | writer = ApplicationManager.getApplication().getService(JavaDocWriter.class); 22 | } 23 | 24 | @Override 25 | protected void processElement(@NotNull PsiElement element) { 26 | writer.remove(element); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/configuration/JavaDocConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.configuration; 2 | 3 | import com.github.setial.intellijjavadocs.model.settings.JavaDocSettings; 4 | import org.jetbrains.annotations.Nullable; 5 | 6 | /** 7 | * The interface Java doc configuration. 8 | * 9 | * @author Sergey Timofiychuk 10 | */ 11 | public interface JavaDocConfiguration { 12 | 13 | 14 | /** 15 | * The constant COMPONENT_NAME. 16 | */ 17 | String COMPONENT_NAME = "JavaDocConfiguration"; 18 | 19 | /** 20 | * The constant COMPONENT_VERSION. 21 | */ 22 | String COMPONENT_CONFIG_VERSION = "4.0.1"; 23 | 24 | /** 25 | * The constant COMPONENT_CONFIG_PATH. 26 | */ 27 | String COMPONENT_CONFIG_PATH = "intellij-javadocs-" + COMPONENT_CONFIG_VERSION + ".xml"; 28 | 29 | /** 30 | * Gets the configuration. 31 | * 32 | * @return the Configuration 33 | */ 34 | @Nullable 35 | JavaDocSettings getConfiguration(); 36 | 37 | void setupTemplates(); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/configuration/impl/JavaDocConfigurationImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.configuration.impl; 2 | 3 | import com.github.setial.intellijjavadocs.configuration.JavaDocConfiguration; 4 | import com.github.setial.intellijjavadocs.exception.SetupTemplateException; 5 | import com.github.setial.intellijjavadocs.model.settings.JavaDocSettings; 6 | import com.github.setial.intellijjavadocs.model.settings.Level; 7 | import com.github.setial.intellijjavadocs.model.settings.Mode; 8 | import com.github.setial.intellijjavadocs.model.settings.Visibility; 9 | import com.github.setial.intellijjavadocs.template.DocTemplateManager; 10 | import com.intellij.openapi.application.ApplicationManager; 11 | import com.intellij.openapi.components.PersistentStateComponent; 12 | import com.intellij.openapi.components.State; 13 | import com.intellij.openapi.components.Storage; 14 | import com.intellij.openapi.diagnostic.Logger; 15 | import com.intellij.openapi.ui.Messages; 16 | import org.jdom.Element; 17 | import org.jetbrains.annotations.NotNull; 18 | import org.jetbrains.annotations.Nullable; 19 | 20 | import java.util.HashSet; 21 | import java.util.Set; 22 | 23 | import static com.github.setial.intellijjavadocs.configuration.JavaDocConfiguration.COMPONENT_CONFIG_PATH; 24 | 25 | /** 26 | * The type Java doc configuration impl. 27 | * 28 | * @author Sergey Timofiychuk 29 | */ 30 | @State( 31 | name = JavaDocConfiguration.COMPONENT_NAME, 32 | storages = { 33 | @Storage(value = COMPONENT_CONFIG_PATH) 34 | } 35 | ) 36 | public class JavaDocConfigurationImpl implements JavaDocConfiguration, PersistentStateComponent { 37 | 38 | public static final String JAVADOCS_PLUGIN_TITLE_MSG = "Javadocs plugin"; 39 | 40 | private static final Logger LOGGER = Logger.getInstance(JavaDocConfigurationImpl.class); 41 | 42 | private JavaDocSettings settings; 43 | private DocTemplateManager templateManager; 44 | private boolean loadedStoredConfig = false; 45 | 46 | /** 47 | * Instantiates a new Java doc configuration object. 48 | */ 49 | public JavaDocConfigurationImpl() { 50 | templateManager = ApplicationManager.getApplication().getService(DocTemplateManager.class); 51 | initSettings(); 52 | } 53 | 54 | @Override 55 | public JavaDocSettings getConfiguration() { 56 | return settings; 57 | } 58 | 59 | @Nullable 60 | @Override 61 | public Element getState() { 62 | Element root = new Element("JAVA_DOC_SETTINGS_PLUGIN"); 63 | if (settings != null) { 64 | settings.addToDom(root); 65 | loadedStoredConfig = true; 66 | } 67 | return root; 68 | } 69 | 70 | @Override 71 | public void loadState(@NotNull Element javaDocSettings) { 72 | settings = new JavaDocSettings(javaDocSettings); 73 | setupTemplates(); 74 | loadedStoredConfig = true; 75 | } 76 | 77 | private void initSettings() { 78 | if (!loadedStoredConfig) { 79 | // setup default values 80 | settings = new JavaDocSettings(); 81 | Set levels = new HashSet<>(); 82 | levels.add(Level.TYPE); 83 | levels.add(Level.METHOD); 84 | levels.add(Level.FIELD); 85 | 86 | Set visibilities = new HashSet<>(); 87 | visibilities.add(Visibility.PUBLIC); 88 | visibilities.add(Visibility.PROTECTED); 89 | visibilities.add(Visibility.DEFAULT); 90 | 91 | settings.getGeneralSettings().setOverriddenMethods(false); 92 | settings.getGeneralSettings().setSplittedClassName(true); 93 | settings.getGeneralSettings().setMode(Mode.UPDATE); 94 | settings.getGeneralSettings().setLevels(levels); 95 | settings.getGeneralSettings().setVisibilities(visibilities); 96 | 97 | settings.getTemplateSettings().setClassTemplates(templateManager.getClassTemplates()); 98 | settings.getTemplateSettings().setConstructorTemplates(templateManager.getConstructorTemplates()); 99 | settings.getTemplateSettings().setMethodTemplates(templateManager.getMethodTemplates()); 100 | settings.getTemplateSettings().setFieldTemplates(templateManager.getFieldTemplates()); 101 | } 102 | } 103 | 104 | @Override 105 | public void setupTemplates() { 106 | try { 107 | templateManager.setClassTemplates(settings.getTemplateSettings().getClassTemplates()); 108 | templateManager.setConstructorTemplates(settings.getTemplateSettings().getConstructorTemplates()); 109 | templateManager.setMethodTemplates(settings.getTemplateSettings().getMethodTemplates()); 110 | templateManager.setFieldTemplates(settings.getTemplateSettings().getFieldTemplates()); 111 | } catch (SetupTemplateException e) { 112 | LOGGER.error(e); 113 | Messages.showErrorDialog("Javadocs plugin is not available, cause: " + e.getMessage(), JAVADOCS_PLUGIN_TITLE_MSG); 114 | } 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/exception/FileNotValidException.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.exception; 2 | 3 | /** 4 | * The type File not valid exception. 5 | * 6 | * @author Sergey Timofiychuk 7 | */ 8 | public class FileNotValidException extends RuntimeException { 9 | 10 | /** 11 | * Instantiates a new File not valid exception. 12 | * 13 | * @param message the message 14 | */ 15 | public FileNotValidException(String message) { 16 | super(message); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/exception/NotFoundElementException.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.exception; 2 | 3 | /** 4 | * The type Not found element exception. 5 | * 6 | * @author Sergey Timofiychuk 7 | */ 8 | public class NotFoundElementException extends RuntimeException { 9 | 10 | /** 11 | * Instantiates a new Not found element exception. 12 | * 13 | * @param message the message 14 | */ 15 | public NotFoundElementException(String message) { 16 | super(message); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/exception/SetupTemplateException.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.exception; 2 | 3 | /** 4 | * The type Setup template exception. 5 | * 6 | * @author Sergey Timofiychuk 7 | */ 8 | public class SetupTemplateException extends RuntimeException { 9 | 10 | /** 11 | * Instantiates a new Setup template exception. 12 | * 13 | * @param cause the cause 14 | */ 15 | public SetupTemplateException(Throwable cause) { 16 | super(cause); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/exception/TemplateNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.exception; 2 | 3 | /** 4 | * The type Template not found exception. 5 | * 6 | * @author Sergey Timofiychuk 7 | */ 8 | public class TemplateNotFoundException extends RuntimeException { 9 | 10 | /** 11 | * Instantiates a new Template not found exception. 12 | * 13 | * @param message the message 14 | */ 15 | public TemplateNotFoundException(String message) { 16 | super(message); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/generator/JavaDocGenerator.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.generator; 2 | 3 | import com.intellij.psi.PsiElement; 4 | import com.intellij.psi.javadoc.PsiDocComment; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.annotations.Nullable; 7 | 8 | /** 9 | * The interface Java doc generator. 10 | * 11 | * @param the type parameter 12 | * @author Sergey Timofiychuk 13 | */ 14 | public interface JavaDocGenerator { 15 | 16 | /** 17 | * Generate java docs. 18 | * 19 | * @param element the Element 20 | * @return the Psi doc comment 21 | */ 22 | @Nullable 23 | PsiDocComment generate(@NotNull T element); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/generator/impl/AbstractJavaDocGenerator.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.generator.impl; 2 | 3 | import com.github.setial.intellijjavadocs.configuration.JavaDocConfiguration; 4 | import com.github.setial.intellijjavadocs.generator.JavaDocGenerator; 5 | import com.github.setial.intellijjavadocs.model.JavaDoc; 6 | import com.github.setial.intellijjavadocs.model.settings.JavaDocSettings; 7 | import com.github.setial.intellijjavadocs.model.settings.Mode; 8 | import com.github.setial.intellijjavadocs.model.settings.Visibility; 9 | import com.github.setial.intellijjavadocs.template.DocTemplateManager; 10 | import com.github.setial.intellijjavadocs.template.DocTemplateProcessor; 11 | import com.github.setial.intellijjavadocs.utils.JavaDocUtils; 12 | import com.intellij.openapi.application.ApplicationManager; 13 | import com.intellij.openapi.application.PathMacros; 14 | import com.intellij.openapi.project.Project; 15 | import com.intellij.pom.PomNamedTarget; 16 | import com.intellij.psi.PsiElement; 17 | import com.intellij.psi.PsiElementFactory; 18 | import com.intellij.psi.PsiModifier; 19 | import com.intellij.psi.PsiModifierList; 20 | import com.intellij.psi.javadoc.PsiDocComment; 21 | import org.apache.commons.lang3.StringUtils; 22 | import org.jetbrains.annotations.NotNull; 23 | import org.jetbrains.annotations.Nullable; 24 | 25 | import java.util.HashMap; 26 | import java.util.Map; 27 | 28 | /** 29 | * The type Abstract java doc generator. 30 | * 31 | * @param the type parameter 32 | * @author Sergey Timofiychuk 33 | */ 34 | public abstract class AbstractJavaDocGenerator implements JavaDocGenerator { 35 | 36 | private DocTemplateManager docTemplateManager; 37 | private DocTemplateProcessor docTemplateProcessor; 38 | private PsiElementFactory psiElementFactory; 39 | private JavaDocConfiguration settings; 40 | 41 | /** 42 | * Instantiates a new Abstract java doc generator. 43 | * 44 | * @param project the Project 45 | */ 46 | public AbstractJavaDocGenerator(@NotNull Project project) { 47 | docTemplateManager = ApplicationManager.getApplication().getService(DocTemplateManager.class); 48 | docTemplateProcessor = ApplicationManager.getApplication().getService(DocTemplateProcessor.class); 49 | psiElementFactory = PsiElementFactory.getInstance(project); 50 | settings = project.getService(JavaDocConfiguration.class); 51 | } 52 | 53 | @Nullable 54 | @Override 55 | public final PsiDocComment generate(@NotNull T element) { 56 | PsiDocComment result = null; 57 | PsiDocComment oldDocComment = null; 58 | PsiElement firstElement = element.getFirstChild(); 59 | if (firstElement instanceof PsiDocComment) { 60 | oldDocComment = (PsiDocComment) firstElement; 61 | } 62 | 63 | JavaDocSettings configuration = settings.getConfiguration(); 64 | if (configuration != null) { 65 | Mode mode = configuration.getGeneralSettings().getMode(); 66 | switch (mode) { 67 | case KEEP: 68 | if (oldDocComment != null) { 69 | break; 70 | } 71 | case REPLACE: 72 | result = replaceJavaDocAction(element); 73 | break; 74 | case UPDATE: 75 | default: 76 | if (oldDocComment != null) { 77 | result = updateJavaDocAction(element, oldDocComment); 78 | } else { 79 | result = replaceJavaDocAction(element); 80 | } 81 | break; 82 | } 83 | } 84 | return result; 85 | } 86 | 87 | /** 88 | * Gets the doc template manager. 89 | * 90 | * @return the Doc template manager 91 | */ 92 | @NotNull 93 | protected DocTemplateManager getDocTemplateManager() { 94 | return docTemplateManager; 95 | } 96 | 97 | /** 98 | * Gets the doc template processor. 99 | * 100 | * @return the Doc template processor 101 | */ 102 | @NotNull 103 | protected DocTemplateProcessor getDocTemplateProcessor() { 104 | return docTemplateProcessor; 105 | } 106 | 107 | /** 108 | * Gets the psi element factory. 109 | * 110 | * @return the Psi element factory 111 | */ 112 | @NotNull 113 | protected PsiElementFactory getPsiElementFactory() { 114 | return psiElementFactory; 115 | } 116 | 117 | /** 118 | * Gets settings. 119 | * 120 | * @return the settings 121 | */ 122 | @NotNull 123 | protected JavaDocConfiguration getSettings() { 124 | return settings; 125 | } 126 | 127 | /** 128 | * Check whether javadoc should be generated. 129 | * 130 | * @param modifiers the modifiers 131 | * @return the boolean 132 | */ 133 | protected boolean shouldGenerate(PsiModifierList modifiers) { 134 | return checkModifiers(modifiers, PsiModifier.PUBLIC, Visibility.PUBLIC) || 135 | checkModifiers(modifiers, PsiModifier.PROTECTED, Visibility.PROTECTED) || 136 | checkModifiers(modifiers, PsiModifier.PACKAGE_LOCAL, Visibility.DEFAULT) || 137 | checkModifiers(modifiers, PsiModifier.PRIVATE, Visibility.PRIVATE); 138 | } 139 | 140 | /** 141 | * Gets default parameters used to build template. 142 | * 143 | * @param element the element 144 | * @return the default parameters 145 | */ 146 | protected Map getDefaultParameters(PomNamedTarget element) { 147 | Map params = new HashMap<>(); 148 | params.put("element", element); 149 | params.put("name", getDocTemplateProcessor().buildDescription(element.getName(), true)); 150 | params.put("partName", getDocTemplateProcessor().buildPartialDescription(element.getName())); 151 | params.put("splitNames", StringUtils.splitByCharacterTypeCamelCase(element.getName())); 152 | PathMacros macros = PathMacros.getInstance(); 153 | for (String name : macros.getUserMacroNames()) { 154 | params.put("path" + name, macros.getValue(name)); 155 | } 156 | return params; 157 | } 158 | 159 | private PsiDocComment updateJavaDocAction(T element, PsiDocComment oldDocComment) { 160 | PsiDocComment result = null; 161 | JavaDoc newJavaDoc = generateJavaDoc(element); 162 | JavaDoc oldJavaDoc = JavaDocUtils.createJavaDoc(oldDocComment); 163 | if (newJavaDoc != null) { 164 | newJavaDoc = JavaDocUtils.mergeJavaDocs(oldJavaDoc, newJavaDoc); 165 | String javaDoc = newJavaDoc.toJavaDoc(); 166 | result = psiElementFactory.createDocCommentFromText(javaDoc); 167 | } 168 | return result; 169 | } 170 | 171 | private PsiDocComment replaceJavaDocAction(T element) { 172 | PsiDocComment result = null; 173 | JavaDoc newJavaDoc = generateJavaDoc(element); 174 | if (newJavaDoc != null) { 175 | String javaDoc = newJavaDoc.toJavaDoc(); 176 | result = psiElementFactory.createDocCommentFromText(javaDoc); 177 | } 178 | return result; 179 | } 180 | 181 | private boolean checkModifiers(PsiModifierList modifiers, String modifier, Visibility visibility) { 182 | JavaDocSettings configuration = getSettings().getConfiguration(); 183 | return modifiers != null && modifiers.hasModifierProperty(modifier) && configuration != null && 184 | configuration.getGeneralSettings().getVisibilities().contains(visibility); 185 | } 186 | 187 | /** 188 | * Generate java doc. 189 | * 190 | * @param element the Element 191 | * @return the Java doc 192 | */ 193 | @Nullable 194 | protected abstract JavaDoc generateJavaDoc(@NotNull T element); 195 | 196 | } 197 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/generator/impl/ClassJavaDocGenerator.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.generator.impl; 2 | 3 | import com.github.setial.intellijjavadocs.model.JavaDoc; 4 | import com.github.setial.intellijjavadocs.model.settings.JavaDocSettings; 5 | import com.github.setial.intellijjavadocs.model.settings.Level; 6 | import com.github.setial.intellijjavadocs.utils.JavaDocUtils; 7 | import com.intellij.openapi.project.Project; 8 | import com.intellij.psi.PsiClass; 9 | import freemarker.template.Template; 10 | import org.jetbrains.annotations.NotNull; 11 | import org.jetbrains.annotations.Nullable; 12 | 13 | import java.util.Map; 14 | 15 | /** 16 | * The type Class java doc generator. 17 | * 18 | * @author Sergey Timofiychuk 19 | */ 20 | public class ClassJavaDocGenerator extends AbstractJavaDocGenerator { 21 | 22 | /** 23 | * Instantiates a new Class java doc generator. 24 | * 25 | * @param project the Project 26 | */ 27 | public ClassJavaDocGenerator(@NotNull Project project) { 28 | super(project); 29 | } 30 | 31 | @Nullable 32 | @Override 33 | protected JavaDoc generateJavaDoc(@NotNull PsiClass element) { 34 | JavaDocSettings configuration = getSettings().getConfiguration(); 35 | if ((configuration != null && !configuration.getGeneralSettings().getLevels().contains(Level.TYPE)) || 36 | !shouldGenerate(element.getModifierList())) { 37 | return null; 38 | } 39 | Template template = getDocTemplateManager().getClassTemplate(element); 40 | Map params = getDefaultParameters(element); 41 | if (!configuration.getGeneralSettings().isSplittedClassName()) { 42 | params.put("name", element.getName()); 43 | } 44 | String javaDocText = getDocTemplateProcessor().merge(template, params); 45 | return JavaDocUtils.toJavaDoc(javaDocText, getPsiElementFactory()); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/generator/impl/FieldJavaDocGenerator.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.generator.impl; 2 | 3 | import com.github.setial.intellijjavadocs.model.JavaDoc; 4 | import com.github.setial.intellijjavadocs.model.settings.JavaDocSettings; 5 | import com.github.setial.intellijjavadocs.model.settings.Level; 6 | import com.github.setial.intellijjavadocs.utils.JavaDocUtils; 7 | import com.intellij.openapi.project.Project; 8 | import com.intellij.psi.PsiClass; 9 | import com.intellij.psi.PsiElement; 10 | import com.intellij.psi.PsiField; 11 | import freemarker.template.Template; 12 | import org.jetbrains.annotations.NotNull; 13 | import org.jetbrains.annotations.Nullable; 14 | 15 | import java.util.Map; 16 | 17 | /** 18 | * The type Field java doc generator. 19 | * 20 | * @author Sergey Timofiychuk 21 | */ 22 | public class FieldJavaDocGenerator extends AbstractJavaDocGenerator { 23 | 24 | /** 25 | * Instantiates a new Field java doc generator. 26 | * 27 | * @param project the Project 28 | */ 29 | public FieldJavaDocGenerator(@NotNull Project project) { 30 | super(project); 31 | } 32 | 33 | @Nullable 34 | @Override 35 | protected JavaDoc generateJavaDoc(@NotNull PsiField element) { 36 | JavaDocSettings configuration = getSettings().getConfiguration(); 37 | if (configuration != null && !configuration.getGeneralSettings().getLevels().contains(Level.FIELD) || 38 | !shouldGenerate(element.getModifierList())) { 39 | return null; 40 | } 41 | Template template = getDocTemplateManager().getFieldTemplate(element); 42 | Map params = getDefaultParameters(element); 43 | PsiClass parent = findClassElement(element); 44 | if (parent != null) { 45 | params.put("typeName", getDocTemplateProcessor().buildDescription(parent.getName(), false)); 46 | } 47 | String javaDocText = getDocTemplateProcessor().merge(template, params); 48 | return JavaDocUtils.toJavaDoc(javaDocText, getPsiElementFactory()); 49 | } 50 | 51 | private PsiClass findClassElement(PsiElement element) { 52 | PsiClass parentClass = null; 53 | if (element != null) { 54 | PsiElement parent = element.getParent(); 55 | if (parent instanceof PsiClass) { 56 | parentClass = (PsiClass) parent; 57 | } else { 58 | parentClass = findClassElement(parent); 59 | } 60 | } 61 | return parentClass; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/generator/impl/MethodJavaDocGenerator.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.generator.impl; 2 | 3 | import com.github.setial.intellijjavadocs.model.JavaDoc; 4 | import com.github.setial.intellijjavadocs.model.settings.JavaDocSettings; 5 | import com.github.setial.intellijjavadocs.model.settings.Level; 6 | import com.github.setial.intellijjavadocs.utils.JavaDocUtils; 7 | import com.intellij.openapi.project.Project; 8 | import com.intellij.psi.PsiJavaCodeReferenceElement; 9 | import com.intellij.psi.PsiMethod; 10 | import com.intellij.psi.PsiParameter; 11 | import com.intellij.psi.PsiTypeElement; 12 | import com.intellij.psi.PsiTypes; 13 | import freemarker.template.Template; 14 | import org.apache.commons.lang3.StringUtils; 15 | import org.jetbrains.annotations.NotNull; 16 | import org.jetbrains.annotations.Nullable; 17 | 18 | import java.util.HashMap; 19 | import java.util.Map; 20 | 21 | /** 22 | * The type Method java doc generator. 23 | * 24 | * @author Sergey Timofiychuk 25 | */ 26 | public class MethodJavaDocGenerator extends AbstractJavaDocGenerator { 27 | 28 | /** 29 | * Instantiates a new Method java doc generator. 30 | * 31 | * @param project the Project 32 | */ 33 | public MethodJavaDocGenerator(@NotNull Project project) { 34 | super(project); 35 | } 36 | 37 | @Nullable 38 | @Override 39 | protected JavaDoc generateJavaDoc(@NotNull PsiMethod element) { 40 | if (!shouldGenerate(element) || !shouldGenerate(element.getModifierList())) { 41 | return null; 42 | } 43 | Template template = getDocTemplateManager().getMethodTemplate(element); 44 | Map paramNames = new HashMap<>(); 45 | for (PsiParameter parameter : element.getParameterList().getParameters()) { 46 | paramNames.put(parameter.getName(), getDocTemplateProcessor().buildDescription(parameter.getName(), false)); 47 | } 48 | Map exceptionNames = new HashMap<>(); 49 | for (PsiJavaCodeReferenceElement exception : element.getThrowsList().getReferenceElements()) { 50 | exceptionNames.put(exception.getReferenceName(), 51 | getDocTemplateProcessor().buildDescription(exception.getReferenceName(), false)); 52 | } 53 | String returnDescription = StringUtils.EMPTY; 54 | PsiTypeElement returnElement = element.getReturnTypeElement(); 55 | if (returnElement != null) { 56 | returnDescription = returnElement.getText(); 57 | } 58 | Map params = getDefaultParameters(element); 59 | if (returnElement != null) { 60 | params.put("isNotVoid", !returnElement.getType().isAssignableFrom(PsiTypes.voidType())); 61 | params.put("return", getDocTemplateProcessor().buildDescription(returnDescription, false)); 62 | } 63 | params.put("paramNames", paramNames); 64 | params.put("exceptionNames", exceptionNames); 65 | params.put("fieldName", getDocTemplateProcessor().buildFieldDescription(element.getName())); 66 | 67 | String javaDocText = getDocTemplateProcessor().merge(template, params); 68 | return JavaDocUtils.toJavaDoc(javaDocText, getPsiElementFactory()); 69 | } 70 | 71 | private boolean shouldGenerate(@NotNull PsiMethod element) { 72 | PsiMethod[] superMethods = element.findSuperMethods(); 73 | JavaDocSettings configuration = getSettings().getConfiguration(); 74 | boolean result = configuration != null && configuration.getGeneralSettings().getLevels().contains(Level.METHOD); 75 | if (superMethods.length > 0) { 76 | boolean overriddenMethods = superMethods.length > 0 && configuration != null && 77 | configuration.getGeneralSettings().isOverriddenMethods(); 78 | result = result && overriddenMethods; 79 | } 80 | return result; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/model/JavaDoc.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.model; 2 | 3 | import com.github.setial.intellijjavadocs.utils.JavaDocUtils; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | /** 10 | * The type Java doc. 11 | * 12 | * @author Sergey Timofiychuk 13 | */ 14 | public class JavaDoc { 15 | 16 | private List description; 17 | private Map> tags; 18 | 19 | /** 20 | * Instantiates a new Java doc. 21 | * 22 | * @param description the Description 23 | * @param tags the Tags 24 | */ 25 | public JavaDoc(@NotNull List description, @NotNull Map> tags) { 26 | this.description = description; 27 | this.tags = tags; 28 | } 29 | 30 | /** 31 | * Gets the description. 32 | * 33 | * @return the Description 34 | */ 35 | @NotNull 36 | public List getDescription() { 37 | return description; 38 | } 39 | 40 | /** 41 | * Gets the tags. 42 | * 43 | * @return the Tags 44 | */ 45 | @NotNull 46 | public Map> getTags() { 47 | return tags; 48 | } 49 | 50 | /** 51 | * To java doc. 52 | * 53 | * @return the String 54 | */ 55 | @NotNull 56 | public String toJavaDoc() { 57 | return JavaDocUtils.convertJavaDoc(this); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/model/JavaDocElements.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.model; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | /** 6 | * The enum Java doc elements. 7 | * 8 | * @author Sergey Timofiychuk 9 | */ 10 | public enum JavaDocElements { 11 | 12 | STARTING("/*"), 13 | ENDING("/"), 14 | NEW_LINE("\n"), 15 | TAG_START("@"), 16 | LINE_START("*"), 17 | WHITE_SPACE(" "); 18 | 19 | private String presentation; 20 | 21 | /** 22 | * Instantiates a new Java doc elements. 23 | * 24 | * @param value the value 25 | */ 26 | JavaDocElements(String value) { 27 | presentation = value; 28 | } 29 | 30 | /** 31 | * Gets the presentation. 32 | * 33 | * @return the Presentation 34 | */ 35 | @NotNull 36 | public String getPresentation() { 37 | return presentation; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/model/JavaDocTag.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.model; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import org.jetbrains.annotations.Nullable; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * The type Java doc tag. 10 | * 11 | * @author Sergey Timofiychuk 12 | */ 13 | public class JavaDocTag { 14 | 15 | private String refParam; 16 | private String value; 17 | private List description; 18 | 19 | /** 20 | * Instantiates a new Java doc tag. 21 | * 22 | * @param refParam the Ref param 23 | * @param value the Value 24 | * @param description the Description 25 | */ 26 | public JavaDocTag(@Nullable String refParam, @Nullable String value, @NotNull List description) { 27 | this.refParam = refParam; 28 | this.value = value; 29 | this.description = description; 30 | } 31 | 32 | /** 33 | * Gets the ref param. 34 | * 35 | * @return the Ref param 36 | */ 37 | @Nullable 38 | public String getRefParam() { 39 | return refParam; 40 | } 41 | 42 | /** 43 | * Gets the value. 44 | * 45 | * @return the Value 46 | */ 47 | @Nullable 48 | public String getValue() { 49 | return value; 50 | } 51 | 52 | /** 53 | * Gets the description. 54 | * 55 | * @return the Description 56 | */ 57 | @NotNull 58 | public List getDescription() { 59 | return description; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/model/settings/GeneralSettings.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.model.settings; 2 | 3 | import java.util.Set; 4 | 5 | /** 6 | * The type General settings. 7 | * 8 | * @author Sergey Timofiychuk 9 | */ 10 | public class GeneralSettings { 11 | 12 | private Mode mode; 13 | private Set levels; 14 | private Set visibilities; 15 | private boolean overriddenMethods; 16 | private boolean splittedClassName; 17 | 18 | /** 19 | * Gets javadoc update mode. 20 | * 21 | * @return the mode 22 | */ 23 | public Mode getMode() { 24 | return mode; 25 | } 26 | 27 | /** 28 | * Sets javadoc update mode. 29 | * 30 | * @param mode the mode 31 | */ 32 | public void setMode(Mode mode) { 33 | this.mode = mode; 34 | } 35 | 36 | /** 37 | * Gets javadoc generate levels. 38 | * 39 | * @return the levels 40 | */ 41 | public Set getLevels() { 42 | return levels; 43 | } 44 | 45 | /** 46 | * Sets javadoc generate levels. 47 | * 48 | * @param levels the levels 49 | */ 50 | public void setLevels(Set levels) { 51 | this.levels = levels; 52 | } 53 | 54 | /** 55 | * Gets javadoc generate visibilities. 56 | * 57 | * @return the visibilities 58 | */ 59 | public Set getVisibilities() { 60 | return visibilities; 61 | } 62 | 63 | /** 64 | * Sets javadoc generate visibilities. 65 | * 66 | * @param visibilities the visibilities 67 | */ 68 | public void setVisibilities(Set visibilities) { 69 | this.visibilities = visibilities; 70 | } 71 | 72 | /** 73 | * Gets flag that shows whether javadoc should be generated on overridden methods. 74 | * 75 | * @return the flag value 76 | */ 77 | public boolean isOverriddenMethods() { 78 | return overriddenMethods; 79 | } 80 | 81 | /** 82 | * Set flag that shows whether javadoc should be generated on overridden methods. 83 | * 84 | * @param overriddenMethods the overridden methods 85 | */ 86 | public void setOverriddenMethods(boolean overriddenMethods) { 87 | this.overriddenMethods = overriddenMethods; 88 | } 89 | 90 | /** 91 | * Is splitted class name boolean. 92 | * 93 | * @return the boolean 94 | */ 95 | public boolean isSplittedClassName() { 96 | return splittedClassName; 97 | } 98 | 99 | /** 100 | * Sets splitted class name. 101 | * 102 | * @param splittedClassName the splitted class name 103 | */ 104 | public void setSplittedClassName(boolean splittedClassName) { 105 | this.splittedClassName = splittedClassName; 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/model/settings/JavaDocSettings.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.model.settings; 2 | 3 | import com.github.setial.intellijjavadocs.utils.XmlUtils; 4 | import org.apache.commons.beanutils.BeanUtils; 5 | import org.jdom.Element; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * The type Java doc settings. 11 | * 12 | * @author Sergey Timofiychuk 13 | */ 14 | public class JavaDocSettings implements Serializable { 15 | 16 | private static final String MODE = "MODE"; 17 | private static final String LEVELS = "LEVELS"; 18 | private static final String LEVEL = "LEVEL"; 19 | private static final String VISIBILITIES = "VISIBILITIES"; 20 | private static final String VISIBILITY = "VISIBILITY"; 21 | private static final String OVERRIDDEN_METHODS = "OVERRIDDEN_METHODS"; 22 | private static final String SPLITTED_CLASS_NAME = "SPLITTED_CLASS_NAME"; 23 | private static final String GENERAL = "GENERAL"; 24 | private static final String TEMPLATES = "TEMPLATES"; 25 | private static final String CLASS = "CLASS"; 26 | private static final String CLASSES = "CLASSES"; 27 | private static final String CONSTRUCTOR = "CONSTRUCTOR"; 28 | private static final String CONSTRUCTORS = "CONSTRUCTORS"; 29 | private static final String FIELD = "FIELD"; 30 | private static final String FIELDS = "FIELDS"; 31 | private static final String METHOD = "METHOD"; 32 | private static final String METHODS = "METHODS"; 33 | 34 | private GeneralSettings generalSettings = new GeneralSettings(); 35 | private TemplateSettings templateSettings = new TemplateSettings(); 36 | 37 | /** 38 | * Instantiates a new Java doc settings object. 39 | */ 40 | public JavaDocSettings() { 41 | } 42 | 43 | /** 44 | * Instantiates a new Java doc settings. 45 | * 46 | * @param element the element 47 | */ 48 | public JavaDocSettings(Element element) { 49 | Element general = element.getChild(GENERAL); 50 | if (general != null) { 51 | generalSettings.setMode(XmlUtils.getValue(general, MODE, Mode.class)); 52 | generalSettings.setOverriddenMethods(Boolean.parseBoolean(general.getChild(OVERRIDDEN_METHODS).getValue())); 53 | generalSettings.setSplittedClassName(Boolean.parseBoolean(general.getChild(SPLITTED_CLASS_NAME).getValue())); 54 | generalSettings.setLevels(XmlUtils.getValues(general, LEVELS, LEVEL, Level.class)); 55 | generalSettings.setVisibilities(XmlUtils.getValues(general, VISIBILITIES, VISIBILITY, Visibility.class)); 56 | } 57 | Element templates = element.getChild(TEMPLATES); 58 | if (templates != null) { 59 | templateSettings.setClassTemplates(XmlUtils.getMap(templates, CLASSES, CLASS)); 60 | templateSettings.setConstructorTemplates(XmlUtils.getMap(templates, CONSTRUCTORS, CONSTRUCTOR)); 61 | templateSettings.setFieldTemplates(XmlUtils.getMap(templates, FIELDS, FIELD)); 62 | templateSettings.setMethodTemplates(XmlUtils.getMap(templates, METHODS, METHOD)); 63 | } 64 | } 65 | 66 | /** 67 | * Create dom model from this object and add it to root element passed as parameter. 68 | * 69 | * @param root the root 70 | */ 71 | public void addToDom(Element root) { 72 | Element general = new Element(GENERAL); 73 | root.addContent(general); 74 | general.addContent(XmlUtils.getElement(MODE, generalSettings.getMode().toString())); 75 | general.addContent(XmlUtils.getElement(OVERRIDDEN_METHODS, String.valueOf(generalSettings.isOverriddenMethods()))); 76 | general.addContent(XmlUtils.getElement(SPLITTED_CLASS_NAME, String.valueOf(generalSettings.isSplittedClassName()))); 77 | general.addContent(XmlUtils.getElement(LEVELS, LEVEL, generalSettings.getLevels())); 78 | general.addContent(XmlUtils.getElement(VISIBILITIES, VISIBILITY, generalSettings.getVisibilities())); 79 | 80 | Element templates = new Element(TEMPLATES); 81 | root.addContent(templates); 82 | templates.addContent(XmlUtils.getElement(CLASSES, CLASS, templateSettings.getClassTemplates())); 83 | templates.addContent(XmlUtils.getElement(CONSTRUCTORS, CONSTRUCTOR, templateSettings.getConstructorTemplates())); 84 | templates.addContent(XmlUtils.getElement(METHODS, METHOD, templateSettings.getMethodTemplates())); 85 | templates.addContent(XmlUtils.getElement(FIELDS, FIELD, templateSettings.getFieldTemplates())); 86 | } 87 | 88 | /** 89 | * Gets general settings. 90 | * 91 | * @return the general settings 92 | */ 93 | public GeneralSettings getGeneralSettings() { 94 | return generalSettings; 95 | } 96 | 97 | /** 98 | * Sets general settings. 99 | * 100 | * @param generalSettings the general settings 101 | */ 102 | public void setGeneralSettings(GeneralSettings generalSettings) { 103 | this.generalSettings = generalSettings; 104 | } 105 | 106 | /** 107 | * Gets template settings. 108 | * 109 | * @return the template settings 110 | */ 111 | public TemplateSettings getTemplateSettings() { 112 | return templateSettings; 113 | } 114 | 115 | /** 116 | * Sets template settings. 117 | * 118 | * @param templateSettings the template settings 119 | */ 120 | public void setTemplateSettings(TemplateSettings templateSettings) { 121 | this.templateSettings = templateSettings; 122 | } 123 | 124 | } 125 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/model/settings/Level.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.model.settings; 2 | 3 | /** 4 | * The enum Level. 5 | * 6 | * @author Sergey Timofiychuk 7 | */ 8 | public enum Level { 9 | 10 | /** 11 | * Type level. 12 | */ 13 | TYPE, 14 | 15 | /** 16 | * Method level. 17 | */ 18 | METHOD, 19 | 20 | /** 21 | * Field level. 22 | */ 23 | FIELD 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/model/settings/Mode.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.model.settings; 2 | 3 | /** 4 | * The enum Mode. 5 | * 6 | * @author Sergey Timofiychuk 7 | */ 8 | public enum Mode { 9 | 10 | /** 11 | * Keep mode. 12 | */ 13 | KEEP, 14 | 15 | /** 16 | * Update mode. 17 | */ 18 | UPDATE, 19 | 20 | /** 21 | * Replace mode. 22 | */ 23 | REPLACE 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/model/settings/TemplateSettings.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.model.settings; 2 | 3 | import java.util.LinkedHashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * The type Template settings. 8 | * 9 | * @author Sergey Timofiychuk 10 | */ 11 | public class TemplateSettings { 12 | 13 | private Map classTemplates = new LinkedHashMap<>(); 14 | private Map fieldTemplates = new LinkedHashMap<>(); 15 | private Map methodTemplates = new LinkedHashMap<>(); 16 | private Map constructorTemplates = new LinkedHashMap<>(); 17 | 18 | /** 19 | * Gets class templates. 20 | * 21 | * @return the class templates 22 | */ 23 | public Map getClassTemplates() { 24 | return classTemplates; 25 | } 26 | 27 | /** 28 | * Sets class templates. 29 | * 30 | * @param classTemplates the class templates 31 | */ 32 | public void setClassTemplates(Map classTemplates) { 33 | this.classTemplates = classTemplates; 34 | } 35 | 36 | /** 37 | * Gets constructor templates. 38 | * 39 | * @return the constructor templates 40 | */ 41 | public Map getConstructorTemplates() { 42 | return constructorTemplates; 43 | } 44 | 45 | /** 46 | * Sets constructor templates. 47 | * 48 | * @param constructorTemplates the constructor templates 49 | */ 50 | public void setConstructorTemplates(Map constructorTemplates) { 51 | this.constructorTemplates = constructorTemplates; 52 | } 53 | 54 | /** 55 | * Gets field templates. 56 | * 57 | * @return the field templates 58 | */ 59 | public Map getFieldTemplates() { 60 | return fieldTemplates; 61 | } 62 | 63 | /** 64 | * Sets field templates. 65 | * 66 | * @param fieldTemplates the field templates 67 | */ 68 | public void setFieldTemplates(Map fieldTemplates) { 69 | this.fieldTemplates = fieldTemplates; 70 | } 71 | 72 | /** 73 | * Gets method templates. 74 | * 75 | * @return the method templates 76 | */ 77 | public Map getMethodTemplates() { 78 | return methodTemplates; 79 | } 80 | 81 | /** 82 | * Sets method templates. 83 | * 84 | * @param methodTemplates the method templates 85 | */ 86 | public void setMethodTemplates(Map methodTemplates) { 87 | this.methodTemplates = methodTemplates; 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/model/settings/Visibility.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.model.settings; 2 | 3 | /** 4 | * The enum Visibility. 5 | * 6 | * @author Sergey Timofiychuk 7 | */ 8 | public enum Visibility { 9 | 10 | /** 11 | * Public visibility. 12 | */ 13 | PUBLIC, 14 | 15 | /** 16 | * Protected visibility. 17 | */ 18 | PROTECTED, 19 | 20 | /** 21 | * Default visibility. 22 | */ 23 | DEFAULT, 24 | 25 | /** 26 | * Private visibility. 27 | */ 28 | PRIVATE 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/operation/JavaDocWriter.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.operation; 2 | 3 | import com.intellij.psi.PsiElement; 4 | import com.intellij.psi.javadoc.PsiDocComment; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | /** 8 | * The interface Java doc writer. 9 | * 10 | * @author Sergey Timofiychuk 11 | */ 12 | public interface JavaDocWriter { 13 | 14 | /** 15 | * Write java doc. 16 | * 17 | * @param javaDoc the Java doc 18 | * @param beforeElement the element to place javadoc before it 19 | */ 20 | void write(@NotNull PsiDocComment javaDoc, @NotNull PsiElement beforeElement); 21 | 22 | /** 23 | * Remove void. 24 | * 25 | * @param beforeElement the before element 26 | */ 27 | void remove(@NotNull PsiElement beforeElement); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/operation/impl/JavaDocWriterImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.operation.impl; 2 | 3 | import com.github.setial.intellijjavadocs.exception.FileNotValidException; 4 | import com.github.setial.intellijjavadocs.exception.NotFoundElementException; 5 | import com.github.setial.intellijjavadocs.operation.JavaDocWriter; 6 | import com.intellij.lang.ASTNode; 7 | import com.intellij.openapi.command.WriteCommandAction; 8 | import com.intellij.openapi.diagnostic.Logger; 9 | import com.intellij.openapi.editor.Editor; 10 | import com.intellij.openapi.project.Project; 11 | import com.intellij.openapi.ui.Messages; 12 | import com.intellij.openapi.vfs.ReadonlyStatusHandler; 13 | import com.intellij.openapi.vfs.ReadonlyStatusHandler.OperationStatus; 14 | import com.intellij.psi.PsiDocumentManager; 15 | import com.intellij.psi.PsiElement; 16 | import com.intellij.psi.PsiFile; 17 | import com.intellij.psi.PsiWhiteSpace; 18 | import com.intellij.psi.codeStyle.CodeStyleManager; 19 | import com.intellij.psi.impl.source.tree.PsiWhiteSpaceImpl; 20 | import com.intellij.psi.javadoc.PsiDocComment; 21 | import com.intellij.psi.util.PsiEditorUtil; 22 | import com.intellij.util.ThrowableRunnable; 23 | import org.jetbrains.annotations.NotNull; 24 | 25 | import java.util.Collections; 26 | 27 | import static com.github.setial.intellijjavadocs.configuration.impl.JavaDocConfigurationImpl.JAVADOCS_PLUGIN_TITLE_MSG; 28 | 29 | /** 30 | * The type Java doc writer impl. 31 | * 32 | * @author Sergey Timofiychuk 33 | */ 34 | public class JavaDocWriterImpl implements JavaDocWriter { 35 | 36 | private static final Logger LOGGER = Logger.getInstance(JavaDocWriterImpl.class); 37 | 38 | @Override 39 | public void write(@NotNull PsiDocComment javaDoc, @NotNull PsiElement beforeElement) { 40 | try { 41 | checkFilesAccess(beforeElement); 42 | } catch (FileNotValidException e) { 43 | LOGGER.error(e.getMessage()); 44 | Messages.showErrorDialog("Javadocs plugin is not available, cause: " + e.getMessage(), JAVADOCS_PLUGIN_TITLE_MSG); 45 | return; 46 | } 47 | 48 | Project project = beforeElement.getProject(); 49 | PsiFile file = beforeElement.getContainingFile(); 50 | WriteCommandAction.Builder builder = WriteCommandAction.writeCommandAction(project, file); 51 | try { 52 | builder.run(new WriteJavaDocActionImpl(javaDoc, beforeElement)); 53 | } catch (RuntimeException e) { 54 | LOGGER.error(e); 55 | Messages.showErrorDialog("Javadocs plugin is not available, cause: " + e.getMessage(), JAVADOCS_PLUGIN_TITLE_MSG); 56 | } 57 | } 58 | 59 | @Override 60 | public void remove(@NotNull PsiElement beforeElement) { 61 | try { 62 | checkFilesAccess(beforeElement); 63 | } catch (FileNotValidException e) { 64 | LOGGER.error(e); 65 | Messages.showErrorDialog("Javadocs plugin is not available, cause: " + e.getMessage(), JAVADOCS_PLUGIN_TITLE_MSG); 66 | return; 67 | } 68 | 69 | Project project = beforeElement.getProject(); 70 | PsiFile file = beforeElement.getContainingFile(); 71 | WriteCommandAction.Builder builder = WriteCommandAction.writeCommandAction(project, file); 72 | try { 73 | builder.run(new RemoveJavaDocActionImpl(beforeElement)); 74 | } catch (RuntimeException e) { 75 | LOGGER.error(e); 76 | Messages.showErrorDialog("Javadocs plugin is not available, cause: " + e.getMessage(), JAVADOCS_PLUGIN_TITLE_MSG); 77 | } 78 | } 79 | 80 | /** 81 | * The type Write command action impl. 82 | * 83 | * @author Sergey Timofiychuk 84 | */ 85 | private static class WriteJavaDocActionImpl implements ThrowableRunnable { 86 | 87 | private final PsiDocComment javaDoc; 88 | private final PsiElement element; 89 | 90 | /** 91 | * Instantiates a new Write java doc action impl. 92 | * 93 | * @param javaDoc the java doc 94 | * @param element the element 95 | */ 96 | protected WriteJavaDocActionImpl(@NotNull PsiDocComment javaDoc, @NotNull PsiElement element) { 97 | this.javaDoc = javaDoc; 98 | this.element = element; 99 | } 100 | 101 | @Override 102 | public void run() throws RuntimeException { 103 | if (element.getFirstChild() instanceof PsiDocComment) { 104 | replaceJavaDoc(element, javaDoc); 105 | } else { 106 | addJavaDoc(element, javaDoc); 107 | } 108 | ensureWhitespaceAfterJavaDoc(element); 109 | reformatJavaDoc(element); 110 | } 111 | 112 | private void ensureWhitespaceAfterJavaDoc(PsiElement element) { 113 | // this method is required to create well formatted javadocs in enums 114 | PsiElement firstChild = element.getFirstChild(); 115 | if (!PsiDocComment.class.isAssignableFrom(firstChild.getClass())) { 116 | return; 117 | } 118 | PsiElement nextElement = firstChild.getNextSibling(); 119 | if (PsiWhiteSpace.class.isAssignableFrom(nextElement.getClass())) { 120 | return; 121 | } 122 | pushPostponedChanges(element); 123 | ASTNode node = element.getNode(); 124 | if (node != null) 125 | node.addChild(new PsiWhiteSpaceImpl("\n"), nextElement.getNode()); 126 | } 127 | } 128 | 129 | private static class RemoveJavaDocActionImpl implements ThrowableRunnable { 130 | 131 | private final PsiElement element; 132 | 133 | /** 134 | * Instantiates a new Remove java doc action impl. 135 | * 136 | * @param element the element 137 | */ 138 | protected RemoveJavaDocActionImpl(PsiElement element) { 139 | this.element = element; 140 | } 141 | 142 | @Override 143 | public void run() { 144 | if (element.getFirstChild() instanceof PsiDocComment) { 145 | deleteJavaDoc(this.element); 146 | } 147 | } 148 | } 149 | 150 | private static void deleteJavaDoc(PsiElement theElement) { 151 | pushPostponedChanges(theElement); 152 | theElement.getFirstChild().delete(); 153 | } 154 | 155 | private static void addJavaDoc(PsiElement theElement, PsiDocComment theJavaDoc) { 156 | pushPostponedChanges(theElement); 157 | ASTNode node = theElement.getNode(); 158 | if (node != null) 159 | node.addChild(theJavaDoc.getNode(), theElement.getFirstChild().getNode()); 160 | } 161 | 162 | private static void replaceJavaDoc(PsiElement theElement, PsiDocComment theJavaDoc) { 163 | deleteJavaDoc(theElement); 164 | addJavaDoc(theElement, theJavaDoc); 165 | } 166 | 167 | private static void reformatJavaDoc(PsiElement theElement) { 168 | CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(theElement.getProject()); 169 | pushPostponedChanges(theElement); 170 | try { 171 | int javadocTextOffset = findJavaDocTextOffset(theElement); 172 | int javaCodeTextOffset = findJavaCodeTextOffset(theElement); 173 | codeStyleManager.reformatText(theElement.getContainingFile(), javadocTextOffset, javaCodeTextOffset + 1); 174 | } catch (NotFoundElementException e) { 175 | LOGGER.info("Could not reformat javadoc since cannot find required elements", e); 176 | } 177 | } 178 | 179 | private static int findJavaDocTextOffset(PsiElement theElement) { 180 | PsiElement javadocElement = theElement.getFirstChild(); 181 | if (!(javadocElement instanceof PsiDocComment)) { 182 | throw new NotFoundElementException("Cannot find element of type PsiDocComment"); 183 | } 184 | return javadocElement.getTextOffset(); 185 | } 186 | 187 | private static int findJavaCodeTextOffset(PsiElement theElement) { 188 | if (theElement.getChildren().length < 2) { 189 | throw new NotFoundElementException("Can not find offset of java code"); 190 | } 191 | return theElement.getChildren()[1].getTextOffset(); 192 | } 193 | 194 | private static void pushPostponedChanges(PsiElement element) { 195 | Editor editor = PsiEditorUtil.findEditor(element.getContainingFile()); 196 | if (editor != null) { 197 | PsiDocumentManager.getInstance(element.getProject()) 198 | .doPostponedOperationsAndUnblockDocument(editor.getDocument()); 199 | } 200 | } 201 | 202 | private void checkFilesAccess(@NotNull PsiElement beforeElement) { 203 | PsiFile containingFile = beforeElement.getContainingFile(); 204 | if (containingFile == null || !containingFile.isValid()) { 205 | throw new FileNotValidException("File cannot be used to generate javadocs"); 206 | } 207 | OperationStatus status = ReadonlyStatusHandler.getInstance(beforeElement.getProject()). 208 | ensureFilesWritable(Collections.singletonList(containingFile.getVirtualFile())); 209 | if (status.hasReadonlyFiles()) { 210 | throw new FileNotValidException(status.getReadonlyFilesMessage()); 211 | } 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/template/DocTemplateManager.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.template; 2 | 3 | import com.intellij.psi.PsiClass; 4 | import com.intellij.psi.PsiField; 5 | import com.intellij.psi.PsiMethod; 6 | import freemarker.template.Template; 7 | import org.jetbrains.annotations.NotNull; 8 | import org.jetbrains.annotations.Nullable; 9 | 10 | import java.util.Map; 11 | 12 | /** 13 | * The interface Doc template manager. 14 | * 15 | * @author Sergey Timofiychuk 16 | */ 17 | public interface DocTemplateManager { 18 | 19 | /** 20 | * Gets the class template. 21 | * 22 | * @param classElement the Class element 23 | * @return the Class template 24 | */ 25 | @Nullable 26 | Template getClassTemplate(@NotNull PsiClass classElement); 27 | 28 | /** 29 | * Gets class templates. 30 | * 31 | * @return the class templates 32 | */ 33 | @NotNull 34 | Map getClassTemplates(); 35 | 36 | /** 37 | * Sets class templates. 38 | * 39 | * @param templates the templates 40 | */ 41 | void setClassTemplates(@NotNull Map templates); 42 | 43 | /** 44 | * Gets the method template. 45 | * 46 | * @param methodElement the Method element 47 | * @return the Method template 48 | */ 49 | @Nullable 50 | Template getMethodTemplate(@NotNull PsiMethod methodElement); 51 | 52 | /** 53 | * Gets method templates. 54 | * 55 | * @return the method templates 56 | */ 57 | @NotNull 58 | Map getMethodTemplates(); 59 | 60 | /** 61 | * Sets method templates. 62 | * 63 | * @param templates the templates 64 | */ 65 | void setMethodTemplates(@NotNull Map templates); 66 | 67 | /** 68 | * Gets constructor templates. 69 | * 70 | * @return the constructor templates 71 | */ 72 | @NotNull 73 | Map getConstructorTemplates(); 74 | 75 | /** 76 | * Sets constructor templates. 77 | * 78 | * @param templates the templates 79 | */ 80 | void setConstructorTemplates(@NotNull Map templates); 81 | 82 | /** 83 | * Gets the field template. 84 | * 85 | * @param psiField the Field element 86 | * @return the Field template 87 | */ 88 | @Nullable 89 | Template getFieldTemplate(@NotNull PsiField psiField); 90 | 91 | /** 92 | * Gets field templates. 93 | * 94 | * @return the field templates 95 | */ 96 | @NotNull 97 | Map getFieldTemplates(); 98 | 99 | /** 100 | * Sets field templates. 101 | * 102 | * @param templates the templates 103 | */ 104 | void setFieldTemplates(@NotNull Map templates); 105 | 106 | } 107 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/template/DocTemplateProcessor.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.template; 2 | 3 | import freemarker.template.Template; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | import java.util.Map; 7 | 8 | /** 9 | * The interface Doc template processor. 10 | * 11 | * @author Sergey Timofiychuk 12 | */ 13 | public interface DocTemplateProcessor { 14 | 15 | /** 16 | * Merge. 17 | * 18 | * @param template the Template 19 | * @param params the Params 20 | * @return the String 21 | */ 22 | @NotNull 23 | String merge(@NotNull Template template, @NotNull Map params); 24 | 25 | /** 26 | * Builds the description. 27 | * 28 | * @param description the Description 29 | * @param capitalizeFirst the flag shows whether first word should be capitalized 30 | * @return generated description 31 | */ 32 | @NotNull 33 | String buildDescription(@NotNull String description, boolean capitalizeFirst); 34 | 35 | /** 36 | * Builds the description for the methods like getter, setter. There will be removed first word, e.g. get, set, 37 | * etc. 38 | * 39 | * @param description the description 40 | * @return generated description 41 | */ 42 | @NotNull 43 | String buildPartialDescription(@NotNull String description); 44 | 45 | /** 46 | * Builds the description for the methods like getter, setter. The result will be a field name for get/set method. 47 | * 48 | * @param description the description 49 | * @return generated description 50 | */ 51 | @NotNull 52 | String buildFieldDescription(@NotNull String description); 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/template/impl/DocTemplateManagerImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.template.impl; 2 | 3 | import com.github.setial.intellijjavadocs.exception.SetupTemplateException; 4 | import com.github.setial.intellijjavadocs.exception.TemplateNotFoundException; 5 | import com.github.setial.intellijjavadocs.template.DocTemplateManager; 6 | import com.github.setial.intellijjavadocs.template.DocTemplateProcessor; 7 | import com.github.setial.intellijjavadocs.utils.XmlUtils; 8 | import com.intellij.openapi.diagnostic.Logger; 9 | import com.intellij.openapi.util.JDOMUtil; 10 | import com.intellij.psi.PsiClass; 11 | import com.intellij.psi.PsiClassType; 12 | import com.intellij.psi.PsiCodeBlock; 13 | import com.intellij.psi.PsiField; 14 | import com.intellij.psi.PsiMethod; 15 | import com.intellij.psi.PsiModifierList; 16 | import freemarker.cache.StringTemplateLoader; 17 | import freemarker.template.Configuration; 18 | import freemarker.template.Template; 19 | import org.apache.commons.lang3.StringUtils; 20 | import org.jdom.Element; 21 | import org.jetbrains.annotations.NotNull; 22 | import org.jetbrains.annotations.Nullable; 23 | 24 | import java.io.IOException; 25 | import java.io.StringWriter; 26 | import java.io.Writer; 27 | import java.nio.charset.StandardCharsets; 28 | import java.util.LinkedHashMap; 29 | import java.util.List; 30 | import java.util.Map; 31 | import java.util.Map.Entry; 32 | import java.util.regex.Pattern; 33 | 34 | /** 35 | * The type Doc template manager impl. 36 | * 37 | * @author Sergey Timofiychuk 38 | */ 39 | public class DocTemplateManagerImpl implements DocTemplateManager { 40 | 41 | private static final Logger LOGGER = Logger.getInstance(DocTemplateManagerImpl.class); 42 | 43 | private static final String TEMPLATES_PATH = "/templates.xml"; 44 | private static final String TEMPLATE = "template"; 45 | private static final String REGEXP = "regexp"; 46 | private static final String CLASS = "class"; 47 | private static final String FIELD = "field"; 48 | private static final String METHOD = "method"; 49 | private static final String CONSTRUCTOR = "constructor"; 50 | 51 | private Map classTemplates = new LinkedHashMap<>(); 52 | private Map fieldTemplates = new LinkedHashMap<>(); 53 | private Map methodTemplates = new LinkedHashMap<>(); 54 | private Map constructorTemplates = new LinkedHashMap<>(); 55 | 56 | private Configuration config; 57 | private StringTemplateLoader templateLoader; 58 | 59 | /** 60 | * Instantiates a new Doc template manager object. 61 | */ 62 | public DocTemplateManagerImpl() { 63 | templateLoader = new StringTemplateLoader(); 64 | config = new Configuration(Configuration.VERSION_2_3_23); 65 | config.setDefaultEncoding(StandardCharsets.UTF_8.name()); 66 | config.setLocalizedLookup(false); 67 | config.setTemplateLoader(templateLoader); 68 | 69 | try { 70 | Element root = JDOMUtil.load(DocTemplateProcessor.class.getResourceAsStream(TEMPLATES_PATH)); 71 | if (root != null) { 72 | readTemplates(root, CLASS, classTemplates); 73 | readTemplates(root, FIELD, fieldTemplates); 74 | readTemplates(root, METHOD, methodTemplates); 75 | readTemplates(root, CONSTRUCTOR, constructorTemplates); 76 | } 77 | } catch (Exception e) { 78 | LOGGER.error(e); 79 | } 80 | } 81 | 82 | @Nullable 83 | @Override 84 | public Template getClassTemplate(@NotNull PsiClass classElement) { 85 | StringBuilder builder = getClassSignature(classElement); 86 | return getMatchingTemplate(builder.toString(), classTemplates); 87 | } 88 | 89 | @Nullable 90 | @Override 91 | public Template getMethodTemplate(@NotNull PsiMethod methodElement) { 92 | Map templates; 93 | if (methodElement.isConstructor()) { 94 | templates = constructorTemplates; 95 | } else { 96 | templates = methodTemplates; 97 | } 98 | String signature = methodElement.getText(); 99 | PsiCodeBlock methodBody = methodElement.getBody(); 100 | if (methodBody != null) { 101 | signature = signature.replace(methodBody.getText(), ""); 102 | } 103 | return getMatchingTemplate(signature, templates); 104 | 105 | } 106 | 107 | @Nullable 108 | @Override 109 | public Template getFieldTemplate(@NotNull PsiField psiField) { 110 | return getMatchingTemplate(psiField.getText(), fieldTemplates); 111 | 112 | } 113 | 114 | @NotNull 115 | @Override 116 | public Map getClassTemplates() { 117 | Map templates = new LinkedHashMap<>(); 118 | for (Entry entry : classTemplates.entrySet()) { 119 | String template = extractTemplate(entry.getValue()); 120 | templates.put(entry.getKey(), template); 121 | } 122 | return templates; 123 | } 124 | 125 | @NotNull 126 | @Override 127 | public Map getConstructorTemplates() { 128 | Map templates = new LinkedHashMap<>(); 129 | for (Entry entry : constructorTemplates.entrySet()) { 130 | String template = extractTemplate(entry.getValue()); 131 | templates.put(entry.getKey(), template); 132 | } 133 | return templates; 134 | } 135 | 136 | @NotNull 137 | @Override 138 | public Map getMethodTemplates() { 139 | Map templates = new LinkedHashMap<>(); 140 | for (Entry entry : methodTemplates.entrySet()) { 141 | String template = extractTemplate(entry.getValue()); 142 | templates.put(entry.getKey(), template); 143 | } 144 | return templates; 145 | } 146 | 147 | @NotNull 148 | @Override 149 | public Map getFieldTemplates() { 150 | Map templates = new LinkedHashMap<>(); 151 | for (Entry entry : fieldTemplates.entrySet()) { 152 | String template = extractTemplate(entry.getValue()); 153 | templates.put(entry.getKey(), template); 154 | } 155 | return templates; 156 | } 157 | 158 | @Override 159 | public void setClassTemplates(@NotNull Map templates) { 160 | setupTemplates(templates, classTemplates, CLASS); 161 | } 162 | 163 | @Override 164 | public void setConstructorTemplates(@NotNull Map templates) { 165 | setupTemplates(templates, constructorTemplates, CONSTRUCTOR); 166 | } 167 | 168 | @Override 169 | public void setMethodTemplates(@NotNull Map templates) { 170 | setupTemplates(templates, methodTemplates, METHOD); 171 | } 172 | 173 | @Override 174 | public void setFieldTemplates(@NotNull Map templates) { 175 | setupTemplates(templates, fieldTemplates, FIELD); 176 | } 177 | 178 | private void readTemplates(Element document, String elementName, Map templates) 179 | throws IOException { 180 | Element root = document.getChild(elementName); 181 | List elements = root.getChildren(TEMPLATE); 182 | for (Element element : elements) { 183 | String name = element.getAttribute(REGEXP).getValue(); 184 | templates.put(name, createTemplate(name, elementName, XmlUtils.trimElementContent(element))); 185 | } 186 | } 187 | 188 | @NotNull 189 | private Template getMatchingTemplate(@NotNull String elementText, @NotNull Map templates) { 190 | Template result = null; 191 | for (Entry entry : templates.entrySet()) { 192 | if (Pattern.compile(entry.getKey(), Pattern.DOTALL | Pattern.MULTILINE).matcher(elementText).matches()) { 193 | result = entry.getValue(); 194 | break; 195 | } 196 | } 197 | if (result == null) { 198 | throw new TemplateNotFoundException(elementText); 199 | } 200 | return result; 201 | } 202 | 203 | private void setupTemplates(Map from, Map to, String elementName) { 204 | Map result = new LinkedHashMap<>(); 205 | for (Entry entry : from.entrySet()) { 206 | try { 207 | result.put(entry.getKey(), createTemplate(entry.getKey(), elementName, entry.getValue())); 208 | } catch (Exception e) { 209 | throw new SetupTemplateException(e); 210 | } 211 | } 212 | to.clear(); 213 | to.putAll(result); 214 | } 215 | 216 | private StringBuilder getClassSignature(PsiClass classElement) { 217 | StringBuilder builder = new StringBuilder(); 218 | PsiModifierList modifierList = classElement.getModifierList(); 219 | if (modifierList != null) { 220 | builder.append(modifierList.getText()); 221 | } 222 | builder.append(" "); 223 | if (classElement.isInterface()) { 224 | builder.append("interface "); 225 | } else if (classElement.isEnum()) { 226 | builder.append("enum "); 227 | } else { 228 | builder.append("class "); 229 | } 230 | builder.append(classElement.getName()); 231 | builder.append(" "); 232 | PsiClassType[] extendsTypes = classElement.getExtendsListTypes(); 233 | if (extendsTypes.length > 0) { 234 | builder.append("extends "); 235 | for (int i = 0; i < extendsTypes.length; i++) { 236 | PsiClassType extendsType = extendsTypes[i]; 237 | builder.append(extendsType.getClassName()); 238 | if (i < extendsTypes.length - 1) { 239 | builder.append(","); 240 | } 241 | builder.append(" "); 242 | } 243 | } 244 | PsiClassType[] implementTypes = classElement.getImplementsListTypes(); 245 | if (implementTypes.length > 0) { 246 | builder.append("implements"); 247 | for (int i = 0; i < implementTypes.length; i++) { 248 | PsiClassType implementType = implementTypes[i]; 249 | builder.append(implementType.getClassName()); 250 | if (i < implementTypes.length - 1) { 251 | builder.append(","); 252 | } 253 | builder.append(" "); 254 | } 255 | } 256 | return builder; 257 | } 258 | 259 | private Template createTemplate(String templateRegexp, String elementName, String templateContent) throws IOException { 260 | String templateName = normalizeName(elementName + templateRegexp); 261 | if (templateLoader.findTemplateSource(templateName) != null) { 262 | config.clearTemplateCache(); 263 | } 264 | templateLoader.putTemplate(templateName, templateContent); 265 | return config.getTemplate(templateName); 266 | } 267 | 268 | private String normalizeName(String templateName) { 269 | String result = templateName.replaceAll("\\*", "_"); 270 | result = result.replaceAll("\\.", "_"); 271 | return result; 272 | } 273 | 274 | private String extractTemplate(Template templateData) { 275 | Writer writer = new StringWriter(); 276 | try { 277 | templateData.dump(writer); 278 | } catch (IOException e) { 279 | return StringUtils.EMPTY; 280 | } 281 | return writer.toString(); 282 | } 283 | 284 | } 285 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/template/impl/DocTemplateProcessorImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.template.impl; 2 | 3 | import com.github.setial.intellijjavadocs.exception.SetupTemplateException; 4 | import com.github.setial.intellijjavadocs.template.DocTemplateProcessor; 5 | import com.github.setial.intellijjavadocs.utils.XmlUtils; 6 | import freemarker.template.Template; 7 | import org.apache.commons.lang3.StringUtils; 8 | import org.jetbrains.annotations.NotNull; 9 | 10 | import java.io.StringWriter; 11 | import java.util.ArrayList; 12 | import java.util.Arrays; 13 | import java.util.List; 14 | import java.util.Map; 15 | 16 | /** 17 | * The type Doc template processor impl. 18 | * 19 | * @author Sergey Timofiychuk 20 | */ 21 | public class DocTemplateProcessorImpl implements DocTemplateProcessor { 22 | 23 | private static final List SPECIAL_SYMBOLS = Arrays.asList("_", "$"); 24 | 25 | @NotNull 26 | @Override 27 | public String merge(@NotNull Template template, @NotNull Map params) { 28 | StringWriter writer = new StringWriter(); 29 | try { 30 | template.process(params, writer); 31 | return XmlUtils.normalizeTemplate(writer.toString()); 32 | } catch (Exception e) { 33 | throw new SetupTemplateException(e); 34 | } 35 | } 36 | 37 | @NotNull 38 | @Override 39 | public String buildDescription(@NotNull String description, boolean capitalizeFirst) { 40 | if (StringUtils.isBlank(description)) { 41 | return StringUtils.EMPTY; 42 | } 43 | return buildDescription(description, 0, capitalizeFirst); 44 | } 45 | 46 | @NotNull 47 | @Override 48 | public String buildPartialDescription(@NotNull String description) { 49 | if (StringUtils.isBlank(description)) { 50 | return StringUtils.EMPTY; 51 | } 52 | return buildDescription(description, 1, false); 53 | } 54 | 55 | @NotNull 56 | @Override 57 | public String buildFieldDescription(@NotNull String description) { 58 | if (StringUtils.isBlank(description)) { 59 | return StringUtils.EMPTY; 60 | } 61 | String[] parts = StringUtils.splitByCharacterTypeCamelCase(description.replaceAll("<.+>", "")); 62 | StringBuilder result = new StringBuilder(); 63 | for (int i = 1; i < parts.length; i++) { 64 | if (i > 1) { 65 | result.append(StringUtils.capitalize(parts[i])); 66 | } else { 67 | result.append(StringUtils.uncapitalize(parts[i])); 68 | } 69 | } 70 | return result.toString(); 71 | } 72 | 73 | private String buildDescription(String description, int firstElement, boolean capitalizeFirst) { 74 | String[] parts = StringUtils.splitByCharacterTypeCamelCase(description.replaceAll("<.+>", "")); 75 | parts = removeInterfacePrefix(parts); 76 | parts = removeClassSuffix(parts); 77 | parts = removeSpecialSymbols(parts); 78 | 79 | StringBuilder result = new StringBuilder(); 80 | for (int i = firstElement; i < parts.length; i++) { 81 | if (capitalizeFirst && i == firstElement) { 82 | result.append(StringUtils.capitalize(StringUtils.lowerCase(parts[i]))); 83 | } else { 84 | result.append(StringUtils.lowerCase(parts[i])); 85 | } 86 | if (i < parts.length - 1) { 87 | result.append(" "); 88 | } 89 | } 90 | return result.toString(); 91 | } 92 | 93 | private String[] removeInterfacePrefix(String[] parts) { 94 | if (parts != null && parts.length > 0 && "I".equalsIgnoreCase(parts[0])) { 95 | parts = Arrays.copyOfRange(parts, 1, parts.length); 96 | } 97 | return parts; 98 | } 99 | 100 | private String[] removeClassSuffix(String[] parts) { 101 | if (parts != null && parts.length > 0 && "Impl".equalsIgnoreCase(parts[parts.length - 1])) { 102 | parts = Arrays.copyOfRange(parts, 0, parts.length - 1); 103 | } 104 | return parts; 105 | } 106 | 107 | private String[] removeSpecialSymbols(String[] parts) { 108 | List result = new ArrayList<>(); 109 | for (String part : parts) { 110 | if (!SPECIAL_SYMBOLS.contains(part)) { 111 | result.add(part); 112 | } 113 | } 114 | return result.toArray(new String[result.size()]); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/transformation/JavaDocBuilder.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.transformation; 2 | 3 | import com.github.setial.intellijjavadocs.model.JavaDoc; 4 | import com.github.setial.intellijjavadocs.model.JavaDocElements; 5 | import com.github.setial.intellijjavadocs.model.JavaDocTag; 6 | import org.apache.commons.lang3.StringUtils; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | import java.util.Iterator; 10 | import java.util.List; 11 | import java.util.Map; 12 | import java.util.Map.Entry; 13 | 14 | /** 15 | * The type Java doc builder. 16 | * 17 | * @author Sergey Timofiychuk 18 | */ 19 | public class JavaDocBuilder { 20 | 21 | private StringBuilder builder; 22 | 23 | /** 24 | * Instantiates a new Java doc builder. 25 | */ 26 | public JavaDocBuilder() { 27 | builder = new StringBuilder(); 28 | } 29 | 30 | /** 31 | * Open the java doc section. 32 | * 33 | * @return the Java doc builder 34 | */ 35 | public JavaDocBuilder openJavaDoc() { 36 | builder.append(JavaDocElements.STARTING.getPresentation()); 37 | builder.append(JavaDocElements.LINE_START.getPresentation()); 38 | return this; 39 | } 40 | 41 | /** 42 | * Close the java doc section. 43 | * 44 | * @return the Java doc builder 45 | */ 46 | public JavaDocBuilder closeJavaDoc() { 47 | // add new line with asterisk if it's not new line 48 | if (!closeRegularJavaDoc()) { 49 | closeOneLineJavaDoc(); 50 | } 51 | builder.append(JavaDocElements.ENDING.getPresentation()); 52 | return this; 53 | } 54 | 55 | /** 56 | * Add new line to javadoc section. 57 | * 58 | * @return the Java doc builder 59 | */ 60 | public JavaDocBuilder addNewLine() { 61 | builder.append(JavaDocElements.NEW_LINE.getPresentation()); 62 | builder.append(JavaDocElements.LINE_START.getPresentation()); 63 | return this; 64 | } 65 | 66 | /** 67 | * Add description to javadoc section. 68 | * 69 | * @param descriptions the Descriptions 70 | * @return the Java doc builder 71 | */ 72 | public JavaDocBuilder addDescription(List descriptions) { 73 | Iterator iterator = descriptions.iterator(); 74 | while (iterator.hasNext()) { 75 | String description = iterator.next(); 76 | if (isAcceptedDescription(description, iterator.hasNext())) { 77 | builder.append(description); 78 | if (StringUtils.contains(description, JavaDocElements.NEW_LINE.getPresentation())) { 79 | builder.append(JavaDocElements.LINE_START.getPresentation()); 80 | } 81 | } 82 | } 83 | return this; 84 | } 85 | 86 | /** 87 | * Add tag description to javadoc section. 88 | * 89 | * @param descriptions the Descriptions 90 | * @return the Java doc builder 91 | */ 92 | public JavaDocBuilder addTagDescription(List descriptions) { 93 | for (int i = 0; i < descriptions.size(); i++) { 94 | String description = descriptions.get(i); 95 | if (StringUtils.isNotBlank(description)) { 96 | if (i != 0) { 97 | addNewLine(); 98 | } 99 | builder.append(description); 100 | } 101 | } 102 | return this; 103 | } 104 | 105 | /** 106 | * Add tag to javadoc section. 107 | * 108 | * @param name the Name 109 | * @param tag the Tag 110 | * @return the Java doc builder 111 | */ 112 | public JavaDocBuilder addTag(String name, JavaDocTag tag) { 113 | builder.append(JavaDocElements.WHITE_SPACE.getPresentation()); 114 | builder.append(JavaDocElements.TAG_START.getPresentation()); 115 | builder.append(name); 116 | builder.append(JavaDocElements.WHITE_SPACE.getPresentation()); 117 | 118 | if (StringUtils.isNotBlank(tag.getRefParam())) { 119 | builder.append(tag.getRefParam()); 120 | } else if (StringUtils.isNotBlank(tag.getValue())) { 121 | builder.append(tag.getValue()); 122 | } 123 | 124 | builder.append(JavaDocElements.WHITE_SPACE.getPresentation()); 125 | addTagDescription(tag.getDescription()); 126 | return this; 127 | } 128 | 129 | /** 130 | * Add tags to javadoc section. 131 | * 132 | * @param tags the Tags 133 | * @return the Java doc builder 134 | */ 135 | public JavaDocBuilder addTags(@NotNull Map> tags) { 136 | Iterator>> iterator = tags.entrySet().iterator(); 137 | while (iterator.hasNext()) { 138 | Entry> entry = iterator.next(); 139 | String name = entry.getKey(); 140 | Iterator javaDocTagsIterator = entry.getValue().iterator(); 141 | while (javaDocTagsIterator.hasNext()) { 142 | JavaDocTag javaDocTag = javaDocTagsIterator.next(); 143 | addTag(name, javaDocTag); 144 | if (javaDocTagsIterator.hasNext()) { 145 | addNewLine(); 146 | } 147 | } 148 | if (iterator.hasNext()) { 149 | addNewLine(); 150 | } 151 | } 152 | return this; 153 | } 154 | 155 | /** 156 | * Creates the java doc by default rules. 157 | * 158 | * @param javadoc the Javadoc 159 | * @return the Java doc builder 160 | */ 161 | public JavaDocBuilder createDefaultJavaDoc(@NotNull JavaDoc javadoc) { 162 | openJavaDoc(); 163 | addDescription(javadoc.getDescription()); 164 | addTags(javadoc.getTags()); 165 | closeJavaDoc(); 166 | return this; 167 | } 168 | 169 | /** 170 | * Builds the javadoc section. 171 | * 172 | * @return the String 173 | */ 174 | @NotNull 175 | public String build() { 176 | return builder.toString(); 177 | } 178 | 179 | private boolean closeRegularJavaDoc() { 180 | boolean result = false; 181 | if (builder.lastIndexOf(JavaDocElements.LINE_START.getPresentation()) != builder.length() - 1 && 182 | builder.lastIndexOf(JavaDocElements.NEW_LINE.getPresentation()) >= 0) { 183 | builder.append(JavaDocElements.NEW_LINE.getPresentation()); 184 | builder.append(JavaDocElements.WHITE_SPACE.getPresentation()); 185 | builder.append(JavaDocElements.LINE_START.getPresentation()); 186 | result = true; 187 | } 188 | return result; 189 | } 190 | 191 | private boolean closeOneLineJavaDoc() { 192 | boolean result = false; 193 | if (builder.indexOf(JavaDocElements.NEW_LINE.getPresentation()) < 0) { 194 | builder.append(JavaDocElements.LINE_START.getPresentation()); 195 | result = true; 196 | } 197 | return result; 198 | } 199 | 200 | private boolean isAcceptedDescription(String description, boolean hasNext) { 201 | boolean result = false; 202 | // add any not empty string (it could be blank), but do not add last string if this is a space 203 | if ((hasNext && StringUtils.isNotEmpty(description)) || 204 | (!hasNext && !description.matches(" +"))) { 205 | result = true; 206 | } 207 | return result; 208 | } 209 | 210 | } 211 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/ui/component/TemplateConfigDialog.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.ui.component; 2 | 3 | import com.intellij.openapi.ui.DialogWrapper; 4 | import com.intellij.ui.IdeBorderFactory; 5 | import com.intellij.uiDesigner.core.GridConstraints; 6 | import com.intellij.uiDesigner.core.GridLayoutManager; 7 | import com.intellij.util.ui.JBUI; 8 | import org.jetbrains.annotations.Nullable; 9 | 10 | import javax.swing.*; 11 | import java.awt.*; 12 | import java.util.HashMap; 13 | import java.util.Map; 14 | import java.util.Map.Entry; 15 | 16 | /** 17 | * The type Template config dialog. 18 | * 19 | * @author Sergey Timofiychuk 20 | */ 21 | public class TemplateConfigDialog extends DialogWrapper { 22 | 23 | private Entry model; 24 | 25 | private JTextField nameField; 26 | private JTextArea templateField; 27 | 28 | /** 29 | * Instantiates a new Template config dialog. 30 | */ 31 | public TemplateConfigDialog() { 32 | this(null); 33 | } 34 | 35 | /** 36 | * Instantiates a new Template config dialog. 37 | * 38 | * @param model the model 39 | */ 40 | public TemplateConfigDialog(Entry model) { 41 | super(true); 42 | if (model != null) { 43 | Map modelCopy = new HashMap<>(); 44 | modelCopy.put(model.getKey(), model.getValue()); 45 | this.model = modelCopy.entrySet().iterator().next(); 46 | } 47 | init(); 48 | } 49 | 50 | /** 51 | * Gets table model. 52 | * 53 | * @return the model 54 | */ 55 | public Entry getModel() { 56 | Map model = new HashMap<>(); 57 | model.put(nameField.getText(), templateField.getText()); 58 | return model.entrySet().iterator().next(); 59 | } 60 | 61 | @Nullable 62 | @Override 63 | protected JComponent createCenterPanel() { 64 | JPanel panel = new JPanel(new BorderLayout()); 65 | panel.setLayout(new GridLayoutManager(2, 1, JBUI.insets(10, 10, 10, 10), -1, -1)); 66 | 67 | nameField = new JTextField(); 68 | if (model != null) { 69 | nameField.setText(model.getKey()); 70 | } 71 | JPanel namePanel = new JPanel(new BorderLayout()); 72 | namePanel.setBorder(IdeBorderFactory.createTitledBorder("Template regexp", false, JBUI.insets(0, 0, 10, 0))); 73 | namePanel.add(nameField, BorderLayout.CENTER); 74 | 75 | templateField = new JTextArea(); 76 | if (model != null) { 77 | templateField.setText(model.getValue()); 78 | } 79 | JPanel templatePanel = new JPanel(new BorderLayout()); 80 | templatePanel.setBorder(IdeBorderFactory.createTitledBorder("Template content", false, JBUI.insets(0, 0, 0, 0))); 81 | templatePanel.add(templateField, BorderLayout.CENTER); 82 | 83 | panel.add(namePanel, getConstraints(0, 0)); 84 | panel.add(templatePanel, getConstraints(1, 0)); 85 | return panel; 86 | } 87 | 88 | private GridConstraints getConstraints(int row, int column) { 89 | return new GridConstraints(row, column, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false); 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/ui/component/TemplatesTable.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.ui.component; 2 | 3 | import com.intellij.ui.table.JBTable; 4 | import com.intellij.util.ui.EditableModel; 5 | import com.intellij.util.ui.UIUtil; 6 | import org.apache.commons.collections.CollectionUtils; 7 | import org.apache.commons.collections.MapUtils; 8 | 9 | import javax.swing.BorderFactory; 10 | import javax.swing.JLabel; 11 | import javax.swing.JTable; 12 | import javax.swing.table.AbstractTableModel; 13 | import javax.swing.table.TableCellRenderer; 14 | import javax.swing.table.TableColumn; 15 | import java.awt.Component; 16 | import java.awt.event.MouseEvent; 17 | import java.util.Enumeration; 18 | import java.util.EventObject; 19 | import java.util.LinkedHashMap; 20 | import java.util.LinkedList; 21 | import java.util.List; 22 | import java.util.Map; 23 | import java.util.Map.Entry; 24 | 25 | /** 26 | * The type Templates table. 27 | * 28 | * @author Sergey Timofiychuk 29 | */ 30 | public class TemplatesTable extends JBTable { 31 | 32 | private List> settings; 33 | 34 | /** 35 | * Instantiates a new Templates table. 36 | * 37 | * @param model the model 38 | */ 39 | public TemplatesTable(Map model) { 40 | setStriped(true); 41 | setAutoResizeMode(AUTO_RESIZE_ALL_COLUMNS); 42 | settings = new LinkedList<>(); 43 | CollectionUtils.addAll(settings, model.entrySet().toArray(new Entry[model.entrySet().size()])); 44 | setModel(new TableModel()); 45 | Enumeration columns = getColumnModel().getColumns(); 46 | while (columns.hasMoreElements()) { 47 | columns.nextElement().setCellRenderer(new FieldRenderer()); 48 | } 49 | } 50 | 51 | /** 52 | * Gets settings model. 53 | * 54 | * @return clone of the original settings model 55 | */ 56 | @SuppressWarnings("unchecked") 57 | public Map getSettings() { 58 | return MapUtils.putAll(new LinkedHashMap(), settings.toArray()); 59 | } 60 | 61 | /** 62 | * Sets settings model. 63 | * 64 | * @param model the model 65 | */ 66 | public void setSettingsModel(Map model) { 67 | settings.clear(); 68 | CollectionUtils.addAll(settings, model.entrySet().toArray(new Entry[model.entrySet().size()])); 69 | ((TableModel) getModel()).fireTableDataChanged(); 70 | } 71 | 72 | @Override 73 | public boolean editCellAt(int row, int column, EventObject e) { 74 | if (e == null) { 75 | return false; 76 | } 77 | if (e instanceof MouseEvent) { 78 | MouseEvent event = (MouseEvent) e; 79 | if (event.getClickCount() == 1) { 80 | return false; 81 | } 82 | } 83 | TemplateConfigDialog dialog = new TemplateConfigDialog(settings.get(row)); 84 | dialog.show(); 85 | if (dialog.isOK()) { 86 | settings.set(row, dialog.getModel()); 87 | } 88 | return false; 89 | } 90 | 91 | private class TableModel extends AbstractTableModel implements EditableModel { 92 | 93 | private List columnNames; 94 | 95 | /** 96 | * Instantiates a new Table model. 97 | */ 98 | public TableModel() { 99 | columnNames = new LinkedList<>(); 100 | columnNames.add("Regular expression"); 101 | columnNames.add("Preview"); 102 | } 103 | 104 | @Override 105 | public String getColumnName(int column) { 106 | return columnNames.get(column); 107 | } 108 | 109 | @Override 110 | public void addRow() { 111 | TemplateConfigDialog dialog = new TemplateConfigDialog(); 112 | dialog.show(); 113 | if (dialog.isOK()) { 114 | settings.add(dialog.getModel()); 115 | } 116 | } 117 | 118 | @Override 119 | public void removeRow(int index) { 120 | settings.remove(index); 121 | } 122 | 123 | @Override 124 | public void exchangeRows(int oldIndex, int newIndex) { 125 | Entry oldItem = settings.get(oldIndex); 126 | settings.set(oldIndex, settings.get(newIndex)); 127 | settings.set(newIndex, oldItem); 128 | } 129 | 130 | @Override 131 | public boolean canExchangeRows(int oldIndex, int newIndex) { 132 | return true; 133 | } 134 | 135 | @Override 136 | public int getRowCount() { 137 | return settings.size(); 138 | } 139 | 140 | @Override 141 | public int getColumnCount() { 142 | return columnNames.size(); 143 | } 144 | 145 | @Override 146 | public Object getValueAt(int rowIndex, int columnIndex) { 147 | return columnIndex == 0 ? settings.get(rowIndex).getKey() : settings.get(rowIndex).getValue(); 148 | } 149 | 150 | } 151 | 152 | private static class FieldRenderer extends JLabel implements TableCellRenderer { 153 | 154 | /** 155 | * Instantiates a new Field renderer. 156 | */ 157 | public FieldRenderer() { 158 | setOpaque(true); 159 | } 160 | 161 | @Override 162 | public Component getTableCellRendererComponent( 163 | JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 164 | 165 | setBackground(isSelected ? table.getSelectionBackground() : table.getBackground()); 166 | setForeground(isSelected ? table.getSelectionForeground() : table.getForeground()); 167 | 168 | setBorder(hasFocus ? 169 | UIUtil.getTableFocusCellHighlightBorder() : BorderFactory.createEmptyBorder(1, 1, 1, 1)); 170 | setText(value == null ? "" : value.toString()); 171 | return this; 172 | } 173 | 174 | } 175 | 176 | 177 | } 178 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/ui/settings/ConfigPanel.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.ui.settings; 2 | 3 | import com.github.setial.intellijjavadocs.configuration.JavaDocConfiguration; 4 | import com.intellij.openapi.Disposable; 5 | import com.intellij.openapi.options.ConfigurationException; 6 | import com.intellij.openapi.options.SearchableConfigurable; 7 | import com.intellij.openapi.project.Project; 8 | import java.util.ResourceBundle; 9 | import javax.swing.JComponent; 10 | import org.jetbrains.annotations.Nls; 11 | import org.jetbrains.annotations.NotNull; 12 | import org.jetbrains.annotations.Nullable; 13 | 14 | public class ConfigPanel implements SearchableConfigurable, Disposable { 15 | 16 | private JavaDocConfiguration javaDocConfiguration; 17 | private ConfigPanelGUI configPanelGUI; 18 | private ResourceBundle resourceBundle; 19 | 20 | public ConfigPanel(@NotNull Project project) { 21 | javaDocConfiguration = project.getService(JavaDocConfiguration.class); 22 | resourceBundle = ResourceBundle.getBundle("messages"); 23 | } 24 | 25 | @NotNull 26 | @Override 27 | public String getId() { 28 | return "JavaDoc"; 29 | } 30 | 31 | @Nls(capitalization = Nls.Capitalization.Title) 32 | @Override 33 | public String getDisplayName() { 34 | return resourceBundle.getString("configurable.panel.name"); 35 | } 36 | 37 | @Nullable 38 | @Override 39 | public JComponent createComponent() { 40 | configPanelGUI = new ConfigPanelGUI(javaDocConfiguration.getConfiguration()); 41 | configPanelGUI.reset(); 42 | return configPanelGUI; 43 | } 44 | 45 | @Override 46 | public boolean isModified() { 47 | return configPanelGUI.isModified(); 48 | } 49 | 50 | @Override 51 | public void apply() throws ConfigurationException { 52 | configPanelGUI.apply(); 53 | javaDocConfiguration.setupTemplates(); 54 | } 55 | 56 | @Override 57 | public void dispose() { 58 | configPanelGUI.disposeUIResources(); 59 | configPanelGUI = null; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/ui/settings/ConfigPanelGUI.form: -------------------------------------------------------------------------------- 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 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 |
202 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/ui/settings/ConfigPanelGUI.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.ui.settings; 2 | 3 | import com.github.setial.intellijjavadocs.model.settings.JavaDocSettings; 4 | import com.github.setial.intellijjavadocs.model.settings.Level; 5 | import com.github.setial.intellijjavadocs.model.settings.Mode; 6 | import com.github.setial.intellijjavadocs.model.settings.Visibility; 7 | import com.github.setial.intellijjavadocs.ui.component.TemplatesTable; 8 | import com.intellij.ui.IdeBorderFactory; 9 | import com.intellij.ui.ToolbarDecorator; 10 | import com.intellij.uiDesigner.core.GridConstraints; 11 | import com.intellij.uiDesigner.core.GridLayoutManager; 12 | import com.intellij.uiDesigner.core.Spacer; 13 | import com.intellij.util.ui.JBUI; 14 | 15 | import javax.swing.BorderFactory; 16 | import javax.swing.ButtonGroup; 17 | import javax.swing.JCheckBox; 18 | import javax.swing.JComponent; 19 | import javax.swing.JPanel; 20 | import javax.swing.JRadioButton; 21 | import javax.swing.JTabbedPane; 22 | import java.awt.BorderLayout; 23 | import java.awt.Dimension; 24 | import java.util.Map; 25 | import java.util.Map.Entry; 26 | 27 | /** 28 | * The type Config panel. 29 | * 30 | * @author Sergey Timofiychuk 31 | */ 32 | public class ConfigPanelGUI extends JPanel { 33 | 34 | private JavaDocSettings settings; 35 | 36 | private JTabbedPane tabbedPane; 37 | private JPanel panel; 38 | private JRadioButton generalModeKeepRadioButton; 39 | private JRadioButton generalModeUpdateRadioButton; 40 | private JRadioButton generalModeReplaceRadioButton; 41 | private JCheckBox generalLevelTypeCheckbox; 42 | private JCheckBox generalLevelMethodCheckbox; 43 | private JCheckBox generalLevelFieldCheckbox; 44 | private JCheckBox generalVisibilityPublicCheckbox; 45 | private JCheckBox generalVisibilityProtectedCheckbox; 46 | private JCheckBox generalVisibilityDefaultCheckbox; 47 | private JCheckBox generalVisibilityPrivateCheckbox; 48 | private JCheckBox generalOtherOverriddenMethodsCheckbox; 49 | private JCheckBox generalOtherSplittedClassName; 50 | private JPanel generalPanel; 51 | private JPanel generalModePanel; 52 | private JPanel generalLevelPanel; 53 | private JPanel generalVisibilityPanel; 54 | private JPanel generalOtherPanel; 55 | private TemplatesTable classTemplatesTable; 56 | private TemplatesTable constructorTemplatesTable; 57 | private TemplatesTable methodTemplatesTable; 58 | private TemplatesTable fieldTemplatesTable; 59 | 60 | /** 61 | * Instantiates a new Config panel. 62 | * 63 | * @param settings the settings 64 | */ 65 | public ConfigPanelGUI(JavaDocSettings settings) { 66 | this.settings = settings; 67 | setLayout(new BorderLayout()); 68 | add(panel, BorderLayout.CENTER); 69 | setupBorders(); 70 | setupTemplatesPanel(); 71 | } 72 | 73 | /** 74 | * Checks if form is modified. 75 | * 76 | * @return the boolean 77 | */ 78 | public boolean isModified() { 79 | boolean result = false; 80 | // check if general settings are modified 81 | if (generalModeKeepRadioButton.isSelected()) { 82 | result = settings.getGeneralSettings().getMode() != Mode.KEEP; 83 | } else if (generalModeUpdateRadioButton.isSelected()) { 84 | result = settings.getGeneralSettings().getMode() != Mode.UPDATE; 85 | } else if (generalModeReplaceRadioButton.isSelected()) { 86 | result = settings.getGeneralSettings().getMode() != Mode.REPLACE; 87 | } 88 | result = result || isCheckboxModified(generalLevelTypeCheckbox, settings.getGeneralSettings().getLevels().contains(Level.TYPE)); 89 | result = result || isCheckboxModified(generalLevelMethodCheckbox, settings.getGeneralSettings().getLevels().contains(Level.METHOD)); 90 | result = result || isCheckboxModified(generalLevelFieldCheckbox, settings.getGeneralSettings().getLevels().contains(Level.FIELD)); 91 | result = result || isCheckboxModified( 92 | generalVisibilityPublicCheckbox, settings.getGeneralSettings().getVisibilities().contains(Visibility.PUBLIC)); 93 | result = result || isCheckboxModified( 94 | generalVisibilityProtectedCheckbox, settings.getGeneralSettings().getVisibilities().contains(Visibility.PROTECTED)); 95 | result = result || isCheckboxModified( 96 | generalVisibilityDefaultCheckbox, settings.getGeneralSettings().getVisibilities().contains(Visibility.DEFAULT)); 97 | result = result || isCheckboxModified( 98 | generalVisibilityPrivateCheckbox, settings.getGeneralSettings().getVisibilities().contains(Visibility.PRIVATE)); 99 | result = result || isCheckboxModified(generalOtherOverriddenMethodsCheckbox, settings.getGeneralSettings().isOverriddenMethods()); 100 | result = result || isCheckboxModified(generalOtherSplittedClassName, settings.getGeneralSettings().isSplittedClassName()); 101 | 102 | // check if templates settings are modified 103 | result = result || checkIfTableContentModified(classTemplatesTable.getSettings(), 104 | settings.getTemplateSettings().getClassTemplates()); 105 | result = result || checkIfTableContentModified(constructorTemplatesTable.getSettings(), 106 | settings.getTemplateSettings().getConstructorTemplates()); 107 | result = result || checkIfTableContentModified(methodTemplatesTable.getSettings(), 108 | settings.getTemplateSettings().getMethodTemplates()); 109 | result = result || checkIfTableContentModified(fieldTemplatesTable.getSettings(), 110 | settings.getTemplateSettings().getFieldTemplates()); 111 | 112 | return result; 113 | } 114 | 115 | /** 116 | * Apply settings to the form. 117 | */ 118 | public void apply() { 119 | // apply general settings 120 | if (generalModeKeepRadioButton.isSelected()) { 121 | settings.getGeneralSettings().setMode(Mode.KEEP); 122 | } else if (generalModeUpdateRadioButton.isSelected()) { 123 | settings.getGeneralSettings().setMode(Mode.UPDATE); 124 | } else if (generalModeReplaceRadioButton.isSelected()) { 125 | settings.getGeneralSettings().setMode(Mode.REPLACE); 126 | } 127 | 128 | settings.getGeneralSettings().getLevels().clear(); 129 | if (generalLevelTypeCheckbox.isSelected()) { 130 | settings.getGeneralSettings().getLevels().add(Level.TYPE); 131 | } 132 | if (generalLevelMethodCheckbox.isSelected()) { 133 | settings.getGeneralSettings().getLevels().add(Level.METHOD); 134 | } 135 | if (generalLevelFieldCheckbox.isSelected()) { 136 | settings.getGeneralSettings().getLevels().add(Level.FIELD); 137 | } 138 | 139 | settings.getGeneralSettings().getVisibilities().clear(); 140 | if (generalVisibilityPublicCheckbox.isSelected()) { 141 | settings.getGeneralSettings().getVisibilities().add(Visibility.PUBLIC); 142 | } 143 | if (generalVisibilityProtectedCheckbox.isSelected()) { 144 | settings.getGeneralSettings().getVisibilities().add(Visibility.PROTECTED); 145 | } 146 | if (generalVisibilityDefaultCheckbox.isSelected()) { 147 | settings.getGeneralSettings().getVisibilities().add(Visibility.DEFAULT); 148 | } 149 | if (generalVisibilityPrivateCheckbox.isSelected()) { 150 | settings.getGeneralSettings().getVisibilities().add(Visibility.PRIVATE); 151 | } 152 | 153 | settings.getGeneralSettings().setOverriddenMethods(generalOtherOverriddenMethodsCheckbox.isSelected()); 154 | settings.getGeneralSettings().setSplittedClassName(generalOtherSplittedClassName.isSelected()); 155 | 156 | // apply templates settings 157 | settings.getTemplateSettings().setClassTemplates(classTemplatesTable.getSettings()); 158 | settings.getTemplateSettings().setConstructorTemplates(constructorTemplatesTable.getSettings()); 159 | settings.getTemplateSettings().setMethodTemplates(methodTemplatesTable.getSettings()); 160 | settings.getTemplateSettings().setFieldTemplates(fieldTemplatesTable.getSettings()); 161 | } 162 | 163 | /** 164 | * Reset form selection. 165 | */ 166 | public void reset() { 167 | // reset general settings 168 | switch (settings.getGeneralSettings().getMode()) { 169 | case KEEP: 170 | generalModeKeepRadioButton.setSelected(true); 171 | break; 172 | case UPDATE: 173 | generalModeUpdateRadioButton.setSelected(true); 174 | break; 175 | case REPLACE: 176 | default: 177 | generalModeReplaceRadioButton.setSelected(true); 178 | break; 179 | } 180 | for (Level level : settings.getGeneralSettings().getLevels()) { 181 | switch (level) { 182 | case TYPE: 183 | generalLevelTypeCheckbox.setSelected(true); 184 | break; 185 | case METHOD: 186 | generalLevelMethodCheckbox.setSelected(true); 187 | break; 188 | case FIELD: 189 | generalLevelFieldCheckbox.setSelected(true); 190 | break; 191 | } 192 | } 193 | for (Visibility visibility : settings.getGeneralSettings().getVisibilities()) { 194 | switch (visibility) { 195 | case PUBLIC: 196 | generalVisibilityPublicCheckbox.setSelected(true); 197 | break; 198 | case PROTECTED: 199 | generalVisibilityProtectedCheckbox.setSelected(true); 200 | break; 201 | case DEFAULT: 202 | generalVisibilityDefaultCheckbox.setSelected(true); 203 | break; 204 | case PRIVATE: 205 | generalVisibilityPrivateCheckbox.setSelected(true); 206 | break; 207 | } 208 | } 209 | generalOtherOverriddenMethodsCheckbox.setSelected(settings.getGeneralSettings().isOverriddenMethods()); 210 | generalOtherSplittedClassName.setSelected(settings.getGeneralSettings().isSplittedClassName()); 211 | 212 | // reset templates settings 213 | classTemplatesTable.setSettingsModel(settings.getTemplateSettings().getClassTemplates()); 214 | constructorTemplatesTable.setSettingsModel(settings.getTemplateSettings().getConstructorTemplates()); 215 | methodTemplatesTable.setSettingsModel(settings.getTemplateSettings().getMethodTemplates()); 216 | fieldTemplatesTable.setSettingsModel(settings.getTemplateSettings().getFieldTemplates()); 217 | } 218 | 219 | /** 220 | * Dispose uI resources. 221 | */ 222 | public void disposeUIResources() { 223 | } 224 | 225 | @SuppressWarnings("unchecked") 226 | private boolean checkIfTableContentModified(Map templatesTableSettings, 227 | Map templatesSettings) { 228 | boolean result = false; 229 | 230 | Entry[] templatesTableEntries = 231 | templatesTableSettings.entrySet().toArray(new Entry[templatesTableSettings.size()]); 232 | Entry[] templatesEntries = 233 | templatesSettings.entrySet().toArray(new Entry[templatesSettings.size()]); 234 | if (templatesEntries.length == templatesTableEntries.length) { 235 | for (int i = 0; i < templatesEntries.length; i++) { 236 | result = result || !templatesEntries[i].getKey().equals(templatesTableEntries[i].getKey()); 237 | result = result || !templatesEntries[i].getValue().equals(templatesTableEntries[i].getValue()); 238 | } 239 | } else { 240 | result = true; 241 | } 242 | return result; 243 | } 244 | 245 | private boolean isCheckboxModified(JCheckBox checkbox, boolean oldValue) { 246 | return checkbox.isSelected() != oldValue; 247 | } 248 | 249 | private void setupBorders() { 250 | generalModePanel.setBorder( 251 | IdeBorderFactory.createTitledBorder("Mode", false, JBUI.insets(0, 0, 0, 10))); 252 | generalLevelPanel.setBorder( 253 | IdeBorderFactory.createTitledBorder("Level", false, JBUI.insets(0, 0, 0, 10))); 254 | generalVisibilityPanel.setBorder( 255 | IdeBorderFactory.createTitledBorder("Visibility", false, JBUI.insets(0, 0, 0, 0))); 256 | generalOtherPanel.setBorder( 257 | IdeBorderFactory.createTitledBorder("Other", false, JBUI.insets(10, 0, 10, 10))); 258 | } 259 | 260 | private void setupTemplatesPanel() { 261 | classTemplatesTable = new TemplatesTable(settings.getTemplateSettings().getClassTemplates()); 262 | JPanel classTemplatesLocalPanel = ToolbarDecorator.createDecorator(classTemplatesTable).createPanel(); 263 | JPanel classPanel = new JPanel(new BorderLayout()); 264 | classPanel.setBorder(IdeBorderFactory.createTitledBorder("Class level", false, JBUI.insets(0, 0, 10, 0))); 265 | classPanel.add(classTemplatesLocalPanel, BorderLayout.CENTER); 266 | 267 | constructorTemplatesTable = new TemplatesTable(settings.getTemplateSettings().getConstructorTemplates()); 268 | JPanel constructorTemplatesLocalPanel = 269 | ToolbarDecorator.createDecorator(constructorTemplatesTable).createPanel(); 270 | JPanel constructorPanel = new JPanel(new BorderLayout()); 271 | constructorPanel.setBorder(IdeBorderFactory.createTitledBorder("Constructor level", false, 272 | JBUI.insets(0, 0, 10, 0))); 273 | constructorPanel.add(constructorTemplatesLocalPanel, BorderLayout.CENTER); 274 | 275 | methodTemplatesTable = new TemplatesTable(settings.getTemplateSettings().getMethodTemplates()); 276 | JPanel methodTemplatesLocalPanel = ToolbarDecorator.createDecorator(methodTemplatesTable).createPanel(); 277 | JPanel methodPanel = new JPanel(new BorderLayout()); 278 | methodPanel.setBorder(IdeBorderFactory.createTitledBorder("Method level", false, JBUI.insets(0, 0, 10, 0))); 279 | methodPanel.add(methodTemplatesLocalPanel, BorderLayout.CENTER); 280 | 281 | fieldTemplatesTable = new TemplatesTable(settings.getTemplateSettings().getFieldTemplates()); 282 | JPanel fieldTemplatesLocalPanel = ToolbarDecorator.createDecorator(fieldTemplatesTable).createPanel(); 283 | JPanel fieldPanel = new JPanel(new BorderLayout()); 284 | fieldPanel.setBorder(IdeBorderFactory.createTitledBorder("Field level", false, JBUI.insets(0, 0, 0, 0))); 285 | fieldPanel.add(fieldTemplatesLocalPanel, BorderLayout.CENTER); 286 | 287 | JPanel templatesPanel = new JPanel(); 288 | templatesPanel.setLayout(new GridLayoutManager(4, 1, JBUI.insets(10, 10, 10, 10), -1, -1)); 289 | 290 | templatesPanel.add(classPanel, getConstraints(0, 0)); 291 | templatesPanel.add(constructorPanel, getConstraints(1, 0)); 292 | templatesPanel.add(methodPanel, getConstraints(2, 0)); 293 | templatesPanel.add(fieldPanel, getConstraints(3, 0)); 294 | tabbedPane.addTab("Templates", templatesPanel); 295 | } 296 | 297 | private GridConstraints getConstraints(int row, int column) { 298 | return new GridConstraints(row, column, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false); 299 | } 300 | 301 | { 302 | // GUI initializer generated by IntelliJ IDEA GUI Designer 303 | // >>> IMPORTANT!! <<< 304 | // DO NOT EDIT OR ADD ANY CODE HERE! 305 | $$$setupUI$$$(); 306 | } 307 | 308 | /** 309 | * Method generated by IntelliJ IDEA GUI Designer 310 | * >>> IMPORTANT!! <<< 311 | * DO NOT edit this method OR call it in your code! 312 | * 313 | * @noinspection ALL 314 | */ 315 | private void $$$setupUI$$$() { 316 | panel = new JPanel(); 317 | panel.setLayout(new GridLayoutManager(1, 1, JBUI.insets(0, 0, 0, 0), -1, -1)); 318 | tabbedPane = new JTabbedPane(); 319 | panel.add(tabbedPane, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, new Dimension(200, 200), null, 0, false)); 320 | generalPanel = new JPanel(); 321 | generalPanel.setLayout(new GridLayoutManager(3, 3, JBUI.insets(10, 10, 10, 10), -1, -1)); 322 | tabbedPane.addTab("General", generalPanel); 323 | generalPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0), null)); 324 | generalModePanel = new JPanel(); 325 | generalModePanel.setLayout(new GridLayoutManager(3, 1, JBUI.insets(0, 0, 0, 0), -1, -1)); 326 | generalPanel.add(generalModePanel, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); 327 | generalModePanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3), null)); 328 | generalModeKeepRadioButton = new JRadioButton(); 329 | generalModeKeepRadioButton.setSelected(false); 330 | generalModeKeepRadioButton.setText("Keep old javadoc"); 331 | generalModePanel.add(generalModeKeepRadioButton, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); 332 | generalModeUpdateRadioButton = new JRadioButton(); 333 | generalModeUpdateRadioButton.setSelected(false); 334 | generalModeUpdateRadioButton.setText("Update old javadoc"); 335 | generalModePanel.add(generalModeUpdateRadioButton, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); 336 | generalModeReplaceRadioButton = new JRadioButton(); 337 | generalModeReplaceRadioButton.setText("Replace old javadoc"); 338 | generalModePanel.add(generalModeReplaceRadioButton, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); 339 | generalLevelPanel = new JPanel(); 340 | generalLevelPanel.setLayout(new GridLayoutManager(3, 1, JBUI.insets(0, 0, 0, 0), -1, -1)); 341 | generalPanel.add(generalLevelPanel, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); 342 | generalLevelPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3), null)); 343 | generalLevelTypeCheckbox = new JCheckBox(); 344 | generalLevelTypeCheckbox.setSelected(false); 345 | generalLevelTypeCheckbox.setText("Type"); 346 | generalLevelPanel.add(generalLevelTypeCheckbox, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); 347 | generalLevelMethodCheckbox = new JCheckBox(); 348 | generalLevelMethodCheckbox.setSelected(false); 349 | generalLevelMethodCheckbox.setText("Method"); 350 | generalLevelPanel.add(generalLevelMethodCheckbox, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); 351 | generalLevelFieldCheckbox = new JCheckBox(); 352 | generalLevelFieldCheckbox.setSelected(false); 353 | generalLevelFieldCheckbox.setText("Field"); 354 | generalLevelPanel.add(generalLevelFieldCheckbox, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); 355 | generalVisibilityPanel = new JPanel(); 356 | generalVisibilityPanel.setLayout(new GridLayoutManager(4, 1, JBUI.insets(0, 0, 0, 0), -1, -1)); 357 | generalPanel.add(generalVisibilityPanel, new GridConstraints(0, 2, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); 358 | generalVisibilityPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3), "Visibility")); 359 | generalVisibilityPublicCheckbox = new JCheckBox(); 360 | generalVisibilityPublicCheckbox.setSelected(false); 361 | generalVisibilityPublicCheckbox.setText("Public"); 362 | generalVisibilityPanel.add(generalVisibilityPublicCheckbox, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); 363 | generalVisibilityProtectedCheckbox = new JCheckBox(); 364 | generalVisibilityProtectedCheckbox.setSelected(false); 365 | generalVisibilityProtectedCheckbox.setText("Protected"); 366 | generalVisibilityPanel.add(generalVisibilityProtectedCheckbox, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); 367 | generalVisibilityDefaultCheckbox = new JCheckBox(); 368 | generalVisibilityDefaultCheckbox.setSelected(false); 369 | generalVisibilityDefaultCheckbox.setText("Default"); 370 | generalVisibilityPanel.add(generalVisibilityDefaultCheckbox, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); 371 | generalVisibilityPrivateCheckbox = new JCheckBox(); 372 | generalVisibilityPrivateCheckbox.setText("Private"); 373 | generalVisibilityPanel.add(generalVisibilityPrivateCheckbox, new GridConstraints(3, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); 374 | generalOtherPanel = new JPanel(); 375 | generalOtherPanel.setLayout(new GridLayoutManager(2, 1, JBUI.insets(0, 0, 0, 0), -1, -1)); 376 | generalPanel.add(generalOtherPanel, new GridConstraints(1, 0, 1, 2, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); 377 | generalOtherPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3), "Other")); 378 | generalOtherOverriddenMethodsCheckbox = new JCheckBox(); 379 | generalOtherOverriddenMethodsCheckbox.setText("Comment overridden methods"); 380 | generalOtherPanel.add(generalOtherOverriddenMethodsCheckbox, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); 381 | generalOtherSplittedClassName = new JCheckBox(); 382 | generalOtherSplittedClassName.setSelected(true); 383 | generalOtherSplittedClassName.setText("Generate splitted class name"); 384 | generalOtherPanel.add(generalOtherSplittedClassName, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); 385 | final Spacer spacer1 = new Spacer(); 386 | generalPanel.add(spacer1, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_VERTICAL, 1, GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false)); 387 | ButtonGroup buttonGroup; 388 | buttonGroup = new ButtonGroup(); 389 | buttonGroup.add(generalModeKeepRadioButton); 390 | buttonGroup.add(generalModeUpdateRadioButton); 391 | buttonGroup.add(generalModeReplaceRadioButton); 392 | } 393 | 394 | /** 395 | * @noinspection ALL 396 | */ 397 | public JComponent $$$getRootComponent$$$() { 398 | return panel; 399 | } 400 | } 401 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/utils/JavaDocUtils.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.utils; 2 | 3 | import com.github.setial.intellijjavadocs.model.JavaDoc; 4 | import com.github.setial.intellijjavadocs.model.JavaDocTag; 5 | import com.github.setial.intellijjavadocs.transformation.JavaDocBuilder; 6 | import com.intellij.psi.PsiElement; 7 | import com.intellij.psi.PsiElementFactory; 8 | import com.intellij.psi.impl.source.javadoc.PsiDocMethodOrFieldRef; 9 | import com.intellij.psi.impl.source.javadoc.PsiDocParamRef; 10 | import com.intellij.psi.impl.source.javadoc.PsiDocTagValueImpl; 11 | import com.intellij.psi.javadoc.PsiDocComment; 12 | import com.intellij.psi.javadoc.PsiDocTag; 13 | import com.intellij.psi.javadoc.PsiDocTagValue; 14 | import org.apache.commons.collections.CollectionUtils; 15 | import org.apache.commons.lang3.StringUtils; 16 | import org.jetbrains.annotations.NotNull; 17 | import org.jetbrains.annotations.Nullable; 18 | 19 | import java.util.Arrays; 20 | import java.util.Iterator; 21 | import java.util.LinkedHashMap; 22 | import java.util.LinkedList; 23 | import java.util.List; 24 | import java.util.Map; 25 | import java.util.Map.Entry; 26 | 27 | /** 28 | * The type Java doc utils. 29 | * 30 | * @author Sergey Timofiychuk 31 | */ 32 | public class JavaDocUtils { 33 | 34 | private static final List MERGE_TAG_NAMES = Arrays.asList("param", "throws"); 35 | 36 | /** 37 | * Convert java doc. 38 | * 39 | * @param javadoc the Javadoc 40 | * @return the String 41 | */ 42 | @NotNull 43 | public static String convertJavaDoc(@NotNull JavaDoc javadoc) { 44 | JavaDocBuilder builder = new JavaDocBuilder(); 45 | builder.createDefaultJavaDoc(javadoc); 46 | return builder.build(); 47 | } 48 | 49 | /** 50 | * Merge java docs. 51 | * 52 | * @param oldJavaDoc the Old java doc 53 | * @param newJavaDoc the New java doc 54 | * @return the Java doc 55 | */ 56 | @NotNull 57 | public static JavaDoc mergeJavaDocs(@NotNull JavaDoc oldJavaDoc, @NotNull JavaDoc newJavaDoc) { 58 | List description = oldJavaDoc.getDescription(); 59 | if (descriptionIsEmpty(description)) { 60 | description = newJavaDoc.getDescription(); 61 | } 62 | Map> oldTags = oldJavaDoc.getTags(); 63 | Map> newTags = newJavaDoc.getTags(); 64 | Map> tags = new LinkedHashMap<>(); 65 | List processedTagNames = new LinkedList<>(); 66 | for (Entry> newTagsEntry : newTags.entrySet()) { 67 | String name = newTagsEntry.getKey(); 68 | if (!tags.containsKey(name)) { 69 | tags.put(name, new LinkedList<>()); 70 | } 71 | List tagsEntry = newTagsEntry.getValue(); 72 | for (JavaDocTag tag : tagsEntry) { 73 | if (oldTags.containsKey(name)) { 74 | // the case when old tag exists 75 | List oldTagsEntry = oldTags.get(name); 76 | JavaDocTag oldTag; 77 | if (!MERGE_TAG_NAMES.contains(name)) { 78 | oldTag = oldTagsEntry.get(0); 79 | } else { 80 | oldTag = findOldTag(oldTagsEntry, tag.getValue(), tag.getRefParam()); 81 | } 82 | if (oldTag != null) { 83 | // the case when old tag is ok 84 | tags.get(name).add(mergeJavaDocTag(oldTag, tag)); 85 | } else { 86 | tags.get(name).add(tag); 87 | } 88 | } else { 89 | // the case when old tag has been removed 90 | tags.get(name).add(tag); 91 | } 92 | } 93 | processedTagNames.add(name); 94 | } 95 | // add old tags that were not processed 96 | for (Entry> entry : oldTags.entrySet()) { 97 | String name = entry.getKey(); 98 | if (!processedTagNames.contains(name)) { 99 | tags.put(name, entry.getValue()); 100 | } 101 | } 102 | return new JavaDoc(description, tags); 103 | } 104 | 105 | /** 106 | * Merge java doc tag. 107 | * 108 | * @param oldJavaDocTag the Old java doc tag 109 | * @param newJavaDocTag the New java doc tag 110 | * @return the Java doc tag 111 | */ 112 | @NotNull 113 | public static JavaDocTag mergeJavaDocTag(@NotNull JavaDocTag oldJavaDocTag, @NotNull JavaDocTag newJavaDocTag) { 114 | List description = oldJavaDocTag.getDescription(); 115 | if (descriptionIsEmpty(description)) { 116 | description = newJavaDocTag.getDescription(); 117 | } 118 | return new JavaDocTag(oldJavaDocTag.getRefParam(), oldJavaDocTag.getValue(), description); 119 | } 120 | 121 | /** 122 | * Creates the java doc tag. 123 | * 124 | * @param docTag the Doc tag 125 | * @return the Java doc tag 126 | */ 127 | @NotNull 128 | public static JavaDocTag createJavaDocTag(@NotNull PsiDocTag docTag) { 129 | String docTagRefParam = findDocTagRefParam(docTag); 130 | String docTagValue = findDocTagValue(docTag); 131 | List docTagDescription = findDocTagDescription(docTag, docTagRefParam, docTagValue); 132 | return new JavaDocTag( 133 | docTagRefParam, 134 | docTagValue, 135 | docTagDescription); 136 | } 137 | 138 | /** 139 | * Creates the java doc. 140 | * 141 | * @param docComment the Doc comment 142 | * @return the Java doc 143 | */ 144 | @NotNull 145 | public static JavaDoc createJavaDoc(@NotNull PsiDocComment docComment) { 146 | return new JavaDoc( 147 | findDocDescription(docComment), 148 | findDocTags(docComment)); 149 | } 150 | 151 | /** 152 | * Find java doc description. 153 | * 154 | * @param docComment the Doc comment 155 | * @return the description 156 | */ 157 | @NotNull 158 | public static List findDocDescription(@NotNull PsiDocComment docComment) { 159 | List descriptions = new LinkedList<>(); 160 | PsiElement[] descriptionElements = docComment.getDescriptionElements(); 161 | for (PsiElement descriptionElement : descriptionElements) { 162 | descriptions.add(descriptionElement.getText()); 163 | } 164 | return descriptions; 165 | } 166 | 167 | /** 168 | * Find doc tags. 169 | * 170 | * @param docComment the Doc comment 171 | * @return the javadoc tags 172 | */ 173 | @NotNull 174 | public static Map> findDocTags(@NotNull PsiDocComment docComment) { 175 | Map> tags = new LinkedHashMap<>(); 176 | PsiDocTag[] docTags = docComment.getTags(); 177 | for (PsiDocTag docTag : docTags) { 178 | String name = docTag.getName(); 179 | if (!tags.containsKey(name)) { 180 | tags.put(name, new LinkedList<>()); 181 | } 182 | tags.get(name).add(createJavaDocTag(docTag)); 183 | } 184 | return tags; 185 | } 186 | 187 | /** 188 | * Find doc tag ref param. 189 | * 190 | * @param docTag the Doc tag 191 | * @return the javadoc's tag ref parameter 192 | */ 193 | @Nullable 194 | public static String findDocTagRefParam(@NotNull PsiDocTag docTag) { 195 | String refParam = null; 196 | for (PsiElement element : docTag.getDataElements()) { 197 | if (element instanceof PsiDocParamRef || 198 | element instanceof PsiDocMethodOrFieldRef) { 199 | refParam = element.getText(); 200 | break; 201 | } 202 | } 203 | return refParam; 204 | } 205 | 206 | /** 207 | * Find doc tag value. 208 | * 209 | * @param docTag the Doc tag 210 | * @return the javadoc's tag value 211 | */ 212 | @Nullable 213 | public static String findDocTagValue(@NotNull PsiDocTag docTag) { 214 | String value = null; 215 | for (PsiElement element : docTag.getDataElements()) { 216 | if (element instanceof PsiDocTagValue) { 217 | value = element.getText(); 218 | break; 219 | } 220 | } 221 | return value; 222 | } 223 | 224 | /** 225 | * Find doc tag description. 226 | * 227 | * @param docTag the Doc tag 228 | * @param docTagRefParam the doc tag ref param 229 | * @param docTagValue the doc tag value 230 | * @return the javadoc's tag descriptions 231 | */ 232 | @NotNull 233 | public static List findDocTagDescription(@NotNull PsiDocTag docTag, String docTagRefParam, String docTagValue) { 234 | List descriptions = new LinkedList<>(); 235 | List elements = new LinkedList<>(Arrays.asList(docTag.getDataElements())); 236 | for (Iterator iterator = elements.iterator(); iterator.hasNext(); ) { 237 | PsiElement element = iterator.next(); 238 | removeValueIfAssignableType(docTagRefParam, PsiDocParamRef.class, iterator, element); 239 | removeValueIfAssignableType(docTagValue, PsiDocTagValueImpl.class, iterator, element); 240 | } 241 | StringBuilder descriptionBuilder = new StringBuilder(); 242 | for (PsiElement element : elements) { 243 | descriptionBuilder.append(element.getText()); 244 | } 245 | descriptions.add(descriptionBuilder.toString()); 246 | return descriptions; 247 | } 248 | 249 | private static void removeValueIfAssignableType(String value, Class valueType, 250 | Iterator iterator, PsiElement element) { 251 | if (value != null && element.getClass().isAssignableFrom(valueType) && element.getText().equals(value)) { 252 | iterator.remove(); 253 | } 254 | } 255 | 256 | /** 257 | * Converts string to java doc. 258 | * 259 | * @param javaDocText the Java doc text 260 | * @param psiElementFactory the Psi element factory 261 | * @return the Java doc 262 | */ 263 | @Nullable 264 | public static JavaDoc toJavaDoc(@Nullable String javaDocText, @NotNull PsiElementFactory psiElementFactory) { 265 | JavaDoc result = null; 266 | if (StringUtils.isNotBlank(javaDocText)) { 267 | PsiDocComment javaDocComment = psiElementFactory.createDocCommentFromText(javaDocText); 268 | result = createJavaDoc(javaDocComment); 269 | } 270 | return result; 271 | } 272 | 273 | @Nullable 274 | private static JavaDocTag findOldTag(List oldTagsEntry, String value, String refParam) { 275 | JavaDocTag result = null; 276 | for (JavaDocTag oldTag : oldTagsEntry) { 277 | if (StringUtils.equals(oldTag.getValue(), value) && 278 | StringUtils.equals(oldTag.getRefParam(), refParam)) { 279 | result = oldTag; 280 | break; 281 | } 282 | } 283 | return result; 284 | } 285 | 286 | private static boolean descriptionIsEmpty(List description) { 287 | boolean result = true; 288 | if (!CollectionUtils.isEmpty(description)) { 289 | for (String item : description) { 290 | result = result && StringUtils.isBlank(item); 291 | } 292 | } 293 | return result; 294 | } 295 | 296 | private JavaDocUtils() { 297 | } 298 | 299 | } 300 | -------------------------------------------------------------------------------- /src/main/java/com/github/setial/intellijjavadocs/utils/XmlUtils.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.utils; 2 | 3 | import org.jdom.Element; 4 | 5 | import java.util.*; 6 | import java.util.Map.Entry; 7 | 8 | /** 9 | * The type Xml utils. 10 | * 11 | * @author Sergey Timofiychuk 12 | */ 13 | public class XmlUtils { 14 | 15 | /** 16 | * The constant KEY. 17 | */ 18 | public static final String KEY = "KEY"; 19 | 20 | /** 21 | * The constant VALUE. 22 | */ 23 | public static final String VALUE = "VALUE"; 24 | 25 | /** 26 | * Trim element content. 27 | * 28 | * @param element the element 29 | * @return the string 30 | */ 31 | public static String trimElementContent(Element element) { 32 | return element.getTextTrim(); 33 | } 34 | 35 | /** 36 | * Normalize template. 37 | * 38 | * @param template the template 39 | * @return the string 40 | */ 41 | public static String normalizeTemplate(String template) { 42 | Element element = new Element("template"); 43 | element.addContent(template); 44 | return element.getTextNormalize().replaceAll("\\\\n", "\n"); 45 | } 46 | 47 | /** 48 | * Gets element. 49 | * 50 | * @param name the name 51 | * @param value the value 52 | * @return the element 53 | */ 54 | public static Element getElement(String name, String value) { 55 | Element element = new Element(name); 56 | element.addContent(value); 57 | return element; 58 | } 59 | 60 | /** 61 | * Gets element. 62 | * 63 | * @param nameParent the name parent 64 | * @param nameChild the name child 65 | * @param values the values 66 | * @return the element 67 | */ 68 | public static Element getElement(String nameParent, String nameChild, Collection values) { 69 | Element root = new Element(nameParent); 70 | for (Object value : values) { 71 | root.addContent(getElement(nameChild, value.toString())); 72 | } 73 | return root; 74 | } 75 | 76 | /** 77 | * Gets element. 78 | * 79 | * @param nameParent the name parent 80 | * @param nameChild the name child 81 | * @param values the values 82 | * @return the element 83 | */ 84 | public static Element getElement(String nameParent, String nameChild, Map values) { 85 | Element root = new Element(nameParent); 86 | for (Entry entry : values.entrySet()) { 87 | Element child = new Element(nameChild); 88 | root.addContent(child); 89 | child.addContent(getElement(KEY, entry.getKey())); 90 | child.addContent(getElement(VALUE, entry.getValue())); 91 | } 92 | return root; 93 | } 94 | 95 | /** 96 | * Gets value. 97 | * 98 | * @param the type parameter 99 | * @param element the element 100 | * @param name the name 101 | * @param type the type 102 | * @return the value 103 | */ 104 | public static > T getValue(Element element, String name, Class type) { 105 | T enumVal = null; 106 | Element child = element.getChild(name); 107 | if (child != null) { 108 | String result = child.getValue(); 109 | if (result != null) { 110 | enumVal = Enum.valueOf(type, result); 111 | } 112 | } 113 | return enumVal; 114 | } 115 | 116 | /** 117 | * Gets values. 118 | * 119 | * @param the type parameter 120 | * @param element the element 121 | * @param parentName the parent name 122 | * @param childName the child name 123 | * @param type the type 124 | * @return the values 125 | */ 126 | public static > Set getValues(Element element, String parentName, String childName, Class type) { 127 | Set result = new LinkedHashSet<>(); 128 | Element root = element.getChild(parentName); 129 | for (Object value : root.getChildren(childName)) { 130 | if (value instanceof Element) { 131 | Element elem = (Element) value; 132 | String name = elem.getValue(); 133 | result.add(Enum.valueOf(type, name)); 134 | } 135 | } 136 | return result; 137 | } 138 | 139 | /** 140 | * Gets values. 141 | * 142 | * @param element the element 143 | * @param parentName the parent name 144 | * @param childName the child name 145 | * @return the values 146 | */ 147 | public static Set getValues(Element element, String parentName, String childName) { 148 | Set result = new LinkedHashSet<>(); 149 | Element root = element.getChild(parentName); 150 | for (Object value : root.getChildren(childName)) { 151 | if (value instanceof Element) { 152 | result.add((Element) value); 153 | } 154 | } 155 | return result; 156 | } 157 | 158 | /** 159 | * Gets map. 160 | * 161 | * @param root the root 162 | * @param parentName the parent name 163 | * @param childName the child name 164 | * @return the map 165 | */ 166 | public static Map getMap(Element root, String parentName, String childName) { 167 | Map result = new LinkedHashMap<>(); 168 | Set templates = getValues(root, parentName, childName); 169 | for (Element template : templates) { 170 | String key = template.getChild(KEY).getValue(); 171 | String value = template.getChild(VALUE).getValue(); 172 | result.put(key, value); 173 | } 174 | return result; 175 | } 176 | 177 | private XmlUtils() { 178 | } 179 | 180 | } 181 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | Changes in intellij-javadoc-4.1.4 9 |
    10 |
  • Compatibility with intellij-idea build 2024.3
  • 11 |
12 |

Changes in intellij-javadoc-4.1.3

13 |
    14 |
  • Compatibility with intellij-idea build 2024.2
  • 15 |
16 |

Changes in intellij-javadoc-4.1.2

17 |
    18 |
  • Compatibility with intellij-idea build 2024.1
  • 19 |
20 |

Changes in intellij-javadoc-4.1.1

21 |
    22 |
  • Compatibility with intellij-idea build 2023.3
  • 23 |
  • Remove usage of deprecated API
  • 24 |
25 |

Changes in intellij-javadoc-4.1.0

26 |
    27 |
  • Compatibility with intellij-idea build 2023.2
  • 28 |
29 |

Changes in intellij-javadoc-4.0.2

30 |
    31 |
  • Compatibility with intellij-idea build 2020.1
  • 32 |
33 |

Changes in intellij-javadoc-4.0.1

34 |
    35 |
  • Compatibility with intellij-idea build 2019.3.1
  • 36 |
  • Migrate project to gradle
  • 37 |
38 |

Changes in intellij-javadoc-2.1.2

39 |
    40 |
  • Update freemarker version to most recent
  • 41 |
42 |

Changes in intellij-javadoc-2.1.1

43 |
    44 |
  • Update supports intellij-idea versions (supports only 14.x versions)
  • 45 |
46 |

Changes in intellij-javadoc-2.1.0

47 |
    48 |
  • Fix issue related to File Locked Exception
  • 49 |
  • Fix issue on update 'throws' tags
  • 50 |
  • Fix issue on generate @see and @link tags
  • 51 |
  • Fix issue on load custom template configuration
  • 52 |
  • Improve field templates to generate correct javadoc for constants in interfaces
  • 53 |
  • Improve field templates to generate correct javadoc for constants in enums
  • 54 |
  • Add fieldName variable to templates
  • 55 |
  • Add notification messages during indexing process
  • 56 |
  • Change template engine to freemarker
  • 57 |
58 |

Changes in intellij-javadoc-2.0.0

59 |
    60 |
  • Update support build versions (supported intellij idea build versions 132.102+)
  • 61 |
  • Fix issue related to File Locked Exception
  • 62 |
63 |

Changes in intellij-javadoc-1.0.11

64 |
    65 |
  • Add actions to Remove javadocs on selected element or on the java file
  • 66 |
  • Add actions to Create/Remove javadocs on a project/package/selected files
  • 67 |
68 |

Changes in intellij-javadoc-1.0.10

69 |
    70 |
  • Fix critical issue on generate javadocs in interfaces
  • 71 |
72 |

Changes in intellij-javadoc-1.0.9

73 |
    74 |
  • 75 | Change key mappings, since previous are reserved by intellij idea 13.
    76 | Details about new mapping please find on wiki page 77 |
  • 78 |
  • Fix bug to show menu only in generate menu of java sources
  • 79 |
80 |

Changes in intellij-javadoc-1.0.8

81 |
    82 |
  • Persist javadocs settings on a global level
  • 83 |
84 |

Changes in intellij-javadoc-1.0.7

85 |
    86 |
  • Fixed issue with line breaks on javadocs for enum values.
  • 87 |
  • Fixed exception on try to generate javadoc on last line of class.
  • 88 |
  • Add generic types support
  • 89 |
90 |

Changes in intellij-javadoc-1.0.6

91 |
    92 |
  • Fixed issue with generating javadocs formatted as single line.
  • 93 |
  • Add feature of generating javadocs for the elements in selected area.
  • 94 |
95 |

Changes in intellij-javadoc-1.0.5

96 |
    97 |
  • Introduce new setting that allows to check whether you want to generate splitted class name or not
  • 98 |
  • Bug fixing
  • 99 |
100 |

Changes in intellij-javadoc-1.0.4

101 |
    102 |
  • Fixed logging issue on different environment
  • 103 |
104 |

Changes in intellij-javadoc-1.0.3

105 |
    106 |
  • Improve regular expressions to better methods recognition
  • 107 |
  • Improve the way how old javadoc and new one are merged in update mode
  • 108 |
109 |

Changes in intellij-javadoc-1.0.2

110 |
    111 |
  • Recompile plugin with java 1.6 support
  • 112 |
113 |

Changes in intellij-javadoc-1.0.1

114 |
    115 |
  • Initial implementation of "JavaDoc" plugin
  • 116 |
117 |

118 | ]]> 119 |
120 | 121 | 123 | com.intellij.modules.java 124 | 125 | 126 | 127 | 128 | 132 | 133 | 134 | 138 | 139 | 140 | 141 | 145 | 146 | 147 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 161 | 162 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 176 | 178 | 180 | 182 | 183 | 185 | 186 |
187 | -------------------------------------------------------------------------------- /src/main/resources/messages.properties: -------------------------------------------------------------------------------- 1 | configurable.panel.name=JavaDoc -------------------------------------------------------------------------------- /src/main/resources/templates.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 20 | 21 | 26 | 27 | 41 | 42 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 70 | 71 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 128 | 129 | 169 | 170 | 192 | 193 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 264 | 265 | 266 | 267 | 268 | -------------------------------------------------------------------------------- /src/test/java/com/github/setial/intellijjavadocs/generator/impl/MethodJavaDocGeneratorTest.java: -------------------------------------------------------------------------------- 1 | package com.github.setial.intellijjavadocs.generator.impl; 2 | 3 | import com.github.setial.intellijjavadocs.configuration.JavaDocConfiguration; 4 | import com.github.setial.intellijjavadocs.model.JavaDoc; 5 | import com.github.setial.intellijjavadocs.model.settings.GeneralSettings; 6 | import com.github.setial.intellijjavadocs.model.settings.Level; 7 | import com.github.setial.intellijjavadocs.model.settings.Mode; 8 | import com.github.setial.intellijjavadocs.model.settings.Visibility; 9 | import com.google.common.collect.Sets; 10 | import com.intellij.ide.highlighter.JavaFileType; 11 | import com.intellij.openapi.project.Project; 12 | import com.intellij.psi.PsiElementFactory; 13 | import com.intellij.psi.PsiFile; 14 | import com.intellij.psi.PsiFileFactory; 15 | import com.intellij.psi.PsiMethod; 16 | import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase4; 17 | import org.junit.Before; 18 | import org.junit.Test; 19 | 20 | import static com.intellij.openapi.application.ActionsKt.runReadAction; 21 | import static org.hamcrest.CoreMatchers.notNullValue; 22 | import static org.hamcrest.CoreMatchers.nullValue; 23 | import static org.hamcrest.MatcherAssert.assertThat; 24 | 25 | public class MethodJavaDocGeneratorTest extends LightJavaCodeInsightFixtureTestCase4 { 26 | 27 | private MethodJavaDocGenerator methodJavaDocGenerator; 28 | private PsiElementFactory elementFactory; 29 | private GeneralSettings generalSettings; 30 | private PsiFile psiFile; 31 | private PsiMethod publicGetMethod; 32 | private PsiMethod protectedGetMethod; 33 | 34 | @Before 35 | public void setUp() { 36 | methodJavaDocGenerator = new MethodJavaDocGenerator(getProject()); 37 | elementFactory = PsiElementFactory.getInstance(getProject()); 38 | JavaDocConfiguration settings = getProject().getService(JavaDocConfiguration.class); 39 | generalSettings = settings.getConfiguration().getGeneralSettings(); 40 | generalSettings.setMode(Mode.REPLACE); 41 | PsiFileFactory fileFactory = PsiFileFactory.getInstance(getProject()); 42 | psiFile = runReadAction(() -> fileFactory.createFileFromText( 43 | "Test.java", JavaFileType.INSTANCE, "public class Test {}")); 44 | publicGetMethod = runReadAction(() -> elementFactory.createMethodFromText("public String getParam(String param) {}", psiFile)); 45 | protectedGetMethod = runReadAction(() -> elementFactory.createMethodFromText("protected String getParam(String param) {}", psiFile)); 46 | } 47 | 48 | @Test 49 | public void testGenerateJavaDoc() { 50 | generalSettings.setLevels( 51 | Sets.immutableEnumSet(Level.FIELD, Level.METHOD, Level.TYPE)); 52 | generalSettings.setVisibilities( 53 | Sets.immutableEnumSet(Visibility.DEFAULT, Visibility.PRIVATE, Visibility.PROTECTED, Visibility.PUBLIC)); 54 | 55 | JavaDoc javaDoc = runReadAction(() -> methodJavaDocGenerator.generateJavaDoc(publicGetMethod)); 56 | assertThat(javaDoc, notNullValue()); 57 | } 58 | 59 | @Test 60 | public void testGenerateJavaDoc_NoPublicVisibility() { 61 | generalSettings.setLevels( 62 | Sets.immutableEnumSet(Level.FIELD, Level.METHOD, Level.TYPE)); 63 | generalSettings.setVisibilities( 64 | Sets.immutableEnumSet(Visibility.DEFAULT, Visibility.PRIVATE, Visibility.PROTECTED)); 65 | 66 | JavaDoc javaDoc = runReadAction(() -> methodJavaDocGenerator.generateJavaDoc(publicGetMethod)); 67 | assertThat(javaDoc, nullValue()); 68 | } 69 | 70 | @Test 71 | public void testGenerateJavaDoc_NoMethodLevel() { 72 | generalSettings.setLevels( 73 | Sets.immutableEnumSet(Level.FIELD, Level.TYPE)); 74 | generalSettings.setVisibilities( 75 | Sets.immutableEnumSet(Visibility.DEFAULT, Visibility.PRIVATE, Visibility.PROTECTED, Visibility.PUBLIC)); 76 | 77 | JavaDoc javaDoc = runReadAction(() -> methodJavaDocGenerator.generateJavaDoc(publicGetMethod)); 78 | assertThat(javaDoc, nullValue()); 79 | } 80 | 81 | @Test 82 | public void testGenerateJavaDoc_NoMethodLevelAndPublicVisibility() { 83 | generalSettings.setLevels( 84 | Sets.immutableEnumSet(Level.FIELD, Level.TYPE)); 85 | generalSettings.setVisibilities( 86 | Sets.immutableEnumSet(Visibility.DEFAULT, Visibility.PRIVATE, Visibility.PROTECTED)); 87 | 88 | JavaDoc javaDoc = runReadAction(() -> methodJavaDocGenerator.generateJavaDoc(publicGetMethod)); 89 | assertThat(javaDoc, nullValue()); 90 | } 91 | 92 | @Test 93 | public void testGenerateJavaDocProtected() { 94 | generalSettings.setLevels( 95 | Sets.immutableEnumSet(Level.FIELD, Level.TYPE, Level.METHOD)); 96 | generalSettings.setVisibilities( 97 | Sets.immutableEnumSet(Visibility.DEFAULT, Visibility.PRIVATE, Visibility.PROTECTED)); 98 | 99 | JavaDoc javaDoc = runReadAction(() -> methodJavaDocGenerator.generateJavaDoc(protectedGetMethod)); 100 | assertThat(javaDoc, notNullValue()); 101 | } 102 | 103 | @Test 104 | public void testGenerateJavaDocProtected_NoProtectedVisibility() { 105 | generalSettings.setLevels( 106 | Sets.immutableEnumSet(Level.FIELD, Level.TYPE, Level.METHOD)); 107 | generalSettings.setVisibilities( 108 | Sets.immutableEnumSet(Visibility.DEFAULT, Visibility.PRIVATE)); 109 | 110 | JavaDoc javaDoc = runReadAction(() -> methodJavaDocGenerator.generateJavaDoc(protectedGetMethod)); 111 | assertThat(javaDoc, nullValue()); 112 | } 113 | 114 | private Project getProject() { 115 | return getFixture().getProject(); 116 | } 117 | } --------------------------------------------------------------------------------