├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── build.gradle ├── dep.txt ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── src ├── main │ ├── java │ │ └── com │ │ │ └── avast │ │ │ └── server │ │ │ └── libver │ │ │ ├── Application.java │ │ │ ├── model │ │ │ └── gradle │ │ │ │ ├── DataRequest.java │ │ │ │ ├── GradleDepsDescriptor.java │ │ │ │ ├── Node.java │ │ │ │ └── Subproject.java │ │ │ └── service │ │ │ ├── GradleController.java │ │ │ ├── GradleService.java │ │ │ ├── ParseInvalidException.java │ │ │ └── impl │ │ │ ├── GradleParser.java │ │ │ └── GradleServiceImpl.java │ └── resources │ │ ├── application.properties │ │ ├── banner.txt │ │ ├── static │ │ ├── appfavicon.ico │ │ ├── clipboard │ │ │ ├── clipboard.js │ │ │ ├── clipboard.min.js │ │ │ └── tooltips.js │ │ ├── css │ │ │ ├── custom.css │ │ │ └── primer.css │ │ ├── favicon.ico │ │ ├── img │ │ │ ├── glyphicons-65-lightbulb.png │ │ │ ├── gradle.png │ │ │ └── maven.png │ │ ├── index.html │ │ └── js │ │ │ ├── gradle.js │ │ │ ├── js.cookie.js │ │ │ ├── moment.min.js │ │ │ └── utils.js │ │ └── templates │ │ ├── footer.html │ │ ├── gradle.html │ │ └── menu.html └── test │ ├── java │ └── com │ │ └── avast │ │ └── server │ │ └── libver │ │ ├── ApplicationTest.java │ │ └── service │ │ └── GradleServiceTest.java │ └── resources │ ├── dep.txt │ └── dep2.txt └── web └── screenshot.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io 2 | 3 | ### OSX ### 4 | .DS_Store 5 | .AppleDouble 6 | .LSOverride 7 | 8 | # Icon must end with two \r 9 | Icon 10 | 11 | 12 | # Thumbnails 13 | ._* 14 | 15 | # Files that might appear on external disk 16 | .Spotlight-V100 17 | .Trashes 18 | 19 | # Directories potentially created on remote AFP share 20 | .AppleDB 21 | .AppleDesktop 22 | Network Trash Folder 23 | Temporary Items 24 | .apdisk 25 | 26 | 27 | ### Windows ### 28 | # Windows image file caches 29 | Thumbs.db 30 | ehthumbs.db 31 | 32 | # Folder config file 33 | Desktop.ini 34 | 35 | # Recycle Bin used on file shares 36 | $RECYCLE.BIN/ 37 | 38 | # Windows Installer files 39 | *.cab 40 | *.msi 41 | *.msm 42 | *.msp 43 | 44 | # Windows shortcuts 45 | *.lnk 46 | 47 | 48 | ### Linux ### 49 | *~ 50 | 51 | # KDE directory preferences 52 | .directory 53 | 54 | 55 | ### Java ### 56 | *.class 57 | 58 | # Mobile Tools for Java (J2ME) 59 | .mtj.tmp/ 60 | 61 | # Package Files # 62 | #*.jar 63 | *.war 64 | *.ear 65 | 66 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 67 | hs_err_pid* 68 | 69 | 70 | ### Scala ### 71 | *.class 72 | *.log 73 | 74 | # sbt specific 75 | .cache 76 | .history 77 | .lib/ 78 | dist/* 79 | target/ 80 | lib_managed/ 81 | src_managed/ 82 | project/boot/ 83 | project/plugins/project/ 84 | 85 | # Scala-IDE specific 86 | .scala_dependencies 87 | .worksheet 88 | 89 | 90 | ### Gradle ### 91 | .gradle 92 | build/ 93 | 94 | # Ignore Gradle GUI config 95 | gradle-app.setting 96 | 97 | 98 | ### Maven ### 99 | target/ 100 | pom.xml.tag 101 | pom.xml.releaseBackup 102 | pom.xml.versionsBackup 103 | pom.xml.next 104 | release.properties 105 | 106 | 107 | ### Intellij ### 108 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm 109 | 110 | *.iml 111 | 112 | ## Directory-based project format: 113 | .idea/ 114 | # if you remove the above rule, at least ignore the following: 115 | 116 | # User-specific stuff: 117 | # .idea/workspace.xml 118 | # .idea/tasks.xml 119 | # .idea/dictionaries 120 | 121 | # Sensitive or high-churn files: 122 | # .idea/dataSources.ids 123 | # .idea/dataSources.xml 124 | # .idea/sqlDataSources.xml 125 | # .idea/dynamic.xml 126 | # .idea/uiDesigner.xml 127 | 128 | # Gradle: 129 | # .idea/gradle.xml 130 | # .idea/libraries 131 | 132 | # Mongo Explorer plugin: 133 | # .idea/mongoSettings.xml 134 | 135 | ## File-based project format: 136 | *.ipr 137 | *.iws 138 | 139 | ## Plugin-specific files: 140 | 141 | # IntelliJ 142 | out/ 143 | 144 | # mpeltonen/sbt-idea plugin 145 | .idea_modules/ 146 | 147 | # JIRA plugin 148 | atlassian-ide-plugin.xml 149 | 150 | # Crashlytics plugin (for Android Studio and IntelliJ) 151 | com_crashlytics_export_strings.xml 152 | crashlytics.properties 153 | crashlytics-build.properties 154 | 155 | 156 | ### Eclipse ### 157 | *.pydevproject 158 | .metadata 159 | .gradle 160 | bin/ 161 | tmp/ 162 | *.tmp 163 | *.bak 164 | *.swp 165 | *~.nib 166 | local.properties 167 | .settings/ 168 | .loadpath 169 | .classpath 170 | .project 171 | 172 | # External tool builders 173 | .externalToolBuilders/ 174 | 175 | # Locally stored "Eclipse launch configurations" 176 | *.launch 177 | 178 | # CDT-specific 179 | .cproject 180 | 181 | # PDT-specific 182 | .buildpath 183 | 184 | # sbteclipse plugin 185 | .target 186 | 187 | # TeXlipse plugin 188 | .texlipse 189 | 190 | 191 | ### NetBeans ### 192 | nbproject/private/ 193 | build/ 194 | nbbuild/ 195 | dist/ 196 | nbdist/ 197 | nbactions.xml 198 | nb-configuration.xml 199 | 200 | 201 | ### vim ### 202 | [._]*.s[a-w][a-z] 203 | [._]s[a-w][a-z] 204 | *.un~ 205 | Session.vim 206 | .netrwhist 207 | *~ 208 | 209 | 210 | ### Emacs ### 211 | # -*- mode: gitignore; -*- 212 | *~ 213 | \#*\# 214 | /.emacs.desktop 215 | /.emacs.desktop.lock 216 | *.elc 217 | auto-save-list 218 | tramp 219 | .\#* 220 | 221 | # Org-mode 222 | .org-id-locations 223 | *_archive 224 | 225 | # flymake-mode 226 | *_flymake.* 227 | 228 | # eshell files 229 | /eshell/history 230 | /eshell/lastdir 231 | 232 | # elpa packages 233 | /elpa/ 234 | 235 | # reftex files 236 | *.rel 237 | 238 | # AUCTeX auto folder 239 | /auto/ 240 | 241 | # cask packages 242 | .cask/ 243 | 244 | build-test 245 | 246 | ### SublimeText ### 247 | # cache files for sublime text 248 | *.tmlanguage.cache 249 | *.tmPreferences.cache 250 | *.stTheme.cache 251 | 252 | # workspace files are user-specific 253 | *.sublime-workspace 254 | 255 | # project files should be checked into the repository, unless a significant 256 | # proportion of contributors will probably not be using SublimeText 257 | # *.sublime-project 258 | 259 | # sftp configuration file 260 | sftp-config.json 261 | 262 | classes/ 263 | workspace.xml -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - oraclejdk8 4 | cache: 5 | directories: 6 | - $HOME/.gradle/wrapper/ 7 | after_success: 8 | - test $TRAVIS_PULL_REQUEST == "false" && test "$TRAVIS_TAG" != "" && test $TRAVIS_REPO_SLUG == "avast/gradle-dependencies-viewer" && -Pversion="$TRAVIS_TAG" --info -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Gradle dependencies viewer (tool) 2 | A simple web UI to analyze dependencies for your project based on the text data generated from ```gradle dependencies``` command. 3 | ![Gradle dependencies viewer (tool) screenshot](https://github.com/avast/gradle-dependencies-viewer/blob/master/web/screenshot.png) 4 | 5 | [![Build Status - Master](https://travis-ci.org/avast/gradle-dependencies-viewer.svg?branch=master)](https://travis-ci.org/avast/gradle-dependencies-viewer) ![Linux](https://img.shields.io/badge/os-linux-green.svg?style=flat) ![Windows](https://img.shields.io/badge/os-windows-green.svg?style=flat) ![Apache 2](https://img.shields.io/badge/license-Apache2-blue.svg?style=flat) 6 | ## Purpose 7 | Since there is still no good support for Gradle dependencies view in IntelliJ IDEA (at least not good as for Maven is) and it's really difficult to browse (especially for larger projects with tens of listed dependencies) we decided to create this very simple tool. 8 | This tool helps us to solve such common dependency-hell problem like *"Where this dependency/artifact came from?"* or *"Which dependencies are coming with this artifact?"*. 9 | 10 | ## Using dependencies viewer 11 | 1. Run command ```gradle dependencies > dep.txt``` inside of your project directory.` 12 | 2. Drag&Drop dep.txt file into input area. File will be automatically uploaded and parsed. Alternativaly you can copy&paste the output of gradle dependencies command into the input area. 13 | 3. Browse dependencies tree in the left panel and/or use search input box to find artifact you need to explore 14 | 4. If you want to generate gradle code to exclude some artifact, press right mouse button to view context menu and select *Exclude artifact*. 15 | 16 | ## Working demo 17 | [You can try to use it here](http://gradle.vity.cz/) 18 | (it's located on Heroku, sometimes it requires more time to load, please be patient) 19 | ## Launching app locally 20 | 21 | #### Requirements: 22 | - JDK 1.8 23 | 24 | #### Running from the latest release 25 | 1. [Download current release](https://github.com/avast/gradle-dependencies-viewer/files/790796/gradle-dependencies-viewer-1.0.0.zip) 26 | 2. Extract zip file and use ```/bin/gradle-dependencies-viewer.bat``` (Win) or ```/bin/gradle-dependencies-viewer``` (Linux) 27 | 28 | **OR** 29 | 30 | #### Running from sources 31 | 1. Build binaries ```gradle build``` or ```gradlew.bat build``` or 32 | 2. Extract ```build/distributions/gradle-dependencies-viewer-x.x.x.zip``` (or .tar on Linux) 33 | 3. Run script ```/bin/gradle-dependencies-viewer.bat``` (Win) or ```/bin/gradle-dependencies-viewer``` (Linux) 34 | 4. **OR** Run single fat jar ```java -jar gradle-dependencies-viewer-1.0.0.jar --server.port=8090``` 35 | - File ```gradle-dependencies-viewer-x.x.x.jar``` is located in ```build/libs```. 36 | 5. Open [http://localhost:8090/](http://localhost:8090/) in your web browser. 37 | - Default port value has been set to 8090. 38 | 39 | 40 | ## Project programming info 41 | The project is using Gradle 7.x to build. The project is based on Spring Boot using Thymeleaf template engine. 42 | 43 | ## License 44 | Apache 2 License. 45 | 46 | ## Contact 47 | Author&Maintainer: Ladislav Vitasek aka Vity - vitasek/@/avast.com 48 | 49 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'idea' 4 | id 'eclipse' 5 | id 'org.springframework.boot' version '2.5.6' 6 | id 'io.spring.dependency-management' version '1.0.11.RELEASE' 7 | 8 | } 9 | 10 | idea { 11 | module { 12 | inheritOutputDirs = false 13 | outputDir = file("$buildDir/classes/main/") 14 | 15 | testOutputDir = file('build-test') 16 | } 17 | } 18 | 19 | repositories { 20 | mavenCentral() 21 | } 22 | 23 | jar { 24 | manifest { 25 | attributes("Implementation-Version": project.getVersion()) 26 | } 27 | } 28 | 29 | 30 | 31 | allprojects { 32 | tasks.withType(Javadoc).all { enabled = false } 33 | } 34 | 35 | sourceCompatibility = 1.8 36 | targetCompatibility = 1.8 37 | 38 | group = "com.avast.server" 39 | 40 | version = '1.0.0' 41 | 42 | dependencies { 43 | implementation 'org.springframework.boot:spring-boot-starter-web' 44 | implementation "org.springframework.boot:spring-boot-starter-thymeleaf" 45 | implementation 'commons-io:commons-io:2.11.0' 46 | 47 | developmentOnly 'org.springframework.boot:spring-boot-devtools' 48 | 49 | testImplementation("org.springframework.boot:spring-boot-starter-test") 50 | } 51 | 52 | test { 53 | useJUnitPlatform() 54 | // afterTest { desc, result -> 55 | // logger.quiet "Executing test ${desc.name} [${desc.className}] with result: ${result.resultType}" 56 | // } 57 | testLogging { 58 | events "passed", "skipped", "failed" 59 | exceptionFormat "full" 60 | //showStandardStreams = true 61 | } 62 | } -------------------------------------------------------------------------------- /dep.txt: -------------------------------------------------------------------------------- 1 | Starting a Gradle Daemon (subsequent builds will be faster) 2 | The plugin id 'spring-boot' is deprecated. Please use 'org.springframework.boot' instead. 3 | :dependencies 4 | 5 | ------------------------------------------------------------ 6 | Root project 7 | ------------------------------------------------------------ 8 | 9 | archives - Configuration for archive artifacts. 10 | No dependencies 11 | 12 | compile - Dependencies for source set 'main'. 13 | +--- org.springframework.boot:spring-boot-starter-thymeleaf:1.4.2.RELEASE 14 | | +--- org.springframework.boot:spring-boot-starter:1.4.2.RELEASE 15 | | | +--- org.springframework.boot:spring-boot:1.4.2.RELEASE 16 | | | | +--- org.springframework:spring-core:4.3.4.RELEASE 17 | | | | \--- org.springframework:spring-context:4.3.4.RELEASE 18 | | | | +--- org.springframework:spring-aop:4.3.4.RELEASE 19 | | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE 20 | | | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 21 | | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 22 | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 23 | | | | +--- org.springframework:spring-core:4.3.4.RELEASE 24 | | | | \--- org.springframework:spring-expression:4.3.4.RELEASE 25 | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 26 | | | +--- org.springframework.boot:spring-boot-autoconfigure:1.4.2.RELEASE 27 | | | | \--- org.springframework.boot:spring-boot:1.4.2.RELEASE (*) 28 | | | +--- org.springframework.boot:spring-boot-starter-logging:1.4.2.RELEASE 29 | | | | +--- ch.qos.logback:logback-classic:1.1.7 30 | | | | | +--- ch.qos.logback:logback-core:1.1.7 31 | | | | | \--- org.slf4j:slf4j-api:1.7.20 -> 1.7.21 32 | | | | +--- org.slf4j:jcl-over-slf4j:1.7.21 33 | | | | | \--- org.slf4j:slf4j-api:1.7.21 34 | | | | +--- org.slf4j:jul-to-slf4j:1.7.21 35 | | | | | \--- org.slf4j:slf4j-api:1.7.21 36 | | | | \--- org.slf4j:log4j-over-slf4j:1.7.21 37 | | | | \--- org.slf4j:slf4j-api:1.7.21 38 | | | +--- org.springframework:spring-core:4.3.4.RELEASE 39 | | | \--- org.yaml:snakeyaml:1.17 40 | | +--- org.springframework.boot:spring-boot-starter-web:1.4.2.RELEASE 41 | | | +--- org.springframework.boot:spring-boot-starter:1.4.2.RELEASE (*) 42 | | | +--- org.springframework.boot:spring-boot-starter-tomcat:1.4.2.RELEASE 43 | | | | +--- org.apache.tomcat.embed:tomcat-embed-core:8.5.6 44 | | | | +--- org.apache.tomcat.embed:tomcat-embed-el:8.5.6 45 | | | | \--- org.apache.tomcat.embed:tomcat-embed-websocket:8.5.6 46 | | | | \--- org.apache.tomcat.embed:tomcat-embed-core:8.5.6 47 | | | +--- org.hibernate:hibernate-validator:5.2.4.Final 48 | | | | +--- javax.validation:validation-api:1.1.0.Final 49 | | | | +--- org.jboss.logging:jboss-logging:3.2.1.Final -> 3.3.0.Final 50 | | | | \--- com.fasterxml:classmate:1.1.0 -> 1.3.3 51 | | | +--- com.fasterxml.jackson.core:jackson-databind:2.8.4 52 | | | | +--- com.fasterxml.jackson.core:jackson-annotations:2.8.0 -> 2.8.4 53 | | | | \--- com.fasterxml.jackson.core:jackson-core:2.8.4 54 | | | +--- org.springframework:spring-web:4.3.4.RELEASE 55 | | | | +--- org.springframework:spring-aop:4.3.4.RELEASE (*) 56 | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 57 | | | | +--- org.springframework:spring-context:4.3.4.RELEASE (*) 58 | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 59 | | | \--- org.springframework:spring-webmvc:4.3.4.RELEASE 60 | | | +--- org.springframework:spring-aop:4.3.4.RELEASE (*) 61 | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 62 | | | +--- org.springframework:spring-context:4.3.4.RELEASE (*) 63 | | | +--- org.springframework:spring-core:4.3.4.RELEASE 64 | | | +--- org.springframework:spring-expression:4.3.4.RELEASE (*) 65 | | | \--- org.springframework:spring-web:4.3.4.RELEASE (*) 66 | | +--- org.thymeleaf:thymeleaf-spring4:2.1.5.RELEASE 67 | | | +--- org.thymeleaf:thymeleaf:2.1.5.RELEASE 68 | | | | +--- ognl:ognl:3.0.8 69 | | | | +--- org.javassist:javassist:3.16.1-GA -> 3.20.0-GA 70 | | | | +--- org.unbescape:unbescape:1.1.0.RELEASE 71 | | | | \--- org.slf4j:slf4j-api:1.6.6 -> 1.7.21 72 | | | \--- org.slf4j:slf4j-api:1.6.6 -> 1.7.21 73 | | \--- nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:1.4.0 74 | | +--- org.codehaus.groovy:groovy:2.4.3 -> 2.4.7 75 | | \--- org.thymeleaf:thymeleaf:2.1.4.RELEASE -> 2.1.5.RELEASE (*) 76 | +--- org.springframework.boot:spring-boot-devtools:1.4.2.RELEASE 77 | | +--- org.springframework.boot:spring-boot:1.4.2.RELEASE (*) 78 | | \--- org.springframework.boot:spring-boot-autoconfigure:1.4.2.RELEASE (*) 79 | \--- commons-io:commons-io:2.5 80 | 81 | compileClasspath - Compile classpath for source set 'main'. 82 | +--- org.springframework.boot:spring-boot-starter-thymeleaf:1.4.2.RELEASE 83 | | +--- org.springframework.boot:spring-boot-starter:1.4.2.RELEASE 84 | | | +--- org.springframework.boot:spring-boot:1.4.2.RELEASE 85 | | | | +--- org.springframework:spring-core:4.3.4.RELEASE 86 | | | | \--- org.springframework:spring-context:4.3.4.RELEASE 87 | | | | +--- org.springframework:spring-aop:4.3.4.RELEASE 88 | | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE 89 | | | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 90 | | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 91 | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 92 | | | | +--- org.springframework:spring-core:4.3.4.RELEASE 93 | | | | \--- org.springframework:spring-expression:4.3.4.RELEASE 94 | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 95 | | | +--- org.springframework.boot:spring-boot-autoconfigure:1.4.2.RELEASE 96 | | | | \--- org.springframework.boot:spring-boot:1.4.2.RELEASE (*) 97 | | | +--- org.springframework.boot:spring-boot-starter-logging:1.4.2.RELEASE 98 | | | | +--- ch.qos.logback:logback-classic:1.1.7 99 | | | | | +--- ch.qos.logback:logback-core:1.1.7 100 | | | | | \--- org.slf4j:slf4j-api:1.7.20 -> 1.7.21 101 | | | | +--- org.slf4j:jcl-over-slf4j:1.7.21 102 | | | | | \--- org.slf4j:slf4j-api:1.7.21 103 | | | | +--- org.slf4j:jul-to-slf4j:1.7.21 104 | | | | | \--- org.slf4j:slf4j-api:1.7.21 105 | | | | \--- org.slf4j:log4j-over-slf4j:1.7.21 106 | | | | \--- org.slf4j:slf4j-api:1.7.21 107 | | | +--- org.springframework:spring-core:4.3.4.RELEASE 108 | | | \--- org.yaml:snakeyaml:1.17 109 | | +--- org.springframework.boot:spring-boot-starter-web:1.4.2.RELEASE 110 | | | +--- org.springframework.boot:spring-boot-starter:1.4.2.RELEASE (*) 111 | | | +--- org.springframework.boot:spring-boot-starter-tomcat:1.4.2.RELEASE 112 | | | | +--- org.apache.tomcat.embed:tomcat-embed-core:8.5.6 113 | | | | +--- org.apache.tomcat.embed:tomcat-embed-el:8.5.6 114 | | | | \--- org.apache.tomcat.embed:tomcat-embed-websocket:8.5.6 115 | | | | \--- org.apache.tomcat.embed:tomcat-embed-core:8.5.6 116 | | | +--- org.hibernate:hibernate-validator:5.2.4.Final 117 | | | | +--- javax.validation:validation-api:1.1.0.Final 118 | | | | +--- org.jboss.logging:jboss-logging:3.2.1.Final -> 3.3.0.Final 119 | | | | \--- com.fasterxml:classmate:1.1.0 -> 1.3.3 120 | | | +--- com.fasterxml.jackson.core:jackson-databind:2.8.4 121 | | | | +--- com.fasterxml.jackson.core:jackson-annotations:2.8.0 -> 2.8.4 122 | | | | \--- com.fasterxml.jackson.core:jackson-core:2.8.4 123 | | | +--- org.springframework:spring-web:4.3.4.RELEASE 124 | | | | +--- org.springframework:spring-aop:4.3.4.RELEASE (*) 125 | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 126 | | | | +--- org.springframework:spring-context:4.3.4.RELEASE (*) 127 | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 128 | | | \--- org.springframework:spring-webmvc:4.3.4.RELEASE 129 | | | +--- org.springframework:spring-aop:4.3.4.RELEASE (*) 130 | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 131 | | | +--- org.springframework:spring-context:4.3.4.RELEASE (*) 132 | | | +--- org.springframework:spring-core:4.3.4.RELEASE 133 | | | +--- org.springframework:spring-expression:4.3.4.RELEASE (*) 134 | | | \--- org.springframework:spring-web:4.3.4.RELEASE (*) 135 | | +--- org.thymeleaf:thymeleaf-spring4:2.1.5.RELEASE 136 | | | +--- org.thymeleaf:thymeleaf:2.1.5.RELEASE 137 | | | | +--- ognl:ognl:3.0.8 138 | | | | +--- org.javassist:javassist:3.16.1-GA -> 3.20.0-GA 139 | | | | +--- org.unbescape:unbescape:1.1.0.RELEASE 140 | | | | \--- org.slf4j:slf4j-api:1.6.6 -> 1.7.21 141 | | | \--- org.slf4j:slf4j-api:1.6.6 -> 1.7.21 142 | | \--- nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:1.4.0 143 | | +--- org.codehaus.groovy:groovy:2.4.3 -> 2.4.7 144 | | \--- org.thymeleaf:thymeleaf:2.1.4.RELEASE -> 2.1.5.RELEASE (*) 145 | +--- org.springframework.boot:spring-boot-devtools:1.4.2.RELEASE 146 | | +--- org.springframework.boot:spring-boot:1.4.2.RELEASE (*) 147 | | \--- org.springframework.boot:spring-boot-autoconfigure:1.4.2.RELEASE (*) 148 | \--- commons-io:commons-io:2.5 149 | 150 | compileOnly - Compile dependencies for source set 'main'. 151 | +--- org.springframework.boot:spring-boot-starter-thymeleaf:1.4.2.RELEASE 152 | | +--- org.springframework.boot:spring-boot-starter:1.4.2.RELEASE 153 | | | +--- org.springframework.boot:spring-boot:1.4.2.RELEASE 154 | | | | +--- org.springframework:spring-core:4.3.4.RELEASE 155 | | | | \--- org.springframework:spring-context:4.3.4.RELEASE 156 | | | | +--- org.springframework:spring-aop:4.3.4.RELEASE 157 | | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE 158 | | | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 159 | | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 160 | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 161 | | | | +--- org.springframework:spring-core:4.3.4.RELEASE 162 | | | | \--- org.springframework:spring-expression:4.3.4.RELEASE 163 | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 164 | | | +--- org.springframework.boot:spring-boot-autoconfigure:1.4.2.RELEASE 165 | | | | \--- org.springframework.boot:spring-boot:1.4.2.RELEASE (*) 166 | | | +--- org.springframework.boot:spring-boot-starter-logging:1.4.2.RELEASE 167 | | | | +--- ch.qos.logback:logback-classic:1.1.7 168 | | | | | +--- ch.qos.logback:logback-core:1.1.7 169 | | | | | \--- org.slf4j:slf4j-api:1.7.20 -> 1.7.21 170 | | | | +--- org.slf4j:jcl-over-slf4j:1.7.21 171 | | | | | \--- org.slf4j:slf4j-api:1.7.21 172 | | | | +--- org.slf4j:jul-to-slf4j:1.7.21 173 | | | | | \--- org.slf4j:slf4j-api:1.7.21 174 | | | | \--- org.slf4j:log4j-over-slf4j:1.7.21 175 | | | | \--- org.slf4j:slf4j-api:1.7.21 176 | | | +--- org.springframework:spring-core:4.3.4.RELEASE 177 | | | \--- org.yaml:snakeyaml:1.17 178 | | +--- org.springframework.boot:spring-boot-starter-web:1.4.2.RELEASE 179 | | | +--- org.springframework.boot:spring-boot-starter:1.4.2.RELEASE (*) 180 | | | +--- org.springframework.boot:spring-boot-starter-tomcat:1.4.2.RELEASE 181 | | | | +--- org.apache.tomcat.embed:tomcat-embed-core:8.5.6 182 | | | | +--- org.apache.tomcat.embed:tomcat-embed-el:8.5.6 183 | | | | \--- org.apache.tomcat.embed:tomcat-embed-websocket:8.5.6 184 | | | | \--- org.apache.tomcat.embed:tomcat-embed-core:8.5.6 185 | | | +--- org.hibernate:hibernate-validator:5.2.4.Final 186 | | | | +--- javax.validation:validation-api:1.1.0.Final 187 | | | | +--- org.jboss.logging:jboss-logging:3.2.1.Final -> 3.3.0.Final 188 | | | | \--- com.fasterxml:classmate:1.1.0 -> 1.3.3 189 | | | +--- com.fasterxml.jackson.core:jackson-databind:2.8.4 190 | | | | +--- com.fasterxml.jackson.core:jackson-annotations:2.8.0 -> 2.8.4 191 | | | | \--- com.fasterxml.jackson.core:jackson-core:2.8.4 192 | | | +--- org.springframework:spring-web:4.3.4.RELEASE 193 | | | | +--- org.springframework:spring-aop:4.3.4.RELEASE (*) 194 | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 195 | | | | +--- org.springframework:spring-context:4.3.4.RELEASE (*) 196 | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 197 | | | \--- org.springframework:spring-webmvc:4.3.4.RELEASE 198 | | | +--- org.springframework:spring-aop:4.3.4.RELEASE (*) 199 | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 200 | | | +--- org.springframework:spring-context:4.3.4.RELEASE (*) 201 | | | +--- org.springframework:spring-core:4.3.4.RELEASE 202 | | | +--- org.springframework:spring-expression:4.3.4.RELEASE (*) 203 | | | \--- org.springframework:spring-web:4.3.4.RELEASE (*) 204 | | +--- org.thymeleaf:thymeleaf-spring4:2.1.5.RELEASE 205 | | | +--- org.thymeleaf:thymeleaf:2.1.5.RELEASE 206 | | | | +--- ognl:ognl:3.0.8 207 | | | | +--- org.javassist:javassist:3.16.1-GA -> 3.20.0-GA 208 | | | | +--- org.unbescape:unbescape:1.1.0.RELEASE 209 | | | | \--- org.slf4j:slf4j-api:1.6.6 -> 1.7.21 210 | | | \--- org.slf4j:slf4j-api:1.6.6 -> 1.7.21 211 | | \--- nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:1.4.0 212 | | +--- org.codehaus.groovy:groovy:2.4.3 -> 2.4.7 213 | | \--- org.thymeleaf:thymeleaf:2.1.4.RELEASE -> 2.1.5.RELEASE (*) 214 | +--- org.springframework.boot:spring-boot-devtools:1.4.2.RELEASE 215 | | +--- org.springframework.boot:spring-boot:1.4.2.RELEASE (*) 216 | | \--- org.springframework.boot:spring-boot-autoconfigure:1.4.2.RELEASE (*) 217 | \--- commons-io:commons-io:2.5 218 | 219 | default - Configuration for default artifacts. 220 | +--- org.springframework.boot:spring-boot-starter-thymeleaf:1.4.2.RELEASE 221 | | +--- org.springframework.boot:spring-boot-starter:1.4.2.RELEASE 222 | | | +--- org.springframework.boot:spring-boot:1.4.2.RELEASE 223 | | | | +--- org.springframework:spring-core:4.3.4.RELEASE 224 | | | | \--- org.springframework:spring-context:4.3.4.RELEASE 225 | | | | +--- org.springframework:spring-aop:4.3.4.RELEASE 226 | | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE 227 | | | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 228 | | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 229 | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 230 | | | | +--- org.springframework:spring-core:4.3.4.RELEASE 231 | | | | \--- org.springframework:spring-expression:4.3.4.RELEASE 232 | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 233 | | | +--- org.springframework.boot:spring-boot-autoconfigure:1.4.2.RELEASE 234 | | | | \--- org.springframework.boot:spring-boot:1.4.2.RELEASE (*) 235 | | | +--- org.springframework.boot:spring-boot-starter-logging:1.4.2.RELEASE 236 | | | | +--- ch.qos.logback:logback-classic:1.1.7 237 | | | | | +--- ch.qos.logback:logback-core:1.1.7 238 | | | | | \--- org.slf4j:slf4j-api:1.7.20 -> 1.7.21 239 | | | | +--- org.slf4j:jcl-over-slf4j:1.7.21 240 | | | | | \--- org.slf4j:slf4j-api:1.7.21 241 | | | | +--- org.slf4j:jul-to-slf4j:1.7.21 242 | | | | | \--- org.slf4j:slf4j-api:1.7.21 243 | | | | \--- org.slf4j:log4j-over-slf4j:1.7.21 244 | | | | \--- org.slf4j:slf4j-api:1.7.21 245 | | | +--- org.springframework:spring-core:4.3.4.RELEASE 246 | | | \--- org.yaml:snakeyaml:1.17 247 | | +--- org.springframework.boot:spring-boot-starter-web:1.4.2.RELEASE 248 | | | +--- org.springframework.boot:spring-boot-starter:1.4.2.RELEASE (*) 249 | | | +--- org.springframework.boot:spring-boot-starter-tomcat:1.4.2.RELEASE 250 | | | | +--- org.apache.tomcat.embed:tomcat-embed-core:8.5.6 251 | | | | +--- org.apache.tomcat.embed:tomcat-embed-el:8.5.6 252 | | | | \--- org.apache.tomcat.embed:tomcat-embed-websocket:8.5.6 253 | | | | \--- org.apache.tomcat.embed:tomcat-embed-core:8.5.6 254 | | | +--- org.hibernate:hibernate-validator:5.2.4.Final 255 | | | | +--- javax.validation:validation-api:1.1.0.Final 256 | | | | +--- org.jboss.logging:jboss-logging:3.2.1.Final -> 3.3.0.Final 257 | | | | \--- com.fasterxml:classmate:1.1.0 -> 1.3.3 258 | | | +--- com.fasterxml.jackson.core:jackson-databind:2.8.4 259 | | | | +--- com.fasterxml.jackson.core:jackson-annotations:2.8.0 -> 2.8.4 260 | | | | \--- com.fasterxml.jackson.core:jackson-core:2.8.4 261 | | | +--- org.springframework:spring-web:4.3.4.RELEASE 262 | | | | +--- org.springframework:spring-aop:4.3.4.RELEASE (*) 263 | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 264 | | | | +--- org.springframework:spring-context:4.3.4.RELEASE (*) 265 | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 266 | | | \--- org.springframework:spring-webmvc:4.3.4.RELEASE 267 | | | +--- org.springframework:spring-aop:4.3.4.RELEASE (*) 268 | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 269 | | | +--- org.springframework:spring-context:4.3.4.RELEASE (*) 270 | | | +--- org.springframework:spring-core:4.3.4.RELEASE 271 | | | +--- org.springframework:spring-expression:4.3.4.RELEASE (*) 272 | | | \--- org.springframework:spring-web:4.3.4.RELEASE (*) 273 | | +--- org.thymeleaf:thymeleaf-spring4:2.1.5.RELEASE 274 | | | +--- org.thymeleaf:thymeleaf:2.1.5.RELEASE 275 | | | | +--- ognl:ognl:3.0.8 276 | | | | +--- org.javassist:javassist:3.16.1-GA -> 3.20.0-GA 277 | | | | +--- org.unbescape:unbescape:1.1.0.RELEASE 278 | | | | \--- org.slf4j:slf4j-api:1.6.6 -> 1.7.21 279 | | | \--- org.slf4j:slf4j-api:1.6.6 -> 1.7.21 280 | | \--- nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:1.4.0 281 | | +--- org.codehaus.groovy:groovy:2.4.3 -> 2.4.7 282 | | \--- org.thymeleaf:thymeleaf:2.1.4.RELEASE -> 2.1.5.RELEASE (*) 283 | +--- org.springframework.boot:spring-boot-devtools:1.4.2.RELEASE 284 | | +--- org.springframework.boot:spring-boot:1.4.2.RELEASE (*) 285 | | \--- org.springframework.boot:spring-boot-autoconfigure:1.4.2.RELEASE (*) 286 | \--- commons-io:commons-io:2.5 287 | 288 | runtime - Runtime dependencies for source set 'main'. 289 | +--- org.springframework.boot:spring-boot-starter-thymeleaf:1.4.2.RELEASE 290 | | +--- org.springframework.boot:spring-boot-starter:1.4.2.RELEASE 291 | | | +--- org.springframework.boot:spring-boot:1.4.2.RELEASE 292 | | | | +--- org.springframework:spring-core:4.3.4.RELEASE 293 | | | | \--- org.springframework:spring-context:4.3.4.RELEASE 294 | | | | +--- org.springframework:spring-aop:4.3.4.RELEASE 295 | | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE 296 | | | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 297 | | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 298 | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 299 | | | | +--- org.springframework:spring-core:4.3.4.RELEASE 300 | | | | \--- org.springframework:spring-expression:4.3.4.RELEASE 301 | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 302 | | | +--- org.springframework.boot:spring-boot-autoconfigure:1.4.2.RELEASE 303 | | | | \--- org.springframework.boot:spring-boot:1.4.2.RELEASE (*) 304 | | | +--- org.springframework.boot:spring-boot-starter-logging:1.4.2.RELEASE 305 | | | | +--- ch.qos.logback:logback-classic:1.1.7 306 | | | | | +--- ch.qos.logback:logback-core:1.1.7 307 | | | | | \--- org.slf4j:slf4j-api:1.7.20 -> 1.7.21 308 | | | | +--- org.slf4j:jcl-over-slf4j:1.7.21 309 | | | | | \--- org.slf4j:slf4j-api:1.7.21 310 | | | | +--- org.slf4j:jul-to-slf4j:1.7.21 311 | | | | | \--- org.slf4j:slf4j-api:1.7.21 312 | | | | \--- org.slf4j:log4j-over-slf4j:1.7.21 313 | | | | \--- org.slf4j:slf4j-api:1.7.21 314 | | | +--- org.springframework:spring-core:4.3.4.RELEASE 315 | | | \--- org.yaml:snakeyaml:1.17 316 | | +--- org.springframework.boot:spring-boot-starter-web:1.4.2.RELEASE 317 | | | +--- org.springframework.boot:spring-boot-starter:1.4.2.RELEASE (*) 318 | | | +--- org.springframework.boot:spring-boot-starter-tomcat:1.4.2.RELEASE 319 | | | | +--- org.apache.tomcat.embed:tomcat-embed-core:8.5.6 320 | | | | +--- org.apache.tomcat.embed:tomcat-embed-el:8.5.6 321 | | | | \--- org.apache.tomcat.embed:tomcat-embed-websocket:8.5.6 322 | | | | \--- org.apache.tomcat.embed:tomcat-embed-core:8.5.6 323 | | | +--- org.hibernate:hibernate-validator:5.2.4.Final 324 | | | | +--- javax.validation:validation-api:1.1.0.Final 325 | | | | +--- org.jboss.logging:jboss-logging:3.2.1.Final -> 3.3.0.Final 326 | | | | \--- com.fasterxml:classmate:1.1.0 -> 1.3.3 327 | | | +--- com.fasterxml.jackson.core:jackson-databind:2.8.4 328 | | | | +--- com.fasterxml.jackson.core:jackson-annotations:2.8.0 -> 2.8.4 329 | | | | \--- com.fasterxml.jackson.core:jackson-core:2.8.4 330 | | | +--- org.springframework:spring-web:4.3.4.RELEASE 331 | | | | +--- org.springframework:spring-aop:4.3.4.RELEASE (*) 332 | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 333 | | | | +--- org.springframework:spring-context:4.3.4.RELEASE (*) 334 | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 335 | | | \--- org.springframework:spring-webmvc:4.3.4.RELEASE 336 | | | +--- org.springframework:spring-aop:4.3.4.RELEASE (*) 337 | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 338 | | | +--- org.springframework:spring-context:4.3.4.RELEASE (*) 339 | | | +--- org.springframework:spring-core:4.3.4.RELEASE 340 | | | +--- org.springframework:spring-expression:4.3.4.RELEASE (*) 341 | | | \--- org.springframework:spring-web:4.3.4.RELEASE (*) 342 | | +--- org.thymeleaf:thymeleaf-spring4:2.1.5.RELEASE 343 | | | +--- org.thymeleaf:thymeleaf:2.1.5.RELEASE 344 | | | | +--- ognl:ognl:3.0.8 345 | | | | +--- org.javassist:javassist:3.16.1-GA -> 3.20.0-GA 346 | | | | +--- org.unbescape:unbescape:1.1.0.RELEASE 347 | | | | \--- org.slf4j:slf4j-api:1.6.6 -> 1.7.21 348 | | | \--- org.slf4j:slf4j-api:1.6.6 -> 1.7.21 349 | | \--- nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:1.4.0 350 | | +--- org.codehaus.groovy:groovy:2.4.3 -> 2.4.7 351 | | \--- org.thymeleaf:thymeleaf:2.1.4.RELEASE -> 2.1.5.RELEASE (*) 352 | +--- org.springframework.boot:spring-boot-devtools:1.4.2.RELEASE 353 | | +--- org.springframework.boot:spring-boot:1.4.2.RELEASE (*) 354 | | \--- org.springframework.boot:spring-boot-autoconfigure:1.4.2.RELEASE (*) 355 | \--- commons-io:commons-io:2.5 356 | 357 | testCompile - Dependencies for source set 'test'. 358 | +--- org.springframework.boot:spring-boot-starter-thymeleaf:1.4.2.RELEASE 359 | | +--- org.springframework.boot:spring-boot-starter:1.4.2.RELEASE 360 | | | +--- org.springframework.boot:spring-boot:1.4.2.RELEASE 361 | | | | +--- org.springframework:spring-core:4.3.4.RELEASE 362 | | | | \--- org.springframework:spring-context:4.3.4.RELEASE 363 | | | | +--- org.springframework:spring-aop:4.3.4.RELEASE 364 | | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE 365 | | | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 366 | | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 367 | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 368 | | | | +--- org.springframework:spring-core:4.3.4.RELEASE 369 | | | | \--- org.springframework:spring-expression:4.3.4.RELEASE 370 | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 371 | | | +--- org.springframework.boot:spring-boot-autoconfigure:1.4.2.RELEASE 372 | | | | \--- org.springframework.boot:spring-boot:1.4.2.RELEASE (*) 373 | | | +--- org.springframework.boot:spring-boot-starter-logging:1.4.2.RELEASE 374 | | | | +--- ch.qos.logback:logback-classic:1.1.7 375 | | | | | +--- ch.qos.logback:logback-core:1.1.7 376 | | | | | \--- org.slf4j:slf4j-api:1.7.20 -> 1.7.21 377 | | | | +--- org.slf4j:jcl-over-slf4j:1.7.21 378 | | | | | \--- org.slf4j:slf4j-api:1.7.21 379 | | | | +--- org.slf4j:jul-to-slf4j:1.7.21 380 | | | | | \--- org.slf4j:slf4j-api:1.7.21 381 | | | | \--- org.slf4j:log4j-over-slf4j:1.7.21 382 | | | | \--- org.slf4j:slf4j-api:1.7.21 383 | | | +--- org.springframework:spring-core:4.3.4.RELEASE 384 | | | \--- org.yaml:snakeyaml:1.17 385 | | +--- org.springframework.boot:spring-boot-starter-web:1.4.2.RELEASE 386 | | | +--- org.springframework.boot:spring-boot-starter:1.4.2.RELEASE (*) 387 | | | +--- org.springframework.boot:spring-boot-starter-tomcat:1.4.2.RELEASE 388 | | | | +--- org.apache.tomcat.embed:tomcat-embed-core:8.5.6 389 | | | | +--- org.apache.tomcat.embed:tomcat-embed-el:8.5.6 390 | | | | \--- org.apache.tomcat.embed:tomcat-embed-websocket:8.5.6 391 | | | | \--- org.apache.tomcat.embed:tomcat-embed-core:8.5.6 392 | | | +--- org.hibernate:hibernate-validator:5.2.4.Final 393 | | | | +--- javax.validation:validation-api:1.1.0.Final 394 | | | | +--- org.jboss.logging:jboss-logging:3.2.1.Final -> 3.3.0.Final 395 | | | | \--- com.fasterxml:classmate:1.1.0 -> 1.3.3 396 | | | +--- com.fasterxml.jackson.core:jackson-databind:2.8.4 397 | | | | +--- com.fasterxml.jackson.core:jackson-annotations:2.8.0 -> 2.8.4 398 | | | | \--- com.fasterxml.jackson.core:jackson-core:2.8.4 399 | | | +--- org.springframework:spring-web:4.3.4.RELEASE 400 | | | | +--- org.springframework:spring-aop:4.3.4.RELEASE (*) 401 | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 402 | | | | +--- org.springframework:spring-context:4.3.4.RELEASE (*) 403 | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 404 | | | \--- org.springframework:spring-webmvc:4.3.4.RELEASE 405 | | | +--- org.springframework:spring-aop:4.3.4.RELEASE (*) 406 | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 407 | | | +--- org.springframework:spring-context:4.3.4.RELEASE (*) 408 | | | +--- org.springframework:spring-core:4.3.4.RELEASE 409 | | | +--- org.springframework:spring-expression:4.3.4.RELEASE (*) 410 | | | \--- org.springframework:spring-web:4.3.4.RELEASE (*) 411 | | +--- org.thymeleaf:thymeleaf-spring4:2.1.5.RELEASE 412 | | | +--- org.thymeleaf:thymeleaf:2.1.5.RELEASE 413 | | | | +--- ognl:ognl:3.0.8 414 | | | | +--- org.javassist:javassist:3.16.1-GA -> 3.20.0-GA 415 | | | | +--- org.unbescape:unbescape:1.1.0.RELEASE 416 | | | | \--- org.slf4j:slf4j-api:1.6.6 -> 1.7.21 417 | | | \--- org.slf4j:slf4j-api:1.6.6 -> 1.7.21 418 | | \--- nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:1.4.0 419 | | +--- org.codehaus.groovy:groovy:2.4.3 -> 2.4.7 420 | | \--- org.thymeleaf:thymeleaf:2.1.4.RELEASE -> 2.1.5.RELEASE (*) 421 | +--- org.springframework.boot:spring-boot-devtools:1.4.2.RELEASE 422 | | +--- org.springframework.boot:spring-boot:1.4.2.RELEASE (*) 423 | | \--- org.springframework.boot:spring-boot-autoconfigure:1.4.2.RELEASE (*) 424 | +--- commons-io:commons-io:2.5 425 | \--- org.springframework.boot:spring-boot-starter-test:1.4.2.RELEASE 426 | +--- org.springframework.boot:spring-boot-test:1.4.2.RELEASE 427 | | \--- org.springframework.boot:spring-boot:1.4.2.RELEASE (*) 428 | +--- org.springframework.boot:spring-boot-test-autoconfigure:1.4.2.RELEASE 429 | | +--- org.springframework.boot:spring-boot-test:1.4.2.RELEASE (*) 430 | | \--- org.springframework.boot:spring-boot-autoconfigure:1.4.2.RELEASE (*) 431 | +--- com.jayway.jsonpath:json-path:2.2.0 432 | | +--- net.minidev:json-smart:2.2.1 433 | | | \--- net.minidev:accessors-smart:1.1 434 | | | \--- org.ow2.asm:asm:5.0.3 435 | | \--- org.slf4j:slf4j-api:1.7.16 -> 1.7.21 436 | +--- junit:junit:4.12 437 | | \--- org.hamcrest:hamcrest-core:1.3 438 | +--- org.assertj:assertj-core:2.5.0 439 | +--- org.mockito:mockito-core:1.10.19 440 | | +--- org.hamcrest:hamcrest-core:1.1 -> 1.3 441 | | \--- org.objenesis:objenesis:2.1 442 | +--- org.hamcrest:hamcrest-core:1.3 443 | +--- org.hamcrest:hamcrest-library:1.3 444 | | \--- org.hamcrest:hamcrest-core:1.3 445 | +--- org.skyscreamer:jsonassert:1.3.0 446 | | \--- org.json:json:20090211 -> 20140107 447 | +--- org.springframework:spring-core:4.3.4.RELEASE 448 | \--- org.springframework:spring-test:4.3.4.RELEASE 449 | \--- org.springframework:spring-core:4.3.4.RELEASE 450 | 451 | testCompileClasspath - Compile classpath for source set 'test'. 452 | +--- org.springframework.boot:spring-boot-starter-thymeleaf:1.4.2.RELEASE 453 | | +--- org.springframework.boot:spring-boot-starter:1.4.2.RELEASE 454 | | | +--- org.springframework.boot:spring-boot:1.4.2.RELEASE 455 | | | | +--- org.springframework:spring-core:4.3.4.RELEASE 456 | | | | \--- org.springframework:spring-context:4.3.4.RELEASE 457 | | | | +--- org.springframework:spring-aop:4.3.4.RELEASE 458 | | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE 459 | | | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 460 | | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 461 | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 462 | | | | +--- org.springframework:spring-core:4.3.4.RELEASE 463 | | | | \--- org.springframework:spring-expression:4.3.4.RELEASE 464 | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 465 | | | +--- org.springframework.boot:spring-boot-autoconfigure:1.4.2.RELEASE 466 | | | | \--- org.springframework.boot:spring-boot:1.4.2.RELEASE (*) 467 | | | +--- org.springframework.boot:spring-boot-starter-logging:1.4.2.RELEASE 468 | | | | +--- ch.qos.logback:logback-classic:1.1.7 469 | | | | | +--- ch.qos.logback:logback-core:1.1.7 470 | | | | | \--- org.slf4j:slf4j-api:1.7.20 -> 1.7.21 471 | | | | +--- org.slf4j:jcl-over-slf4j:1.7.21 472 | | | | | \--- org.slf4j:slf4j-api:1.7.21 473 | | | | +--- org.slf4j:jul-to-slf4j:1.7.21 474 | | | | | \--- org.slf4j:slf4j-api:1.7.21 475 | | | | \--- org.slf4j:log4j-over-slf4j:1.7.21 476 | | | | \--- org.slf4j:slf4j-api:1.7.21 477 | | | +--- org.springframework:spring-core:4.3.4.RELEASE 478 | | | \--- org.yaml:snakeyaml:1.17 479 | | +--- org.springframework.boot:spring-boot-starter-web:1.4.2.RELEASE 480 | | | +--- org.springframework.boot:spring-boot-starter:1.4.2.RELEASE (*) 481 | | | +--- org.springframework.boot:spring-boot-starter-tomcat:1.4.2.RELEASE 482 | | | | +--- org.apache.tomcat.embed:tomcat-embed-core:8.5.6 483 | | | | +--- org.apache.tomcat.embed:tomcat-embed-el:8.5.6 484 | | | | \--- org.apache.tomcat.embed:tomcat-embed-websocket:8.5.6 485 | | | | \--- org.apache.tomcat.embed:tomcat-embed-core:8.5.6 486 | | | +--- org.hibernate:hibernate-validator:5.2.4.Final 487 | | | | +--- javax.validation:validation-api:1.1.0.Final 488 | | | | +--- org.jboss.logging:jboss-logging:3.2.1.Final -> 3.3.0.Final 489 | | | | \--- com.fasterxml:classmate:1.1.0 -> 1.3.3 490 | | | +--- com.fasterxml.jackson.core:jackson-databind:2.8.4 491 | | | | +--- com.fasterxml.jackson.core:jackson-annotations:2.8.0 -> 2.8.4 492 | | | | \--- com.fasterxml.jackson.core:jackson-core:2.8.4 493 | | | +--- org.springframework:spring-web:4.3.4.RELEASE 494 | | | | +--- org.springframework:spring-aop:4.3.4.RELEASE (*) 495 | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 496 | | | | +--- org.springframework:spring-context:4.3.4.RELEASE (*) 497 | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 498 | | | \--- org.springframework:spring-webmvc:4.3.4.RELEASE 499 | | | +--- org.springframework:spring-aop:4.3.4.RELEASE (*) 500 | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 501 | | | +--- org.springframework:spring-context:4.3.4.RELEASE (*) 502 | | | +--- org.springframework:spring-core:4.3.4.RELEASE 503 | | | +--- org.springframework:spring-expression:4.3.4.RELEASE (*) 504 | | | \--- org.springframework:spring-web:4.3.4.RELEASE (*) 505 | | +--- org.thymeleaf:thymeleaf-spring4:2.1.5.RELEASE 506 | | | +--- org.thymeleaf:thymeleaf:2.1.5.RELEASE 507 | | | | +--- ognl:ognl:3.0.8 508 | | | | +--- org.javassist:javassist:3.16.1-GA -> 3.20.0-GA 509 | | | | +--- org.unbescape:unbescape:1.1.0.RELEASE 510 | | | | \--- org.slf4j:slf4j-api:1.6.6 -> 1.7.21 511 | | | \--- org.slf4j:slf4j-api:1.6.6 -> 1.7.21 512 | | \--- nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:1.4.0 513 | | +--- org.codehaus.groovy:groovy:2.4.3 -> 2.4.7 514 | | \--- org.thymeleaf:thymeleaf:2.1.4.RELEASE -> 2.1.5.RELEASE (*) 515 | +--- org.springframework.boot:spring-boot-devtools:1.4.2.RELEASE 516 | | +--- org.springframework.boot:spring-boot:1.4.2.RELEASE (*) 517 | | \--- org.springframework.boot:spring-boot-autoconfigure:1.4.2.RELEASE (*) 518 | +--- commons-io:commons-io:2.5 519 | \--- org.springframework.boot:spring-boot-starter-test:1.4.2.RELEASE 520 | +--- org.springframework.boot:spring-boot-test:1.4.2.RELEASE 521 | | \--- org.springframework.boot:spring-boot:1.4.2.RELEASE (*) 522 | +--- org.springframework.boot:spring-boot-test-autoconfigure:1.4.2.RELEASE 523 | | +--- org.springframework.boot:spring-boot-test:1.4.2.RELEASE (*) 524 | | \--- org.springframework.boot:spring-boot-autoconfigure:1.4.2.RELEASE (*) 525 | +--- com.jayway.jsonpath:json-path:2.2.0 526 | | +--- net.minidev:json-smart:2.2.1 527 | | | \--- net.minidev:accessors-smart:1.1 528 | | | \--- org.ow2.asm:asm:5.0.3 529 | | \--- org.slf4j:slf4j-api:1.7.16 -> 1.7.21 530 | +--- junit:junit:4.12 531 | | \--- org.hamcrest:hamcrest-core:1.3 532 | +--- org.assertj:assertj-core:2.5.0 533 | +--- org.mockito:mockito-core:1.10.19 534 | | +--- org.hamcrest:hamcrest-core:1.1 -> 1.3 535 | | \--- org.objenesis:objenesis:2.1 536 | +--- org.hamcrest:hamcrest-core:1.3 537 | +--- org.hamcrest:hamcrest-library:1.3 538 | | \--- org.hamcrest:hamcrest-core:1.3 539 | +--- org.skyscreamer:jsonassert:1.3.0 540 | | \--- org.json:json:20090211 -> 20140107 541 | +--- org.springframework:spring-core:4.3.4.RELEASE 542 | \--- org.springframework:spring-test:4.3.4.RELEASE 543 | \--- org.springframework:spring-core:4.3.4.RELEASE 544 | 545 | testCompileOnly - Compile dependencies for source set 'test'. 546 | +--- org.springframework.boot:spring-boot-starter-thymeleaf:1.4.2.RELEASE 547 | | +--- org.springframework.boot:spring-boot-starter:1.4.2.RELEASE 548 | | | +--- org.springframework.boot:spring-boot:1.4.2.RELEASE 549 | | | | +--- org.springframework:spring-core:4.3.4.RELEASE 550 | | | | \--- org.springframework:spring-context:4.3.4.RELEASE 551 | | | | +--- org.springframework:spring-aop:4.3.4.RELEASE 552 | | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE 553 | | | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 554 | | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 555 | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 556 | | | | +--- org.springframework:spring-core:4.3.4.RELEASE 557 | | | | \--- org.springframework:spring-expression:4.3.4.RELEASE 558 | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 559 | | | +--- org.springframework.boot:spring-boot-autoconfigure:1.4.2.RELEASE 560 | | | | \--- org.springframework.boot:spring-boot:1.4.2.RELEASE (*) 561 | | | +--- org.springframework.boot:spring-boot-starter-logging:1.4.2.RELEASE 562 | | | | +--- ch.qos.logback:logback-classic:1.1.7 563 | | | | | +--- ch.qos.logback:logback-core:1.1.7 564 | | | | | \--- org.slf4j:slf4j-api:1.7.20 -> 1.7.21 565 | | | | +--- org.slf4j:jcl-over-slf4j:1.7.21 566 | | | | | \--- org.slf4j:slf4j-api:1.7.21 567 | | | | +--- org.slf4j:jul-to-slf4j:1.7.21 568 | | | | | \--- org.slf4j:slf4j-api:1.7.21 569 | | | | \--- org.slf4j:log4j-over-slf4j:1.7.21 570 | | | | \--- org.slf4j:slf4j-api:1.7.21 571 | | | +--- org.springframework:spring-core:4.3.4.RELEASE 572 | | | \--- org.yaml:snakeyaml:1.17 573 | | +--- org.springframework.boot:spring-boot-starter-web:1.4.2.RELEASE 574 | | | +--- org.springframework.boot:spring-boot-starter:1.4.2.RELEASE (*) 575 | | | +--- org.springframework.boot:spring-boot-starter-tomcat:1.4.2.RELEASE 576 | | | | +--- org.apache.tomcat.embed:tomcat-embed-core:8.5.6 577 | | | | +--- org.apache.tomcat.embed:tomcat-embed-el:8.5.6 578 | | | | \--- org.apache.tomcat.embed:tomcat-embed-websocket:8.5.6 579 | | | | \--- org.apache.tomcat.embed:tomcat-embed-core:8.5.6 580 | | | +--- org.hibernate:hibernate-validator:5.2.4.Final 581 | | | | +--- javax.validation:validation-api:1.1.0.Final 582 | | | | +--- org.jboss.logging:jboss-logging:3.2.1.Final -> 3.3.0.Final 583 | | | | \--- com.fasterxml:classmate:1.1.0 -> 1.3.3 584 | | | +--- com.fasterxml.jackson.core:jackson-databind:2.8.4 585 | | | | +--- com.fasterxml.jackson.core:jackson-annotations:2.8.0 -> 2.8.4 586 | | | | \--- com.fasterxml.jackson.core:jackson-core:2.8.4 587 | | | +--- org.springframework:spring-web:4.3.4.RELEASE 588 | | | | +--- org.springframework:spring-aop:4.3.4.RELEASE (*) 589 | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 590 | | | | +--- org.springframework:spring-context:4.3.4.RELEASE (*) 591 | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 592 | | | \--- org.springframework:spring-webmvc:4.3.4.RELEASE 593 | | | +--- org.springframework:spring-aop:4.3.4.RELEASE (*) 594 | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 595 | | | +--- org.springframework:spring-context:4.3.4.RELEASE (*) 596 | | | +--- org.springframework:spring-core:4.3.4.RELEASE 597 | | | +--- org.springframework:spring-expression:4.3.4.RELEASE (*) 598 | | | \--- org.springframework:spring-web:4.3.4.RELEASE (*) 599 | | +--- org.thymeleaf:thymeleaf-spring4:2.1.5.RELEASE 600 | | | +--- org.thymeleaf:thymeleaf:2.1.5.RELEASE 601 | | | | +--- ognl:ognl:3.0.8 602 | | | | +--- org.javassist:javassist:3.16.1-GA -> 3.20.0-GA 603 | | | | +--- org.unbescape:unbescape:1.1.0.RELEASE 604 | | | | \--- org.slf4j:slf4j-api:1.6.6 -> 1.7.21 605 | | | \--- org.slf4j:slf4j-api:1.6.6 -> 1.7.21 606 | | \--- nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:1.4.0 607 | | +--- org.codehaus.groovy:groovy:2.4.3 -> 2.4.7 608 | | \--- org.thymeleaf:thymeleaf:2.1.4.RELEASE -> 2.1.5.RELEASE (*) 609 | +--- org.springframework.boot:spring-boot-devtools:1.4.2.RELEASE 610 | | +--- org.springframework.boot:spring-boot:1.4.2.RELEASE (*) 611 | | \--- org.springframework.boot:spring-boot-autoconfigure:1.4.2.RELEASE (*) 612 | +--- commons-io:commons-io:2.5 613 | \--- org.springframework.boot:spring-boot-starter-test:1.4.2.RELEASE 614 | +--- org.springframework.boot:spring-boot-test:1.4.2.RELEASE 615 | | \--- org.springframework.boot:spring-boot:1.4.2.RELEASE (*) 616 | +--- org.springframework.boot:spring-boot-test-autoconfigure:1.4.2.RELEASE 617 | | +--- org.springframework.boot:spring-boot-test:1.4.2.RELEASE (*) 618 | | \--- org.springframework.boot:spring-boot-autoconfigure:1.4.2.RELEASE (*) 619 | +--- com.jayway.jsonpath:json-path:2.2.0 620 | | +--- net.minidev:json-smart:2.2.1 621 | | | \--- net.minidev:accessors-smart:1.1 622 | | | \--- org.ow2.asm:asm:5.0.3 623 | | \--- org.slf4j:slf4j-api:1.7.16 -> 1.7.21 624 | +--- junit:junit:4.12 625 | | \--- org.hamcrest:hamcrest-core:1.3 626 | +--- org.assertj:assertj-core:2.5.0 627 | +--- org.mockito:mockito-core:1.10.19 628 | | +--- org.hamcrest:hamcrest-core:1.1 -> 1.3 629 | | \--- org.objenesis:objenesis:2.1 630 | +--- org.hamcrest:hamcrest-core:1.3 631 | +--- org.hamcrest:hamcrest-library:1.3 632 | | \--- org.hamcrest:hamcrest-core:1.3 633 | +--- org.skyscreamer:jsonassert:1.3.0 634 | | \--- org.json:json:20090211 -> 20140107 635 | +--- org.springframework:spring-core:4.3.4.RELEASE 636 | \--- org.springframework:spring-test:4.3.4.RELEASE 637 | \--- org.springframework:spring-core:4.3.4.RELEASE 638 | 639 | testRuntime - Runtime dependencies for source set 'test'. 640 | +--- org.springframework.boot:spring-boot-starter-thymeleaf:1.4.2.RELEASE 641 | | +--- org.springframework.boot:spring-boot-starter:1.4.2.RELEASE 642 | | | +--- org.springframework.boot:spring-boot:1.4.2.RELEASE 643 | | | | +--- org.springframework:spring-core:4.3.4.RELEASE 644 | | | | \--- org.springframework:spring-context:4.3.4.RELEASE 645 | | | | +--- org.springframework:spring-aop:4.3.4.RELEASE 646 | | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE 647 | | | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 648 | | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 649 | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 650 | | | | +--- org.springframework:spring-core:4.3.4.RELEASE 651 | | | | \--- org.springframework:spring-expression:4.3.4.RELEASE 652 | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 653 | | | +--- org.springframework.boot:spring-boot-autoconfigure:1.4.2.RELEASE 654 | | | | \--- org.springframework.boot:spring-boot:1.4.2.RELEASE (*) 655 | | | +--- org.springframework.boot:spring-boot-starter-logging:1.4.2.RELEASE 656 | | | | +--- ch.qos.logback:logback-classic:1.1.7 657 | | | | | +--- ch.qos.logback:logback-core:1.1.7 658 | | | | | \--- org.slf4j:slf4j-api:1.7.20 -> 1.7.21 659 | | | | +--- org.slf4j:jcl-over-slf4j:1.7.21 660 | | | | | \--- org.slf4j:slf4j-api:1.7.21 661 | | | | +--- org.slf4j:jul-to-slf4j:1.7.21 662 | | | | | \--- org.slf4j:slf4j-api:1.7.21 663 | | | | \--- org.slf4j:log4j-over-slf4j:1.7.21 664 | | | | \--- org.slf4j:slf4j-api:1.7.21 665 | | | +--- org.springframework:spring-core:4.3.4.RELEASE 666 | | | \--- org.yaml:snakeyaml:1.17 667 | | +--- org.springframework.boot:spring-boot-starter-web:1.4.2.RELEASE 668 | | | +--- org.springframework.boot:spring-boot-starter:1.4.2.RELEASE (*) 669 | | | +--- org.springframework.boot:spring-boot-starter-tomcat:1.4.2.RELEASE 670 | | | | +--- org.apache.tomcat.embed:tomcat-embed-core:8.5.6 671 | | | | +--- org.apache.tomcat.embed:tomcat-embed-el:8.5.6 672 | | | | \--- org.apache.tomcat.embed:tomcat-embed-websocket:8.5.6 673 | | | | \--- org.apache.tomcat.embed:tomcat-embed-core:8.5.6 674 | | | +--- org.hibernate:hibernate-validator:5.2.4.Final 675 | | | | +--- javax.validation:validation-api:1.1.0.Final 676 | | | | +--- org.jboss.logging:jboss-logging:3.2.1.Final -> 3.3.0.Final 677 | | | | \--- com.fasterxml:classmate:1.1.0 -> 1.3.3 678 | | | +--- com.fasterxml.jackson.core:jackson-databind:2.8.4 679 | | | | +--- com.fasterxml.jackson.core:jackson-annotations:2.8.0 -> 2.8.4 680 | | | | \--- com.fasterxml.jackson.core:jackson-core:2.8.4 681 | | | +--- org.springframework:spring-web:4.3.4.RELEASE 682 | | | | +--- org.springframework:spring-aop:4.3.4.RELEASE (*) 683 | | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 684 | | | | +--- org.springframework:spring-context:4.3.4.RELEASE (*) 685 | | | | \--- org.springframework:spring-core:4.3.4.RELEASE 686 | | | \--- org.springframework:spring-webmvc:4.3.4.RELEASE 687 | | | +--- org.springframework:spring-aop:4.3.4.RELEASE (*) 688 | | | +--- org.springframework:spring-beans:4.3.4.RELEASE (*) 689 | | | +--- org.springframework:spring-context:4.3.4.RELEASE (*) 690 | | | +--- org.springframework:spring-core:4.3.4.RELEASE 691 | | | +--- org.springframework:spring-expression:4.3.4.RELEASE (*) 692 | | | \--- org.springframework:spring-web:4.3.4.RELEASE (*) 693 | | +--- org.thymeleaf:thymeleaf-spring4:2.1.5.RELEASE 694 | | | +--- org.thymeleaf:thymeleaf:2.1.5.RELEASE 695 | | | | +--- ognl:ognl:3.0.8 696 | | | | +--- org.javassist:javassist:3.16.1-GA -> 3.20.0-GA 697 | | | | +--- org.unbescape:unbescape:1.1.0.RELEASE 698 | | | | \--- org.slf4j:slf4j-api:1.6.6 -> 1.7.21 699 | | | \--- org.slf4j:slf4j-api:1.6.6 -> 1.7.21 700 | | \--- nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:1.4.0 701 | | +--- org.codehaus.groovy:groovy:2.4.3 -> 2.4.7 702 | | \--- org.thymeleaf:thymeleaf:2.1.4.RELEASE -> 2.1.5.RELEASE (*) 703 | +--- org.springframework.boot:spring-boot-devtools:1.4.2.RELEASE 704 | | +--- org.springframework.boot:spring-boot:1.4.2.RELEASE (*) 705 | | \--- org.springframework.boot:spring-boot-autoconfigure:1.4.2.RELEASE (*) 706 | +--- commons-io:commons-io:2.5 707 | \--- org.springframework.boot:spring-boot-starter-test:1.4.2.RELEASE 708 | +--- org.springframework.boot:spring-boot-test:1.4.2.RELEASE 709 | | \--- org.springframework.boot:spring-boot:1.4.2.RELEASE (*) 710 | +--- org.springframework.boot:spring-boot-test-autoconfigure:1.4.2.RELEASE 711 | | +--- org.springframework.boot:spring-boot-test:1.4.2.RELEASE (*) 712 | | \--- org.springframework.boot:spring-boot-autoconfigure:1.4.2.RELEASE (*) 713 | +--- com.jayway.jsonpath:json-path:2.2.0 714 | | +--- net.minidev:json-smart:2.2.1 715 | | | \--- net.minidev:accessors-smart:1.1 716 | | | \--- org.ow2.asm:asm:5.0.3 717 | | \--- org.slf4j:slf4j-api:1.7.16 -> 1.7.21 718 | +--- junit:junit:4.12 719 | | \--- org.hamcrest:hamcrest-core:1.3 720 | +--- org.assertj:assertj-core:2.5.0 721 | +--- org.mockito:mockito-core:1.10.19 722 | | +--- org.hamcrest:hamcrest-core:1.1 -> 1.3 723 | | \--- org.objenesis:objenesis:2.1 724 | +--- org.hamcrest:hamcrest-core:1.3 725 | +--- org.hamcrest:hamcrest-library:1.3 726 | | \--- org.hamcrest:hamcrest-core:1.3 727 | +--- org.skyscreamer:jsonassert:1.3.0 728 | | \--- org.json:json:20090211 -> 20140107 729 | +--- org.springframework:spring-core:4.3.4.RELEASE 730 | \--- org.springframework:spring-test:4.3.4.RELEASE 731 | \--- org.springframework:spring-core:4.3.4.RELEASE 732 | 733 | (*) - dependencies omitted (listed previously) 734 | 735 | BUILD SUCCESSFUL 736 | 737 | Total time: 14.286 secs 738 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # old school'ish.. 2 | org.gradle.console=plain -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avast/gradle-dependencies-viewer/1dedefefa0509b0ebcaa5db816ed76726f6194af/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 84 | 85 | APP_NAME="Gradle" 86 | APP_BASE_NAME=${0##*/} 87 | 88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | 142 | # Increase the maximum file descriptors if we can. 143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 144 | case $MAX_FD in #( 145 | max*) 146 | MAX_FD=$( ulimit -H -n ) || 147 | warn "Could not query maximum file descriptor limit" 148 | esac 149 | case $MAX_FD in #( 150 | '' | soft) :;; #( 151 | *) 152 | ulimit -n "$MAX_FD" || 153 | warn "Could not set maximum file descriptor limit to $MAX_FD" 154 | esac 155 | fi 156 | 157 | # Collect all arguments for the java command, stacking in reverse order: 158 | # * args from the command line 159 | # * the main class name 160 | # * -classpath 161 | # * -D...appname settings 162 | # * --module-path (only if needed) 163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 164 | 165 | # For Cygwin or MSYS, switch paths to Windows format before running java 166 | if "$cygwin" || "$msys" ; then 167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 169 | 170 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 171 | 172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 173 | for arg do 174 | if 175 | case $arg in #( 176 | -*) false ;; # don't mess with options #( 177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 178 | [ -e "$t" ] ;; #( 179 | *) false ;; 180 | esac 181 | then 182 | arg=$( cygpath --path --ignore --mixed "$arg" ) 183 | fi 184 | # Roll the args list around exactly as many times as the number of 185 | # args, so each arg winds up back in the position where it started, but 186 | # possibly modified. 187 | # 188 | # NB: a `for` loop captures its iteration list before it begins, so 189 | # changing the positional parameters here affects neither the number of 190 | # iterations, nor the values presented in `arg`. 191 | shift # remove old arg 192 | set -- "$@" "$arg" # push replacement arg 193 | done 194 | fi 195 | 196 | # Collect all arguments for the java command; 197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 198 | # shell script including quotes and variable substitutions, so put them in 199 | # double quotes to make sure that they get re-expanded; and 200 | # * put everything else in single quotes, so that it's not re-expanded. 201 | 202 | set -- \ 203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 204 | -classpath "$CLASSPATH" \ 205 | org.gradle.wrapper.GradleWrapperMain \ 206 | "$@" 207 | 208 | # Use "xargs" to parse quoted args. 209 | # 210 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 211 | # 212 | # In Bash we could simply go: 213 | # 214 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 215 | # set -- "${ARGS[@]}" "$@" 216 | # 217 | # but POSIX shell has neither arrays nor command substitution, so instead we 218 | # post-process each arg (as a line of input to sed) to backslash-escape any 219 | # character that might be a shell metacharacter, then use eval to reverse 220 | # that process (while maintaining the separation between arguments), and wrap 221 | # the whole thing up as a single "set" statement. 222 | # 223 | # This will of course break if any of these variables contains a newline or 224 | # an unmatched quote. 225 | # 226 | 227 | eval "set -- $( 228 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 229 | xargs -n1 | 230 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 231 | tr '\n' ' ' 232 | )" '"$@"' 233 | 234 | exec "$JAVACMD" "$@" 235 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /src/main/java/com/avast/server/libver/Application.java: -------------------------------------------------------------------------------- 1 | package com.avast.server.libver; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.ComponentScan; 7 | import org.springframework.http.MediaType; 8 | import org.springframework.http.converter.HttpMessageConverter; 9 | import org.springframework.web.client.RestTemplate; 10 | 11 | import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; 12 | 13 | import java.util.Collections; 14 | 15 | @SpringBootApplication 16 | @ComponentScan("com.avast.server.libver.service") 17 | public class Application { 18 | 19 | @Bean 20 | public RestTemplate restTemplate() { 21 | final RestTemplate restTemplate = new RestTemplate(); 22 | restTemplate.getMessageConverters().add(jacksonSupportsText()); 23 | return restTemplate; 24 | } 25 | 26 | 27 | private HttpMessageConverter jacksonSupportsText() {//Gitlab returns JSON as plain text 28 | MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); 29 | converter.setSupportedMediaTypes(Collections.singletonList(MediaType.parseMediaType("text/plain;charset=utf-8"))); 30 | return converter; 31 | } 32 | 33 | public static void main(String[] args) { 34 | System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "10"); 35 | SpringApplication.run(Application.class, args); 36 | } 37 | 38 | public static String getImplementationVersion() { 39 | return Application.class.getPackage().getImplementationVersion(); 40 | } 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/avast/server/libver/model/gradle/DataRequest.java: -------------------------------------------------------------------------------- 1 | package com.avast.server.libver.model.gradle; 2 | 3 | /** 4 | * @author Vitasek L. 5 | */ 6 | public class DataRequest { 7 | private String data; 8 | 9 | public String getData() { 10 | return data; 11 | } 12 | 13 | public void setData(String data) { 14 | this.data = data; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/avast/server/libver/model/gradle/GradleDepsDescriptor.java: -------------------------------------------------------------------------------- 1 | package com.avast.server.libver.model.gradle; 2 | 3 | import java.util.LinkedHashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * @author Vitasek L. 8 | */ 9 | public class GradleDepsDescriptor { 10 | Map projects = new LinkedHashMap<>(); 11 | 12 | public Map getProjects() { 13 | return projects; 14 | } 15 | 16 | public void setProjects(Map projects) { 17 | this.projects = projects; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/avast/server/libver/model/gradle/Node.java: -------------------------------------------------------------------------------- 1 | package com.avast.server.libver.model.gradle; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | /** 9 | * @author Vitasek L. 10 | */ 11 | public class Node { 12 | public String text; 13 | 14 | @JsonIgnore 15 | public int level; 16 | private List children; 17 | 18 | 19 | public Node() { 20 | } 21 | 22 | public String getText() { 23 | return text; 24 | } 25 | 26 | public void setText(String text) { 27 | this.text = text; 28 | } 29 | 30 | public int getLevel() { 31 | return level; 32 | } 33 | 34 | public void setLevel(int level) { 35 | this.level = level; 36 | } 37 | 38 | public List getChildren() { 39 | return children; 40 | } 41 | 42 | public void setChildren(List children) { 43 | this.children = children; 44 | } 45 | 46 | public Node(String text, int level) { 47 | this.text = text; 48 | this.level = level; 49 | } 50 | 51 | public void addChild(Node childNode) { 52 | if (children == null) { 53 | children = new ArrayList<>(); 54 | } 55 | children.add(childNode); 56 | } 57 | 58 | @Override 59 | public String toString() { 60 | return "{" + 61 | text + '\'' + 62 | ", level=" + level + 63 | '}'; 64 | } 65 | } -------------------------------------------------------------------------------- /src/main/java/com/avast/server/libver/model/gradle/Subproject.java: -------------------------------------------------------------------------------- 1 | package com.avast.server.libver.model.gradle; 2 | 3 | import java.util.LinkedHashMap; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | /** 8 | * @author Vitasek L. 9 | */ 10 | public class Subproject { 11 | private Map> sourceSet = new LinkedHashMap<>(); 12 | 13 | public Map> getSourceSet() { 14 | return sourceSet; 15 | } 16 | 17 | public void setSourceSet(Map> sourceSet) { 18 | this.sourceSet = sourceSet; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/avast/server/libver/service/GradleController.java: -------------------------------------------------------------------------------- 1 | package com.avast.server.libver.service; 2 | 3 | import com.avast.server.libver.model.gradle.DataRequest; 4 | import com.avast.server.libver.model.gradle.GradleDepsDescriptor; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.core.env.Environment; 7 | import org.springframework.stereotype.Controller; 8 | import org.springframework.ui.Model; 9 | import org.springframework.web.bind.annotation.*; 10 | 11 | import java.text.ParseException; 12 | 13 | @Controller 14 | public class GradleController { 15 | 16 | @Autowired 17 | Environment env; 18 | 19 | @Autowired 20 | GradleService gradleService; 21 | 22 | @RequestMapping(value = "/gradle/parse", method = RequestMethod.POST) 23 | @ResponseBody 24 | public GradleDepsDescriptor parseGradle(@RequestBody DataRequest dataRequest) { 25 | if (dataRequest == null || dataRequest.getData() == null) { 26 | throw new ParseInvalidException("No data to parse"); 27 | } 28 | try { 29 | final GradleDepsDescriptor parse = gradleService.parse(dataRequest.getData()); 30 | if (parse.getProjects().isEmpty()) { 31 | throw new ParseInvalidException("Empty project list"); 32 | } 33 | return parse; 34 | } catch (ParseException e) { 35 | throw new ParseInvalidException(e.getMessage()); 36 | } 37 | } 38 | 39 | @RequestMapping("/") 40 | public String gradleDeps(Model model) { 41 | return "gradle"; 42 | } 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/avast/server/libver/service/GradleService.java: -------------------------------------------------------------------------------- 1 | package com.avast.server.libver.service; 2 | 3 | import com.avast.server.libver.model.gradle.GradleDepsDescriptor; 4 | 5 | import java.text.ParseException; 6 | 7 | /** 8 | * @author Vitasek L. 9 | */ 10 | public interface GradleService { 11 | 12 | GradleDepsDescriptor parse(String data) throws ParseException; 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/avast/server/libver/service/ParseInvalidException.java: -------------------------------------------------------------------------------- 1 | package com.avast.server.libver.service; 2 | 3 | import org.springframework.http.HttpStatus; 4 | import org.springframework.web.bind.annotation.ResponseStatus; 5 | 6 | /** 7 | * @author Vitasek L. 8 | */ 9 | @ResponseStatus(value = HttpStatus.BAD_REQUEST) 10 | public class ParseInvalidException extends RuntimeException { 11 | 12 | public ParseInvalidException() { 13 | } 14 | 15 | public ParseInvalidException(String message) { 16 | super(message); 17 | } 18 | 19 | public ParseInvalidException(String message, Throwable cause) { 20 | super(message, cause); 21 | } 22 | 23 | public ParseInvalidException(Throwable cause) { 24 | super(cause); 25 | } 26 | 27 | public ParseInvalidException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 28 | super(message, cause, enableSuppression, writableStackTrace); 29 | } 30 | } -------------------------------------------------------------------------------- /src/main/java/com/avast/server/libver/service/impl/GradleParser.java: -------------------------------------------------------------------------------- 1 | package com.avast.server.libver.service.impl; 2 | 3 | import com.avast.server.libver.model.gradle.GradleDepsDescriptor; 4 | import com.avast.server.libver.model.gradle.Node; 5 | import com.avast.server.libver.model.gradle.Subproject; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.util.StringUtils; 9 | 10 | import java.text.ParseException; 11 | import java.util.Scanner; 12 | import java.util.regex.Matcher; 13 | import java.util.regex.Pattern; 14 | 15 | /** 16 | * @author Vitasek L. 17 | */ 18 | public class GradleParser { 19 | private final static Logger logger = LoggerFactory.getLogger(GradleParser.class); 20 | 21 | private final static Pattern TREE_LINE = Pattern.compile("\\\\|\\+---"); 22 | private String data; 23 | 24 | private final static String PROJECT_TITLE = "------------------------------------------------------------\\n(.*?)\\n------------------------------------------------------------"; 25 | private final static Pattern PROJECT_PATTERN = Pattern.compile(PROJECT_TITLE); 26 | 27 | 28 | public GradleParser(String data) { 29 | this.data = data.replace("\r\n", "\n") + "\n\n"; 30 | } 31 | 32 | public GradleDepsDescriptor parse() throws ParseException { 33 | int projectIndex = 0; 34 | final GradleDepsDescriptor gradleDepsDescriptor = new GradleDepsDescriptor(); 35 | final Matcher projectMatcher = PROJECT_PATTERN.matcher(data); 36 | while (projectMatcher.find(projectIndex)) { 37 | projectIndex = projectMatcher.start(); 38 | String projectName = projectMatcher.group(1); 39 | if (projectName.startsWith("Project :")) { 40 | projectName = projectName.substring(9); 41 | } 42 | final Subproject subproject = new Subproject(); 43 | gradleDepsDescriptor.getProjects().put(projectName, subproject); 44 | final Matcher projectMatcher2 = PROJECT_PATTERN.matcher(data); 45 | final boolean foundAnotherProject = projectMatcher2.find(projectMatcher.end()); 46 | final String projectDepsData; 47 | if (foundAnotherProject) { 48 | projectDepsData = data.substring(projectIndex, projectMatcher2.start()); 49 | } else { 50 | projectDepsData = data.substring(projectIndex); 51 | } 52 | fillSourceSets(subproject, projectDepsData); 53 | projectIndex = projectMatcher.end(); 54 | } 55 | return gradleDepsDescriptor; 56 | } 57 | 58 | private void fillSourceSets(Subproject subproject, String projectDepsData) throws ParseException { 59 | final Matcher matcher = TREE_LINE.matcher(projectDepsData); 60 | int sourceIndex = 0; 61 | while (matcher.find(sourceIndex)) { 62 | final int treeLineStart = matcher.start(); 63 | final int titleIndex = projectDepsData.lastIndexOf("\n\n", treeLineStart); 64 | if (titleIndex == -1) { 65 | throw new ParseException("Cannot find source set description", sourceIndex); 66 | } 67 | String sourceSet = projectDepsData.substring(titleIndex + 2, projectDepsData.indexOf('\n', titleIndex + 3)); 68 | if (sourceSet.contains(" - ")) { 69 | sourceSet = sourceSet.substring(0, sourceSet.lastIndexOf(" - ")); 70 | } 71 | 72 | final Node root = new Node("root", -1); 73 | 74 | try (SourceSetParser sourceSetParser = new SourceSetParser(projectDepsData.substring(treeLineStart))) { 75 | sourceSetParser.walkTree(root); 76 | } catch (Exception e) { 77 | logger.error("Failed to parse source set", e); 78 | throw new ParseException("Cannot parse source set: " + e.getMessage(), 0); 79 | } 80 | if (root.getChildren() != null) { 81 | subproject.getSourceSet().put(sourceSet, root.getChildren()); 82 | } 83 | sourceIndex = projectDepsData.indexOf("\n\n", treeLineStart); 84 | } 85 | 86 | } 87 | 88 | private class SourceSetParser implements AutoCloseable{ 89 | private Scanner scanner; 90 | 91 | SourceSetParser(String data) { 92 | this.scanner = new Scanner(data); 93 | } 94 | 95 | String walkTree(Node currentNode, String currentLine) { 96 | Node lastNode = currentNode; 97 | while (currentLine != null) { 98 | final int foundPlus = currentLine.indexOf("---");//well, not 100% optimized when going back in tree 99 | int lineLevel = 0; 100 | if (foundPlus >= 0) { 101 | lineLevel = (foundPlus - 1) / 5; 102 | } else assert false; 103 | if (currentNode.level + 1 > lineLevel) { 104 | return currentLine; 105 | } 106 | final Node newNode = new Node(currentLine.substring(foundPlus + 4).trim(), lineLevel); 107 | if (currentNode.level + 1 == lineLevel) { //on same level 108 | currentNode.addChild(newNode); 109 | lastNode = newNode; 110 | currentLine = getLine(); 111 | } else { 112 | if (currentNode.level + 1 < lineLevel) { // on next level 113 | lastNode.addChild(newNode); 114 | currentLine = walkTree(newNode, getLine()); 115 | } 116 | } 117 | } 118 | return null; 119 | } 120 | 121 | private String getLine() { 122 | if (scanner.hasNextLine()) { 123 | final String line = scanner.nextLine(); 124 | if (StringUtils.isEmpty(line.trim())) { 125 | return null; 126 | } 127 | return line; 128 | } 129 | return null; 130 | } 131 | 132 | @Override 133 | public void close() throws Exception { 134 | if (scanner != null) { 135 | scanner.close(); 136 | } 137 | } 138 | 139 | void walkTree(Node root) { 140 | walkTree(root, getLine()); 141 | } 142 | } 143 | 144 | 145 | } 146 | -------------------------------------------------------------------------------- /src/main/java/com/avast/server/libver/service/impl/GradleServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.avast.server.libver.service.impl; 2 | 3 | import com.avast.server.libver.model.gradle.GradleDepsDescriptor; 4 | import com.avast.server.libver.service.GradleService; 5 | import org.springframework.stereotype.Service; 6 | 7 | import java.text.ParseException; 8 | 9 | /** 10 | * @author Vitasek L. 11 | */ 12 | @Service 13 | public class GradleServiceImpl implements GradleService { 14 | 15 | 16 | @Override 17 | public GradleDepsDescriptor parse(String data) throws ParseException { 18 | return new GradleParser(data).parse(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.resources.cache.period=0 2 | spring.thymeleaf.cache=false 3 | 4 | server.port=8090 5 | server.context-path=/ 6 | spring.mvc.static-path-pattern=/static/** -------------------------------------------------------------------------------- /src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | _______ _ _ _ 2 | (_______) | | | | | 3 | _ ___ ____ _____ __| | | _____ __| |_____ ____ ___ 4 | | | (_ |/ ___|____ |/ _ | || ___ | / _ | ___ | _ \ /___) 5 | | |___) | | / ___ ( (_| | || ____| ( (_| | ____| |_| |___ | 6 | \_____/|_| \_____|\____|\_)_____) \____|_____) __/|___/ 7 | |_| -------------------------------------------------------------------------------- /src/main/resources/static/appfavicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avast/gradle-dependencies-viewer/1dedefefa0509b0ebcaa5db816ed76726f6194af/src/main/resources/static/appfavicon.ico -------------------------------------------------------------------------------- /src/main/resources/static/clipboard/clipboard.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * clipboard.js v1.5.15 3 | * https://zenorocha.github.io/clipboard.js 4 | * 5 | * Licensed MIT © Zeno Rocha 6 | */ 7 | (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Clipboard = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0 && arguments[0] !== undefined ? arguments[0] : {}; 409 | 410 | this.action = options.action; 411 | this.emitter = options.emitter; 412 | this.target = options.target; 413 | this.text = options.text; 414 | this.trigger = options.trigger; 415 | 416 | this.selectedText = ''; 417 | } 418 | }, { 419 | key: 'initSelection', 420 | value: function initSelection() { 421 | if (this.text) { 422 | this.selectFake(); 423 | } else if (this.target) { 424 | this.selectTarget(); 425 | } 426 | } 427 | }, { 428 | key: 'selectFake', 429 | value: function selectFake() { 430 | var _this = this; 431 | 432 | var isRTL = document.documentElement.getAttribute('dir') == 'rtl'; 433 | 434 | this.removeFake(); 435 | 436 | this.fakeHandlerCallback = function () { 437 | return _this.removeFake(); 438 | }; 439 | this.fakeHandler = document.body.addEventListener('click', this.fakeHandlerCallback) || true; 440 | 441 | this.fakeElem = document.createElement('textarea'); 442 | // Prevent zooming on iOS 443 | this.fakeElem.style.fontSize = '12pt'; 444 | // Reset box model 445 | this.fakeElem.style.border = '0'; 446 | this.fakeElem.style.padding = '0'; 447 | this.fakeElem.style.margin = '0'; 448 | // Move element out of screen horizontally 449 | this.fakeElem.style.position = 'absolute'; 450 | this.fakeElem.style[isRTL ? 'right' : 'left'] = '-9999px'; 451 | // Move element to the same position vertically 452 | var yPosition = window.pageYOffset || document.documentElement.scrollTop; 453 | this.fakeElem.addEventListener('focus', window.scrollTo(0, yPosition)); 454 | this.fakeElem.style.top = yPosition + 'px'; 455 | 456 | this.fakeElem.setAttribute('readonly', ''); 457 | this.fakeElem.value = this.text; 458 | 459 | document.body.appendChild(this.fakeElem); 460 | 461 | this.selectedText = (0, _select2.default)(this.fakeElem); 462 | this.copyText(); 463 | } 464 | }, { 465 | key: 'removeFake', 466 | value: function removeFake() { 467 | if (this.fakeHandler) { 468 | document.body.removeEventListener('click', this.fakeHandlerCallback); 469 | this.fakeHandler = null; 470 | this.fakeHandlerCallback = null; 471 | } 472 | 473 | if (this.fakeElem) { 474 | document.body.removeChild(this.fakeElem); 475 | this.fakeElem = null; 476 | } 477 | } 478 | }, { 479 | key: 'selectTarget', 480 | value: function selectTarget() { 481 | this.selectedText = (0, _select2.default)(this.target); 482 | this.copyText(); 483 | } 484 | }, { 485 | key: 'copyText', 486 | value: function copyText() { 487 | var succeeded = void 0; 488 | 489 | try { 490 | succeeded = document.execCommand(this.action); 491 | } catch (err) { 492 | succeeded = false; 493 | } 494 | 495 | this.handleResult(succeeded); 496 | } 497 | }, { 498 | key: 'handleResult', 499 | value: function handleResult(succeeded) { 500 | this.emitter.emit(succeeded ? 'success' : 'error', { 501 | action: this.action, 502 | text: this.selectedText, 503 | trigger: this.trigger, 504 | clearSelection: this.clearSelection.bind(this) 505 | }); 506 | } 507 | }, { 508 | key: 'clearSelection', 509 | value: function clearSelection() { 510 | if (this.target) { 511 | this.target.blur(); 512 | } 513 | 514 | window.getSelection().removeAllRanges(); 515 | } 516 | }, { 517 | key: 'destroy', 518 | value: function destroy() { 519 | this.removeFake(); 520 | } 521 | }, { 522 | key: 'action', 523 | set: function set() { 524 | var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'copy'; 525 | 526 | this._action = action; 527 | 528 | if (this._action !== 'copy' && this._action !== 'cut') { 529 | throw new Error('Invalid "action" value, use either "copy" or "cut"'); 530 | } 531 | }, 532 | get: function get() { 533 | return this._action; 534 | } 535 | }, { 536 | key: 'target', 537 | set: function set(target) { 538 | if (target !== undefined) { 539 | if (target && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && target.nodeType === 1) { 540 | if (this.action === 'copy' && target.hasAttribute('disabled')) { 541 | throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'); 542 | } 543 | 544 | if (this.action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) { 545 | throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes'); 546 | } 547 | 548 | this._target = target; 549 | } else { 550 | throw new Error('Invalid "target" value, use a valid Element'); 551 | } 552 | } 553 | }, 554 | get: function get() { 555 | return this._target; 556 | } 557 | }]); 558 | 559 | return ClipboardAction; 560 | }(); 561 | 562 | module.exports = ClipboardAction; 563 | }); 564 | 565 | },{"select":5}],8:[function(require,module,exports){ 566 | (function (global, factory) { 567 | if (typeof define === "function" && define.amd) { 568 | define(['module', './clipboard-action', 'tiny-emitter', 'good-listener'], factory); 569 | } else if (typeof exports !== "undefined") { 570 | factory(module, require('./clipboard-action'), require('tiny-emitter'), require('good-listener')); 571 | } else { 572 | var mod = { 573 | exports: {} 574 | }; 575 | factory(mod, global.clipboardAction, global.tinyEmitter, global.goodListener); 576 | global.clipboard = mod.exports; 577 | } 578 | })(this, function (module, _clipboardAction, _tinyEmitter, _goodListener) { 579 | 'use strict'; 580 | 581 | var _clipboardAction2 = _interopRequireDefault(_clipboardAction); 582 | 583 | var _tinyEmitter2 = _interopRequireDefault(_tinyEmitter); 584 | 585 | var _goodListener2 = _interopRequireDefault(_goodListener); 586 | 587 | function _interopRequireDefault(obj) { 588 | return obj && obj.__esModule ? obj : { 589 | default: obj 590 | }; 591 | } 592 | 593 | function _classCallCheck(instance, Constructor) { 594 | if (!(instance instanceof Constructor)) { 595 | throw new TypeError("Cannot call a class as a function"); 596 | } 597 | } 598 | 599 | var _createClass = function () { 600 | function defineProperties(target, props) { 601 | for (var i = 0; i < props.length; i++) { 602 | var descriptor = props[i]; 603 | descriptor.enumerable = descriptor.enumerable || false; 604 | descriptor.configurable = true; 605 | if ("value" in descriptor) descriptor.writable = true; 606 | Object.defineProperty(target, descriptor.key, descriptor); 607 | } 608 | } 609 | 610 | return function (Constructor, protoProps, staticProps) { 611 | if (protoProps) defineProperties(Constructor.prototype, protoProps); 612 | if (staticProps) defineProperties(Constructor, staticProps); 613 | return Constructor; 614 | }; 615 | }(); 616 | 617 | function _possibleConstructorReturn(self, call) { 618 | if (!self) { 619 | throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); 620 | } 621 | 622 | return call && (typeof call === "object" || typeof call === "function") ? call : self; 623 | } 624 | 625 | function _inherits(subClass, superClass) { 626 | if (typeof superClass !== "function" && superClass !== null) { 627 | throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); 628 | } 629 | 630 | subClass.prototype = Object.create(superClass && superClass.prototype, { 631 | constructor: { 632 | value: subClass, 633 | enumerable: false, 634 | writable: true, 635 | configurable: true 636 | } 637 | }); 638 | if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; 639 | } 640 | 641 | var Clipboard = function (_Emitter) { 642 | _inherits(Clipboard, _Emitter); 643 | 644 | /** 645 | * @param {String|HTMLElement|HTMLCollection|NodeList} trigger 646 | * @param {Object} options 647 | */ 648 | function Clipboard(trigger, options) { 649 | _classCallCheck(this, Clipboard); 650 | 651 | var _this = _possibleConstructorReturn(this, (Clipboard.__proto__ || Object.getPrototypeOf(Clipboard)).call(this)); 652 | 653 | _this.resolveOptions(options); 654 | _this.listenClick(trigger); 655 | return _this; 656 | } 657 | 658 | /** 659 | * Defines if attributes would be resolved using internal setter functions 660 | * or custom functions that were passed in the constructor. 661 | * @param {Object} options 662 | */ 663 | 664 | 665 | _createClass(Clipboard, [{ 666 | key: 'resolveOptions', 667 | value: function resolveOptions() { 668 | var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 669 | 670 | this.action = typeof options.action === 'function' ? options.action : this.defaultAction; 671 | this.target = typeof options.target === 'function' ? options.target : this.defaultTarget; 672 | this.text = typeof options.text === 'function' ? options.text : this.defaultText; 673 | } 674 | }, { 675 | key: 'listenClick', 676 | value: function listenClick(trigger) { 677 | var _this2 = this; 678 | 679 | this.listener = (0, _goodListener2.default)(trigger, 'click', function (e) { 680 | return _this2.onClick(e); 681 | }); 682 | } 683 | }, { 684 | key: 'onClick', 685 | value: function onClick(e) { 686 | var trigger = e.delegateTarget || e.currentTarget; 687 | 688 | if (this.clipboardAction) { 689 | this.clipboardAction = null; 690 | } 691 | 692 | this.clipboardAction = new _clipboardAction2.default({ 693 | action: this.action(trigger), 694 | target: this.target(trigger), 695 | text: this.text(trigger), 696 | trigger: trigger, 697 | emitter: this 698 | }); 699 | } 700 | }, { 701 | key: 'defaultAction', 702 | value: function defaultAction(trigger) { 703 | return getAttributeValue('action', trigger); 704 | } 705 | }, { 706 | key: 'defaultTarget', 707 | value: function defaultTarget(trigger) { 708 | var selector = getAttributeValue('target', trigger); 709 | 710 | if (selector) { 711 | return document.querySelector(selector); 712 | } 713 | } 714 | }, { 715 | key: 'defaultText', 716 | value: function defaultText(trigger) { 717 | return getAttributeValue('text', trigger); 718 | } 719 | }, { 720 | key: 'destroy', 721 | value: function destroy() { 722 | this.listener.destroy(); 723 | 724 | if (this.clipboardAction) { 725 | this.clipboardAction.destroy(); 726 | this.clipboardAction = null; 727 | } 728 | } 729 | }]); 730 | 731 | return Clipboard; 732 | }(_tinyEmitter2.default); 733 | 734 | /** 735 | * Helper function to retrieve attribute value. 736 | * @param {String} suffix 737 | * @param {Element} element 738 | */ 739 | function getAttributeValue(suffix, element) { 740 | var attribute = 'data-clipboard-' + suffix; 741 | 742 | if (!element.hasAttribute(attribute)) { 743 | return; 744 | } 745 | 746 | return element.getAttribute(attribute); 747 | } 748 | 749 | module.exports = Clipboard; 750 | }); 751 | 752 | },{"./clipboard-action":7,"good-listener":4,"tiny-emitter":6}]},{},[8])(8) 753 | }); -------------------------------------------------------------------------------- /src/main/resources/static/clipboard/clipboard.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * clipboard.js v1.5.15 3 | * https://zenorocha.github.io/clipboard.js 4 | * 5 | * Licensed MIT © Zeno Rocha 6 | */ 7 | !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.Clipboard=e()}}(function(){var e,t,n;return function e(t,n,i){function o(a,c){if(!n[a]){if(!t[a]){var l="function"==typeof require&&require;if(!c&&l)return l(a,!0);if(r)return r(a,!0);var s=new Error("Cannot find module '"+a+"'");throw s.code="MODULE_NOT_FOUND",s}var u=n[a]={exports:{}};t[a][0].call(u.exports,function(e){var n=t[a][1][e];return o(n?n:e)},u,u.exports,e,t,n,i)}return n[a].exports}for(var r="function"==typeof require&&require,a=0;a0&&void 0!==arguments[0]?arguments[0]:{};this.action=t.action,this.emitter=t.emitter,this.target=t.target,this.text=t.text,this.trigger=t.trigger,this.selectedText=""}},{key:"initSelection",value:function e(){this.text?this.selectFake():this.target&&this.selectTarget()}},{key:"selectFake",value:function e(){var t=this,n="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return t.removeFake()},this.fakeHandler=document.body.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[n?"right":"left"]="-9999px";var i=window.pageYOffset||document.documentElement.scrollTop;this.fakeElem.addEventListener("focus",window.scrollTo(0,i)),this.fakeElem.style.top=i+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,document.body.appendChild(this.fakeElem),this.selectedText=(0,o.default)(this.fakeElem),this.copyText()}},{key:"removeFake",value:function e(){this.fakeHandler&&(document.body.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(document.body.removeChild(this.fakeElem),this.fakeElem=null)}},{key:"selectTarget",value:function e(){this.selectedText=(0,o.default)(this.target),this.copyText()}},{key:"copyText",value:function e(){var t=void 0;try{t=document.execCommand(this.action)}catch(e){t=!1}this.handleResult(t)}},{key:"handleResult",value:function e(t){this.emitter.emit(t?"success":"error",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})}},{key:"clearSelection",value:function e(){this.target&&this.target.blur(),window.getSelection().removeAllRanges()}},{key:"destroy",value:function e(){this.removeFake()}},{key:"action",set:function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"copy";if(this._action=t,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function e(){return this._action}},{key:"target",set:function e(t){if(void 0!==t){if(!t||"object"!==("undefined"==typeof t?"undefined":r(t))||1!==t.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&t.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(t.hasAttribute("readonly")||t.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=t}},get:function e(){return this._target}}]),e}();e.exports=c})},{select:5}],8:[function(t,n,i){!function(o,r){if("function"==typeof e&&e.amd)e(["module","./clipboard-action","tiny-emitter","good-listener"],r);else if("undefined"!=typeof i)r(n,t("./clipboard-action"),t("tiny-emitter"),t("good-listener"));else{var a={exports:{}};r(a,o.clipboardAction,o.tinyEmitter,o.goodListener),o.clipboard=a.exports}}(this,function(e,t,n,i){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function c(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function l(e,t){var n="data-clipboard-"+e;if(t.hasAttribute(n))return t.getAttribute(n)}var s=o(t),u=o(n),f=o(i),d=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof t.action?t.action:this.defaultAction,this.target="function"==typeof t.target?t.target:this.defaultTarget,this.text="function"==typeof t.text?t.text:this.defaultText}},{key:"listenClick",value:function e(t){var n=this;this.listener=(0,f.default)(t,"click",function(e){return n.onClick(e)})}},{key:"onClick",value:function e(t){var n=t.delegateTarget||t.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new s.default({action:this.action(n),target:this.target(n),text:this.text(n),trigger:n,emitter:this})}},{key:"defaultAction",value:function e(t){return l("action",t)}},{key:"defaultTarget",value:function e(t){var n=l("target",t);if(n)return document.querySelector(n)}},{key:"defaultText",value:function e(t){return l("text",t)}},{key:"destroy",value:function e(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}]),t}(u.default);e.exports=h})},{"./clipboard-action":7,"good-listener":4,"tiny-emitter":6}]},{},[8])(8)}); -------------------------------------------------------------------------------- /src/main/resources/static/clipboard/tooltips.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | var btns = document.querySelectorAll('.btn'); 3 | for (var i = 0; i < btns.length; i++) { 4 | btns[i].addEventListener('mouseleave', function (e) { 5 | e.currentTarget.setAttribute('class', 'btn btn-default'); 6 | e.currentTarget.removeAttribute('aria-label'); 7 | }); 8 | } 9 | }); 10 | 11 | function showTooltip(elem, msg) { 12 | elem.setAttribute('class', 'btn btn-default tooltipped tooltipped-s'); 13 | elem.setAttribute('aria-label', msg); 14 | } 15 | function fallbackMessage(action) { 16 | var actionMsg = ''; 17 | var actionKey = (action === 'cut' ? 'X' : 'C'); 18 | if (/iPhone|iPad/i.test(navigator.userAgent)) { 19 | actionMsg = 'No support :('; 20 | } 21 | else if (/Mac/i.test(navigator.userAgent)) { 22 | actionMsg = 'Press ⌘-' + actionKey + ' to ' + action; 23 | } 24 | else { 25 | actionMsg = 'Press Ctrl-' + actionKey + ' to ' + action; 26 | } 27 | return actionMsg; 28 | } -------------------------------------------------------------------------------- /src/main/resources/static/css/custom.css: -------------------------------------------------------------------------------- 1 | textarea { 2 | font-family: monospace; 3 | width: 60%; 4 | min-height: 400px; 5 | background-color: #fafafa; 6 | margin: 10px; 7 | padding: 20px; 8 | border: 1px lightgray; 9 | overflow: auto; 10 | outline: none; 11 | 12 | -webkit-box-shadow: none; 13 | -moz-box-shadow: none; 14 | box-shadow: none; 15 | } 16 | .btn { 17 | margin-left: 20px; 18 | } 19 | 20 | .tab-gradle{ 21 | background:url("../img/gradle.png") no-repeat center; 22 | background-size: 90%; 23 | min-width: 85px; 24 | min-height: 52px; 25 | } 26 | .tab-maven{ 27 | background:url("../img/maven.png") no-repeat center; 28 | background-size: 90%; 29 | min-width: 85px; 30 | min-height: 52px; 31 | } 32 | 33 | /*noinspection CssOverwrittenProperties*/ 34 | .custom-icon { 35 | position: relative; 36 | top: -1px; 37 | vertical-align: middle; 38 | display: inline-block; 39 | font-style: normal; 40 | font-weight: normal; 41 | line-height: 1; 42 | /*display: block; !* This is required *!*/ 43 | } 44 | 45 | .custom-icon.normal { 46 | width: 34px; 47 | height: 20px; 48 | } 49 | 50 | 51 | .custom-icon.icon-bulb { 52 | top: 0 !important; 53 | background: url("../img/glyphicons-65-lightbulb.png") transparent no-repeat center; 54 | background-size: cover; 55 | } 56 | 57 | .custom-icon.small { 58 | width: 22px; 59 | height: 20px; 60 | } 61 | 62 | .custom-icon.bigSquare { 63 | width: 30px; 64 | height: 30px; 65 | } 66 | 67 | .fixed-table-body thead th .th-inner, .table th { 68 | box-sizing: border-box; 69 | font-size: 15px; 70 | } 71 | 72 | .custom-icon.glyph { 73 | width: 20px; 74 | height: 26px; 75 | } 76 | 77 | 78 | 79 | .drop_zone { 80 | border: 2px dashed #bbb; 81 | border-radius: 5px; 82 | padding: 25px; 83 | background-color: #FCFCFC; 84 | } 85 | 86 | /* do not group these rules */ 87 | *::-webkit-input-placeholder { 88 | color: lightcoral; 89 | } 90 | *:-moz-placeholder { 91 | /* FF 4-18 */ 92 | color: lightcoral; 93 | } 94 | *::-moz-placeholder { 95 | /* FF 19+ */ 96 | color: lightcoral; 97 | } 98 | *:-ms-input-placeholder { 99 | /* IE 10+ */ 100 | color: lightcoral; 101 | } -------------------------------------------------------------------------------- /src/main/resources/static/css/primer.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}*{box-sizing:border-box}input,select,textarea,button{font:13px / 1.4 Helvetica,arial,nimbussansl,liberationsans,freesans,clean,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"}body{font:13px / 1.4 Helvetica,arial,nimbussansl,liberationsans,freesans,clean,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";color:#333;background-color:#fff}a{color:#4078c0;text-decoration:none}a:hover,a:active{text-decoration:underline}hr,.rule{height:0;margin:15px 0;overflow:hidden;background:transparent;border:0;border-bottom:1px solid #ddd}hr:before,.rule:before{display:table;content:""}hr:after,.rule:after{display:table;clear:both;content:""}h1,h2,h3,h4,h5,h6{margin-top:15px;margin-bottom:15px;line-height:1.1}h1{font-size:30px}h2{font-size:21px}h3{font-size:16px}h4{font-size:14px}h5{font-size:12px}h6{font-size:11px}small{font-size:90%}blockquote{margin:0}.lead{margin-bottom:30px;font-size:20px;font-weight:300;color:#555}.text-muted{color:#767676}.text-danger{color:#bd2c00}.text-emphasized{font-weight:bold;color:#333}.text-small{font-size:12px}ul,ol{padding:0;margin-top:0;margin-bottom:0}ol ol,ul ol{list-style-type:lower-roman}ul ul ol,ul ol ol,ol ul ol,ol ol ol{list-style-type:lower-alpha}dd{margin-left:0}tt,code{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:12px}pre{margin-top:0;margin-bottom:0;font:12px Consolas,"Liberation Mono",Menlo,Courier,monospace}.container{width:980px;margin-right:auto;margin-left:auto}.container:before{display:table;content:""}.container:after{display:table;clear:both;content:""}.columns{margin-right:-10px;margin-left:-10px}.columns:before{display:table;content:""}.columns:after{display:table;clear:both;content:""}.column{float:left;padding-right:10px;padding-left:10px}.one-third{width:33.333333%}.two-thirds{width:66.666667%}.one-fourth{width:25%}.one-half{width:50%}.three-fourths{width:75%}.one-fifth{width:20%}.four-fifths{width:80%}.single-column{padding-right:10px;padding-left:10px}.table-column{display:table-cell;width:1%;padding-right:10px;padding-left:10px;vertical-align:top}fieldset{padding:0;margin:0;border:0}label{font-size:13px;font-weight:bold}.form-control,input[type="text"],input[type="password"],input[type="email"],input[type="number"],input[type="tel"],input[type="url"],select,textarea{min-height:34px;padding:7px 8px;font-size:13px;color:#333;vertical-align:middle;background-color:#fff;background-repeat:no-repeat;background-position:right 8px center;border:1px solid #ccc;border-radius:3px;outline:none;box-shadow:inset 0 1px 2px rgba(0,0,0,0.075)}.form-control.focus,.form-control:focus,input[type="text"].focus,input[type="text"]:focus,input[type="password"].focus,input[type="password"]:focus,input[type="email"].focus,input[type="email"]:focus,input[type="number"].focus,input[type="number"]:focus,input[type="tel"].focus,input[type="tel"]:focus,input[type="url"].focus,input[type="url"]:focus,select.focus,select:focus,textarea.focus,textarea:focus{border-color:#51a7e8;box-shadow:inset 0 1px 2px rgba(0,0,0,0.075),0 0 5px rgba(81,167,232,0.5)}select:not([multiple]){height:34px;vertical-align:middle}input.input-contrast,.input-contrast{background-color:#fafafa}input.input-contrast:focus,.input-contrast:focus{background-color:#fff}::-webkit-input-placeholder{color:#aaa}::-moz-placeholder{color:#aaa}:-ms-input-placeholder{color:#aaa}::placeholder{color:#aaa}input.input-mini{min-height:26px;padding-top:4px;padding-bottom:4px;font-size:12px}input.input-large{padding:6px 10px;font-size:16px}.input-block{display:block;width:100%}.input-monospace{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace}dl.form{margin:15px 0}dl.form input[type="text"],dl.form input[type="password"],dl.form input[type="email"],dl.form input[type="url"],dl.form select,dl.form textarea{background-color:#fafafa}dl.form input[type="text"]:focus,dl.form input[type="password"]:focus,dl.form input[type="email"]:focus,dl.form input[type="url"]:focus,dl.form select:focus,dl.form textarea:focus{background-color:#fff}dl.form>dt{margin:0 0 6px}dl.form>dt label{position:relative}dl.form.flattened>dt{float:left;margin:0;line-height:32px}dl.form.flattened>dd{line-height:32px}dl.form>dd input[type="text"],dl.form>dd input[type="password"],dl.form>dd input[type="email"],dl.form>dd input[type="url"]{width:440px;max-width:100%;margin-right:5px}dl.form>dd input.shorter{width:130px}dl.form>dd input.short{width:250px}dl.form>dd input.long{width:100%}dl.form>dd textarea{width:100%;height:200px;min-height:200px}dl.form>dd textarea.short{height:50px;min-height:50px}dl.form>dd h4{margin:4px 0 0}dl.form>dd h4.is-error{color:#bd2c00}dl.form>dd h4.is-success{color:#6cc644}dl.form>dd h4+p.note{margin-top:0}dl.form.required>dt>label:after{padding-left:5px;color:#9f1006;content:"*"}dl.form .success,dl.form .error,dl.form .indicator{display:none;font-size:12px;font-weight:bold}dl.form.loading{opacity:0.5}dl.form.loading .indicator{display:inline}dl.form.loading .spinner{display:inline-block;vertical-align:middle}dl.form.successful .success{display:inline;color:#390}dl.form.warn dd.warning,dl.form.warn dd.error,dl.form.errored dd.warning,dl.form.errored dd.error{display:inline-block;position:absolute;max-width:450px;z-index:10;margin:2px 0 0;padding:5px 8px;font-size:13px;font-weight:normal;border-radius:3px}dl.form.warn dd.warning:after,dl.form.warn dd.warning:before,dl.form.warn dd.error:after,dl.form.warn dd.error:before,dl.form.errored dd.warning:after,dl.form.errored dd.warning:before,dl.form.errored dd.error:after,dl.form.errored dd.error:before{bottom:100%;z-index:15;left:10px;border:solid transparent;content:" ";height:0;width:0;position:absolute;pointer-events:none}dl.form.warn dd.warning:after,dl.form.warn dd.error:after,dl.form.errored dd.warning:after,dl.form.errored dd.error:after{border-width:5px}dl.form.warn dd.warning:before,dl.form.warn dd.error:before,dl.form.errored dd.warning:before,dl.form.errored dd.error:before{border-width:6px;margin-left:-1px}dl.form.warn dd.warning{color:#4e401e;background-color:#ffe5a7;border:1px solid #e7ce94}dl.form.warn dd.warning:after{border-bottom-color:#ffe5a7}dl.form.warn dd.warning:before{border-bottom-color:#cdb683}dl.form.errored>dt label{color:#bd2c00}dl.form.errored dd.error{color:#fff;background-color:#bf1515;border-color:#911;font-size:13px}dl.form.errored dd.error:after{border-bottom-color:#bf1515}dl.form.errored dd.error:before{border-bottom-color:#911}.note{min-height:17px;margin:4px 0 2px;font-size:12px;color:#767676}.note .spinner{margin-right:3px;vertical-align:middle}.form-checkbox{padding-left:20px;margin:15px 0;vertical-align:middle}.form-checkbox label em.highlight{position:relative;left:-4px;padding:2px 4px;font-style:normal;background:#fffbdc;border-radius:3px}.form-checkbox input[type=checkbox],.form-checkbox input[type=radio]{float:left;margin:2px 0 0 -20px;vertical-align:middle}.form-checkbox .note{display:block;margin:0;font-size:12px;font-weight:normal;color:#666}.hfields{margin:15px 0}.hfields:before{display:table;content:""}.hfields:after{display:table;clear:both;content:""}.hfields dl.form{float:left;margin:0 30px 0 0}.hfields dl.form>dt label{display:inline-block;margin:5px 0 0;color:#666}.hfields dl.form>dt img{position:relative;top:-2px}.hfields .btn{float:left;margin:28px 25px 0 -20px}.hfields select{margin-top:5px}input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{margin:0;-webkit-appearance:none}.input-group{display:table}.input-group input{position:relative;width:100%}.input-group input:focus{z-index:2}.input-group input[type="text"]+.btn{margin-left:0}.input-group.inline{display:inline-table}.input-group input,.input-group-button{display:table-cell}.input-group-button{width:1%;vertical-align:middle}.input-group input:first-child,.input-group-button:first-child .btn{border-top-right-radius:0;border-bottom-right-radius:0}.input-group-button:first-child .btn{margin-right:-1px}.input-group input:last-child,.input-group-button:last-child .btn{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-button:last-child .btn{margin-left:-1px}.form-actions:before{display:table;content:""}.form-actions:after{display:table;clear:both;content:""}.form-actions .btn{float:right}.form-actions .btn+.btn{margin-right:5px}.form-warning{padding:8px 10px;margin:10px 0;font-size:14px;color:#333;background:#ffffe2;border:1px solid #e7e4c2;border-radius:4px}.form-warning p{margin:0;line-height:1.5}.form-warning strong{color:#000}.form-warning a{font-weight:bold}.status-indicator{font:normal normal 16px / 1 "octicons";display:inline-block;text-decoration:none;-webkit-font-smoothing:antialiased;margin-left:5px}.status-indicator-success:before{color:#6cc644;content:"\f03a"}.status-indicator-failed:before{color:#bd2c00;content:"\f02d"}.select{display:inline-block;max-width:100%;padding:7px 24px 7px 8px;vertical-align:middle;background:#fff url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAUCAMAAACzvE1FAAAADFBMVEUzMzMzMzMzMzMzMzMKAG/3AAAAA3RSTlMAf4C/aSLHAAAAPElEQVR42q3NMQ4AIAgEQTn//2cLdRKppSGzBYwzVXvznNWs8C58CiussPJj8h6NwgorrKRdTvuV9v16Afn0AYFOB7aYAAAAAElFTkSuQmCC) no-repeat right 8px center;background-size:8px 10px;box-shadow:inset 0 -1px 2px rgba(0,0,0,0.075);-webkit-appearance:none;-moz-appearance:none;appearance:none;padding-right:8px \9;background-image:none \9}.select:focus{outline:none;border-color:#51a7e8;box-shadow:inset 0 1px 2px rgba(0,0,0,0.075),0 0 5px rgba(81,167,232,0.5)}.select::-ms-expand{opacity:0}.select-sm{padding-top:3px;padding-bottom:3px;font-size:12px}.select-sm:not([multiple]){height:26px;min-height:26px}.clearfix:before{display:table;content:""}.clearfix:after{display:table;clear:both;content:""}.right{float:right}.left{float:left}.centered{display:block;float:none;margin-left:auto;margin-right:auto}.text-right{text-align:right}.text-left{text-align:left}.text-center{text-align:center}.danger{color:#c00}.mute{color:#000}.text-diff-added{color:#55a532}.text-diff-deleted{color:#bd2c00}.text-open,.text-success{color:#6cc644}.text-closed{color:#bd2c00}.text-reverted{color:#bd2c00}.text-merged{color:#6e5494}.text-renamed{color:#fffa5d}.text-pending{color:#cea61b}.text-error,.text-failure{color:#bd2c00}.muted-link{color:#767676}.muted-link:hover{color:#4078c0;text-decoration:none}.hidden{display:none}.warning{padding:0.5em;margin-bottom:0.8em;font-weight:bold;background-color:#fffccc}.error_box{padding:1em;font-weight:bold;background-color:#ffebe8;border:1px solid #dd3c10}.flash{position:relative;padding:15px;font-size:14px;line-height:1.5;color:#246;background-color:#e2eef9;border:1px solid #bac6d3;border-radius:3px}.flash p:last-child{margin-bottom:0}.flash-messages{margin-bottom:20px}.flash-close{float:right;width:34px;height:44px;margin:-11px;color:inherit;line-height:40px;text-align:center;cursor:pointer;opacity:0.6;background:none;border:0;-webkit-appearance:none}.flash-close:hover{opacity:1}.flash-action{float:right;margin-top:-4px;margin-left:20px}.flash-warn{color:#4c4a42;background-color:#fff9ea;border-color:#dfd8c2}.flash-error{color:#911;background-color:#fcdede;border-color:#d2b2b2}.flash-full{margin-top:-1px;border-width:1px 0;border-radius:0}.flash-with-icon .container{padding-left:40px}.flash-with-icon .flash-icon{float:left;margin-top:3px;margin-left:-25px}.flash-content{margin-top:0;margin-bottom:0;line-height:1.5}.avatar{display:inline-block;overflow:hidden;line-height:1;vertical-align:middle;border-radius:3px}.avatar-small{border-radius:2px}.avatar-link{float:left;line-height:1}.avatar-group-item{display:inline-block;margin-bottom:3px}.avatar-parent-child{position:relative}.avatar-child{position:absolute;right:-15%;bottom:-9%;background-color:#fff;border-radius:2px;box-shadow:-2px -2px 0 rgba(255,255,255,0.8)}.blankslate{position:relative;padding:30px;text-align:center;background-color:#fafafa;border:1px solid #e5e5e5;border-radius:3px;box-shadow:inset 0 0 10px rgba(0,0,0,0.05)}.blankslate.clean-background{background:none;border:0;box-shadow:none}.blankslate.capped{border-radius:0 0 3px 3px}.blankslate.spacious{padding:100px 60px 120px}.blankslate.has-fixed-width{width:485px;margin:0 auto}.blankslate.large-format h3{margin:0.75em 0;font-size:20px}.blankslate.large-format p{font-size:16px}.blankslate.large-format p.has-fixed-width{width:540px;margin:0 auto;text-align:left}.blankslate.large-format .mega-octicon{width:40px;height:40px;font-size:40px;color:#aaa}.blankslate.large-format .octicon-inbox{font-size:48px;line-height:40px}.blankslate code{padding:2px 5px 3px;font-size:14px;background:#fff;border:1px solid #eee;border-radius:3px}.blankslate>.mega-octicon{color:#aaa}.blankslate .mega-octicon+.mega-octicon{margin-left:10px}.tabnav+.blankslate{margin-top:20px}.blankslate .context-loader.large-format-loader{padding-top:50px}.counter{display:inline-block;padding:2px 5px;font-size:11px;font-weight:bold;line-height:1;color:#666;background-color:#eee;border-radius:20px}.btn{position:relative;display:inline-block;padding:6px 12px;font-size:13px;font-weight:bold;line-height:20px;color:#333;white-space:nowrap;vertical-align:middle;cursor:pointer;background-color:#eee;background-image:linear-gradient(#fcfcfc, #eee);border:1px solid #d5d5d5;border-radius:3px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-appearance:none}.btn i{font-style:normal;font-weight:500;opacity:0.6}.btn .octicon{vertical-align:text-top}.btn .counter{text-shadow:none;background-color:#e5e5e5}.btn:focus{text-decoration:none;border-color:#51a7e8;outline:none;box-shadow:0 0 5px rgba(81,167,232,0.5)}.btn:focus:hover,.btn.selected:focus{border-color:#51a7e8}.btn:hover,.btn:active,.btn.zeroclipboard-is-hover,.btn.zeroclipboard-is-active{text-decoration:none;background-color:#ddd;background-image:linear-gradient(#eee, #ddd);border-color:#ccc}.btn:active,.btn.selected,.btn.zeroclipboard-is-active{background-color:#dcdcdc;background-image:none;border-color:#b5b5b5;box-shadow:inset 0 2px 4px rgba(0,0,0,0.15)}.btn.selected:hover{background-color:#cfcfcf}.btn:disabled,.btn:disabled:hover,.btn.disabled,.btn.disabled:hover{color:rgba(102,102,102,0.5);cursor:default;background-color:rgba(229,229,229,0.5);background-image:none;border-color:rgba(197,197,197,0.5);box-shadow:none}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.15);background-color:#60b044;background-image:linear-gradient(#8add6d, #60b044);border-color:#5ca941}.btn-primary .counter{color:#60b044;background-color:#fff}.btn-primary:hover{color:#fff;background-color:#569e3d;background-image:linear-gradient(#79d858, #569e3d);border-color:#4a993e}.btn-primary:active,.btn-primary.selected{text-shadow:0 1px 0 rgba(0,0,0,0.15);background-color:#569e3d;background-image:none;border-color:#418737}.btn-primary.selected:hover{background-color:#4c8b36}.btn-primary:disabled,.btn-primary:disabled:hover,.btn-primary.disabled,.btn-primary.disabled:hover{color:#fefefe;background-color:#add39f;background-image:linear-gradient(#c3ecb4, #add39f);border-color:#b9dcac #b9dcac #a7c89b}.btn-danger{color:#900}.btn-danger:hover{color:#fff;background-color:#b33630;background-image:linear-gradient(#dc5f59, #b33630);border-color:#cd504a}.btn-danger:active,.btn-danger.selected{color:#fff;background-color:#b33630;background-image:none;border-color:#9f312c}.btn-danger.selected:hover{background-color:#9f302b}.btn-danger:disabled,.btn-danger:disabled:hover,.btn-danger.disabled,.btn-danger.disabled:hover{color:#cb7f7f;background-color:#efefef;background-image:linear-gradient(#fefefe, #efefef);border-color:#e1e1e1}.btn-danger:hover .counter,.btn-danger:active .counter,.btn-danger.selected .counter{color:#b33630;background-color:#fff}.btn-outline{color:#4078c0;background-color:#fff;background-image:none;border:1px solid #e5e5e5}.btn-outline .counter{background-color:#eee}.btn-outline:hover,.btn-outline:active,.btn-outline.selected,.btn-outline.zeroclipboard-is-hover,.btn-outline.zeroclipboard-is-active{color:#fff;background-color:#4078c0;background-image:none;border-color:#4078c0}.btn-outline:hover .counter,.btn-outline:active .counter,.btn-outline.selected .counter,.btn-outline.zeroclipboard-is-hover .counter,.btn-outline.zeroclipboard-is-active .counter{color:#4078c0;background-color:#fff}.btn-outline.selected:hover{background-color:#396cad}.btn-outline:disabled,.btn-outline:disabled:hover,.btn-outline.disabled,.btn-outline.disabled:hover{color:#767676;background-color:#fff;background-image:none;border-color:#e5e5e5}.btn-with-count{float:left;border-top-right-radius:0;border-bottom-right-radius:0}.btn-sm{padding:2px 10px}.hidden-text-expander{display:block}.hidden-text-expander.inline{position:relative;top:-1px;display:inline-block;margin-left:5px;line-height:0}.hidden-text-expander a,.ellipsis-expander{display:inline-block;height:12px;padding:0 5px 5px;font-size:12px;font-weight:bold;line-height:6px;color:#555;text-decoration:none;vertical-align:middle;background:#ddd;border-radius:1px;border:0}.hidden-text-expander a:hover,.ellipsis-expander:hover{text-decoration:none;background-color:#ccc}.hidden-text-expander a:active,.ellipsis-expander:active{color:#fff;background-color:#4183c4}.social-count{float:left;padding:2px 7px;font-size:11px;font-weight:bold;line-height:20px;color:#333;vertical-align:middle;background-color:#fff;border:1px solid #ddd;border-left:0;border-top-right-radius:3px;border-bottom-right-radius:3px}.social-count:hover,.social-count:active{text-decoration:none}.social-count:hover{color:#4078c0;cursor:pointer}.btn-block{display:block;width:100%;text-align:center}.btn-group{display:inline-block;vertical-align:middle}.btn-group:before{display:table;content:""}.btn-group:after{display:table;clear:both;content:""}.btn-group .btn{position:relative;float:left}.btn-group .btn:not(:first-child):not(:last-child){border-radius:0}.btn-group .btn:first-child:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group .btn:last-child:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .btn:hover,.btn-group .btn:active,.btn-group .btn.selected{z-index:2}.btn-group .btn:focus{z-index:3}.btn-group .btn+.btn{margin-left:-1px}.btn-group .btn+.button_to,.btn-group .button_to+.btn,.btn-group .button_to+.button_to{margin-left:-1px}.btn-group .button_to{float:left}.btn-group .button_to .btn{border-radius:0}.btn-group .button_to:first-child .btn{border-top-left-radius:3px;border-bottom-left-radius:3px}.btn-group .button_to:last-child .btn{border-top-right-radius:3px;border-bottom-right-radius:3px}.btn-group+.btn-group,.btn-group+.btn{margin-left:5px}.btn-link{display:inline-block;padding:0;font-size:inherit;color:#4078c0;white-space:nowrap;cursor:pointer;background-color:transparent;border:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-appearance:none}.btn-link:hover,.btn-link:focus{text-decoration:underline}.btn-link:focus{outline:none}.menu{margin-bottom:15px;list-style:none;background-color:#fff;border:1px solid #d8d8d8;border-radius:3px}.menu-item{position:relative;display:block;padding:8px 10px;text-shadow:0 1px 0 #fff;border-bottom:1px solid #eee}.menu-item:first-child{border-top:0;border-top-right-radius:2px;border-top-left-radius:2px}.menu-item:first-child:before{border-top-left-radius:2px}.menu-item:last-child{border-bottom:0;border-bottom-right-radius:2px;border-bottom-left-radius:2px}.menu-item:last-child:before{border-bottom-left-radius:2px}.menu-item:hover{text-decoration:none;background-color:#f9f9f9}.menu-item.selected{font-weight:bold;color:#222;cursor:default;background-color:#fff}.menu-item.selected:before{position:absolute;top:0;left:0;bottom:0;width:2px;content:"";background-color:#d26911}.menu-item .octicon{margin-right:5px;width:16px;color:#333;text-align:center}.menu-item .counter{float:right;margin-left:5px}.menu-item .menu-warning{float:right;color:#d26911}.menu-item .avatar{float:left;margin-right:5px}.menu-item.alert .counter{color:#bd2c00}.menu-heading{display:block;padding:8px 10px;margin-top:0;margin-bottom:0;font-size:13px;font-weight:bold;line-height:20px;color:#555;background-color:#f7f7f7;border-bottom:1px solid #eee}.menu-heading:hover{text-decoration:none}.menu-heading:first-child{border-top-right-radius:2px;border-top-left-radius:2px}.menu-heading:last-child{border-bottom-right-radius:2px;border-bottom-left-radius:2px;border-bottom:0}.tabnav{margin-top:0;margin-bottom:15px;border-bottom:1px solid #ddd}.tabnav .counter{margin-left:5px}.tabnav-tabs{margin-bottom:-1px}.tabnav-tab{display:inline-block;padding:8px 12px;font-size:14px;line-height:20px;color:#666;text-decoration:none;background-color:transparent;border:1px solid transparent;border-bottom:0}.tabnav-tab.selected{color:#333;background-color:#fff;border-color:#ddd;border-radius:3px 3px 0 0}.tabnav-tab:hover,.tabnav-tab:focus{text-decoration:none}.tabnav-extra{display:inline-block;padding-top:10px;margin-left:10px;font-size:12px;color:#666}.tabnav-extra>.octicon{margin-right:2px}a.tabnav-extra:hover{color:#4078c0;text-decoration:none}.tabnav-btn{margin-left:10px}.filter-list{list-style-type:none}.filter-list.small .filter-item{padding:4px 10px;margin:0 0 2px;font-size:12px}.filter-list.pjax-active .filter-item{color:#767676;background-color:transparent}.filter-list.pjax-active .filter-item.pjax-active{color:#fff;background-color:#4078c0}.filter-item{position:relative;display:block;padding:8px 10px;margin-bottom:5px;overflow:hidden;font-size:14px;color:#767676;text-decoration:none;text-overflow:ellipsis;white-space:nowrap;cursor:pointer;border-radius:3px}.filter-item:hover{text-decoration:none;background-color:#eee}.filter-item.selected{color:#fff;background-color:#4078c0}.filter-item.selected .octicon-remove-close{float:right;opacity:0.8}.filter-item .count{float:right;font-weight:bold}.filter-item .bar{position:absolute;top:2px;right:0;bottom:2px;z-index:-1;display:inline-block;background-color:#f1f1f1}.state{display:inline-block;padding:4px 8px;font-weight:bold;line-height:20px;color:#fff;text-align:center;border-radius:3px;background-color:#999}.state-open,.state-proposed,.state-reopened{background-color:#6cc644}.state-merged{background-color:#6e5494}.state-closed{background-color:#bd2c00}.state-renamed{background-color:#fffa5d}.tooltipped{position:relative}.tooltipped:after{position:absolute;z-index:1000000;display:none;padding:5px 8px;font:normal normal 11px/1.5 Helvetica,arial,nimbussansl,liberationsans,freesans,clean,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";color:#fff;text-align:center;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-wrap:break-word;white-space:pre;pointer-events:none;content:attr(aria-label);background:rgba(0,0,0,0.8);border-radius:3px;-webkit-font-smoothing:subpixel-antialiased}.tooltipped:before{position:absolute;z-index:1000001;display:none;width:0;height:0;color:rgba(0,0,0,0.8);pointer-events:none;content:"";border:5px solid transparent}.tooltipped:hover:before,.tooltipped:hover:after,.tooltipped:active:before,.tooltipped:active:after,.tooltipped:focus:before,.tooltipped:focus:after{display:inline-block;text-decoration:none}.tooltipped-multiline:hover:after,.tooltipped-multiline:active:after,.tooltipped-multiline:focus:after{display:table-cell}.tooltipped-s:after,.tooltipped-se:after,.tooltipped-sw:after{top:100%;right:50%;margin-top:5px}.tooltipped-s:before,.tooltipped-se:before,.tooltipped-sw:before{top:auto;right:50%;bottom:-5px;margin-right:-5px;border-bottom-color:rgba(0,0,0,0.8)}.tooltipped-se:after{right:auto;left:50%;margin-left:-15px}.tooltipped-sw:after{margin-right:-15px}.tooltipped-n:after,.tooltipped-ne:after,.tooltipped-nw:after{right:50%;bottom:100%;margin-bottom:5px}.tooltipped-n:before,.tooltipped-ne:before,.tooltipped-nw:before{top:-5px;right:50%;bottom:auto;margin-right:-5px;border-top-color:rgba(0,0,0,0.8)}.tooltipped-ne:after{right:auto;left:50%;margin-left:-15px}.tooltipped-nw:after{margin-right:-15px}.tooltipped-s:after,.tooltipped-n:after{-webkit-transform:translateX(50%);-ms-transform:translateX(50%);transform:translateX(50%)}.tooltipped-w:after{right:100%;bottom:50%;margin-right:5px;-webkit-transform:translateY(50%);-ms-transform:translateY(50%);transform:translateY(50%)}.tooltipped-w:before{top:50%;bottom:50%;left:-5px;margin-top:-5px;border-left-color:rgba(0,0,0,0.8)}.tooltipped-e:after{bottom:50%;left:100%;margin-left:5px;-webkit-transform:translateY(50%);-ms-transform:translateY(50%);transform:translateY(50%)}.tooltipped-e:before{top:50%;right:-5px;bottom:50%;margin-top:-5px;border-right-color:rgba(0,0,0,0.8)}.tooltipped-multiline:after{width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:250px;word-break:break-word;word-wrap:normal;white-space:pre-line;border-collapse:separate}.tooltipped-multiline.tooltipped-s:after,.tooltipped-multiline.tooltipped-n:after{right:auto;left:50%;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%)}.tooltipped-multiline.tooltipped-w:after,.tooltipped-multiline.tooltipped-e:after{right:100%}@media screen and (min-width: 0\0){.tooltipped-multiline:after{width:250px}}.tooltipped-sticky:before,.tooltipped-sticky:after{display:inline-block}.tooltipped-sticky.tooltipped-multiline:after{display:table-cell}.flex-table{display:table}.flex-table-item{display:table-cell;width:1%;white-space:nowrap;vertical-align:middle}.flex-table-item-primary{width:99%}.css-truncate.css-truncate-target,.css-truncate .css-truncate-target{display:inline-block;max-width:125px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:top}.css-truncate.expandable.zeroclipboard-is-hover .css-truncate-target,.css-truncate.expandable.zeroclipboard-is-hover.css-truncate-target,.css-truncate.expandable:hover .css-truncate-target,.css-truncate.expandable:hover.css-truncate-target{max-width:10000px !important} 2 | -------------------------------------------------------------------------------- /src/main/resources/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avast/gradle-dependencies-viewer/1dedefefa0509b0ebcaa5db816ed76726f6194af/src/main/resources/static/favicon.ico -------------------------------------------------------------------------------- /src/main/resources/static/img/glyphicons-65-lightbulb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avast/gradle-dependencies-viewer/1dedefefa0509b0ebcaa5db816ed76726f6194af/src/main/resources/static/img/glyphicons-65-lightbulb.png -------------------------------------------------------------------------------- /src/main/resources/static/img/gradle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avast/gradle-dependencies-viewer/1dedefefa0509b0ebcaa5db816ed76726f6194af/src/main/resources/static/img/gradle.png -------------------------------------------------------------------------------- /src/main/resources/static/img/maven.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avast/gradle-dependencies-viewer/1dedefefa0509b0ebcaa5db816ed76726f6194af/src/main/resources/static/img/maven.png -------------------------------------------------------------------------------- /src/main/resources/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Getting Started: Serving Web Content 5 | 6 | 7 | 8 | Hello. 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/resources/static/js/gradle.js: -------------------------------------------------------------------------------- 1 | var parsedData = null; 2 | function setData(newData, projectName) { 3 | 4 | var $jstree = $('#jstree'); 5 | var treeData = []; 6 | var projectList = []; 7 | var ignoreTests = $("input[name='ignoreTests']").is(":checked"); 8 | 9 | $.each(newData.projects, function (title, project) { 10 | projectList.push("".formatX(title)); 11 | }); 12 | $.each(newData.projects, function (index, project) { 13 | var show = true; 14 | if (projectName) { 15 | if (index != projectName) { 16 | show = false; 17 | } 18 | } 19 | if (show) { 20 | $.each(project.sourceSet, function (sourceSetName, sub) { 21 | if (!(ignoreTests && sourceSetName.toLowerCase().contains('test'))) { 22 | $.each(sub, function (index, treeItem) { 23 | if (index == 0) { 24 | treeItem.text += ' (' + sourceSetName + ')'; 25 | } 26 | treeData.push(treeItem); 27 | }); 28 | } 29 | }); 30 | return false; 31 | } 32 | }); 33 | 34 | if (!projectName) { 35 | $("#projectList") 36 | .html(projectList) 37 | .selectpicker('refresh'); 38 | } 39 | 40 | $jstree.jstree(true).settings.core.data = treeData; 41 | $jstree.jstree(true).refresh(); 42 | } 43 | 44 | function doParse(pastedData) { 45 | $('#gradlePasteArea').val(pastedData); 46 | var sentDataObject = { 47 | "data": pastedData 48 | }; 49 | $.ajax({ 50 | type: "POST", 51 | url: "/gradle/parse", 52 | data: JSON.stringify(sentDataObject), 53 | traditional: true, 54 | contentType: "application/json", 55 | fail : function(data) { 56 | toastr["error"](data, "Failed to parse input data"); 57 | }, 58 | success: function (data) { 59 | parsedData = data; 60 | setData(jQuery.extend(true, {}, data), null); 61 | }, 62 | dataType: "json" 63 | }); 64 | } 65 | function handlePaste(e) { 66 | var clipboardData, pastedData; 67 | 68 | // Stop data actually being pasted into div 69 | e.stopPropagation(); 70 | e.preventDefault(); 71 | 72 | // Get pasted data via clipboard API 73 | clipboardData = e.clipboardData || window.clipboardData; 74 | pastedData = clipboardData.getData('Text'); 75 | // Do whatever with pasteddata 76 | doParse(pastedData); 77 | } 78 | 79 | function getDependencyText(text) { 80 | text = text.replaceAll("(*)", ""); 81 | var italic = text.indexOf(''); 82 | if (italic >= 0) { 83 | text = text.substring(0, italic); 84 | } 85 | var arrow = text.indexOf('->'); 86 | if (arrow >= 0) { 87 | text = text.substring(0, arrow); 88 | } 89 | return text.trim(); 90 | } 91 | 92 | function getGroup(text) { 93 | var index = text.indexOf(":"); 94 | if (index > 0) { 95 | return text.substring(0, index); 96 | } 97 | return text; 98 | } 99 | 100 | function getGroupWithArtifact(childNodeText, parentNodeText) { 101 | var parent = getDependencyText(parentNodeText); 102 | var child = getDependencyText(childNodeText); 103 | 104 | if (child == parent) { 105 | return "exclude group: '{0}'".formatX(getGroup(child)); 106 | } else { 107 | return "compile(\"{0}\"){\n exclude group: '{1}'\n}".formatX(parent, getGroup(child)); 108 | } 109 | } 110 | 111 | 112 | function applyData() { 113 | var val = $('#gradlePasteArea').val(); 114 | if (val != '') { 115 | doParse(val); 116 | } 117 | } 118 | function refreshData() { 119 | if (parsedData) { 120 | setData(jQuery.extend(true, {}, parsedData), $('#projectList').val()); 121 | } 122 | } 123 | 124 | function handleFileSelect(evt) { 125 | evt.stopPropagation(); 126 | evt.preventDefault(); 127 | 128 | var files = evt.dataTransfer.files; // FileList object. 129 | 130 | if (files.length > 0) { 131 | var fileReader = new FileReader(); 132 | fileReader.onload = function(e) { 133 | var text = fileReader.result; 134 | $('#gradlePasteArea').val(text); 135 | applyData(); 136 | }; 137 | fileReader.readAsText(files[0], "UTF-8") 138 | 139 | } 140 | } 141 | 142 | function handleDragOver(evt) { 143 | evt.stopPropagation(); 144 | evt.preventDefault(); 145 | evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy. 146 | } 147 | 148 | function getSearchTextFromArtifact(text) { 149 | text = text.replaceAll("(*)", ""); 150 | var italic = text.indexOf(''); 151 | if (italic >= 0) { 152 | text = text.substring(0, italic); 153 | } 154 | 155 | var arrowIndex = text.indexOf(" -> "); 156 | var version = null; 157 | if (arrowIndex > 0) { 158 | afterFlag = text.substring(arrowIndex + 4).trim(); 159 | if (!isNaN(afterFlag.charAt(0))) { 160 | version = afterFlag; 161 | } else { 162 | return afterFlag; 163 | } 164 | 165 | text = text.substring(0, arrowIndex); 166 | var split = text.split(":"); 167 | if (split.length >= 2) { 168 | var split2 = split[1]; 169 | var spaceIndex = split2.indexOf(' '); 170 | if (spaceIndex > 0) { 171 | split2 = split2.substring(0, spaceIndex); 172 | } 173 | if (!version) { 174 | version = split[2]; 175 | } 176 | return split2.trim() + ':' + version; 177 | } else { 178 | return text + ':' + version; 179 | } 180 | } else { 181 | var split = text.split(":"); 182 | if (split.length >= 2) { 183 | var split2 = split[1]; 184 | var spaceIndex = split2.indexOf(' '); 185 | if (spaceIndex > 0) { 186 | split2 = split2.substring(0, spaceIndex); 187 | } 188 | if (!version) { 189 | version = split[2]; 190 | } 191 | return split2.trim() + ':' + version; 192 | } else { 193 | return text; 194 | } 195 | } 196 | } 197 | 198 | function searchForArtifact(text) { 199 | var $searchTree = $('#searchTree'); 200 | $searchTree.val(getSearchTextFromArtifact(text)); 201 | $searchTree.trigger("input"); 202 | } 203 | 204 | 205 | $(function () { 206 | //document.getElementById('gradlePasteArea').addEventListener('paste', handlePaste); 207 | 208 | // Setup the dnd listeners. 209 | var dropZone = document.getElementById('gradlePasteArea'); 210 | dropZone.addEventListener('dragover', handleDragOver, false); 211 | dropZone.addEventListener('drop', handleFileSelect, false); 212 | 213 | $("#menuGradle").addClass("active"); 214 | toastr.options = { 215 | "closeButton": false, 216 | "debug": false, 217 | "newestOnTop": false, 218 | "progressBar": false, 219 | "positionClass": "toast-bottom-left", 220 | "preventDuplicates": false, 221 | "onclick": null, 222 | "showDuration": "2000", 223 | "hideDuration": "3000", 224 | "timeOut": "3000", 225 | "extendedTimeOut": "1000", 226 | "showEasing": "swing", 227 | "hideEasing": "linear", 228 | "showMethod": "fadeIn", 229 | "hideMethod": "fadeOut" 230 | }; 231 | 232 | 233 | var $jstree = $('#jstree'); 234 | $('#clearButton').click(function () { 235 | $('#gradlePasteArea').val(''); 236 | }); 237 | 238 | $('#applyButton').click(function () { 239 | applyData(); 240 | }); 241 | 242 | 243 | $('#expandButton').click(function () { 244 | $jstree.jstree("open_all"); 245 | }); 246 | 247 | $('#collapseButton').click(function () { 248 | $jstree.jstree("close_all"); 249 | }); 250 | 251 | $('#projectList').on('hidden.bs.select', function (e) { 252 | refreshData(); 253 | }); 254 | 255 | $("input[name='ignoreTests']").prop("checked", true); 256 | $('#ignoreTests').change(function () { 257 | refreshData(); 258 | }); 259 | 260 | $jstree.jstree({ 261 | "core": { 262 | "animation": 0, 263 | "themes": {"stripes": true} 264 | }, 265 | "types": { 266 | "root": { 267 | "icon": "/static/3.3.3/assets/images/tree_icon.png", 268 | "valid_children": ["default"] 269 | }, 270 | "default": { 271 | "valid_children": ["default", "file"] 272 | }, 273 | "file": { 274 | "icon": "glyphicon glyphicon-file", 275 | "valid_children": [] 276 | } 277 | }, 278 | "contextmenu":{ 279 | "items": function($node) { 280 | var tree = $jstree.jstree(true); 281 | return { 282 | "Search-for-artifact": { 283 | "separator_before": false, 284 | "separator_after": true, 285 | "label": "Search for artifact", 286 | "action": function (obj) { 287 | searchForArtifact(tree.get_text($node)); 288 | } 289 | }, 290 | "Exclude": { 291 | "separator_before": false, 292 | "separator_after": false, 293 | "label": "Exclude dependency", 294 | "action": function (obj) { 295 | var path = tree.get_path($node, null, true); 296 | var rootNode = tree.get_node(path[0]); 297 | copyToClipboard(getGroupWithArtifact(tree.get_text($node), tree.get_text(rootNode))); 298 | toastr["info"]("Copied to clipboard", "Exclude dependency"); 299 | } 300 | } 301 | }; 302 | } 303 | }, 304 | "search": { 305 | "case_insensitive": true, 306 | "show_only_matches": true 307 | }, 308 | "plugins": [ 309 | "contextmenu","dnd", "search", "wholerow" 310 | ] 311 | }); 312 | var to = null; 313 | var $searchTree = $('#searchTree'); 314 | $jstree.on('refresh.jstree', function () { 315 | var v = $searchTree.val(); 316 | 317 | setTimeout(function () { 318 | $jstree.jstree(true).search(v); 319 | }, 50); 320 | }); 321 | $searchTree.on('input', function () { 322 | if (to) { 323 | clearTimeout(to); 324 | } 325 | to = setTimeout(function () { 326 | // var v = $searchTree.val(); 327 | $jstree.jstree(true).refresh(); 328 | 329 | }, 500); 330 | }); 331 | 332 | 333 | }); -------------------------------------------------------------------------------- /src/main/resources/static/js/js.cookie.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JavaScript Cookie v2.1.3 3 | * https://github.com/js-cookie/js-cookie 4 | * 5 | * Copyright 2006, 2015 Klaus Hartl & Fagner Brack 6 | * Released under the MIT license 7 | */ 8 | ;(function (factory) { 9 | var registeredInModuleLoader = false; 10 | if (typeof define === 'function' && define.amd) { 11 | define(factory); 12 | registeredInModuleLoader = true; 13 | } 14 | if (typeof exports === 'object') { 15 | module.exports = factory(); 16 | registeredInModuleLoader = true; 17 | } 18 | if (!registeredInModuleLoader) { 19 | var OldCookies = window.Cookies; 20 | var api = window.Cookies = factory(); 21 | api.noConflict = function () { 22 | window.Cookies = OldCookies; 23 | return api; 24 | }; 25 | } 26 | }(function () { 27 | function extend () { 28 | var i = 0; 29 | var result = {}; 30 | for (; i < arguments.length; i++) { 31 | var attributes = arguments[ i ]; 32 | for (var key in attributes) { 33 | result[key] = attributes[key]; 34 | } 35 | } 36 | return result; 37 | } 38 | 39 | function init (converter) { 40 | function api (key, value, attributes) { 41 | var result; 42 | if (typeof document === 'undefined') { 43 | return; 44 | } 45 | 46 | // Write 47 | 48 | if (arguments.length > 1) { 49 | attributes = extend({ 50 | path: '/' 51 | }, api.defaults, attributes); 52 | 53 | if (typeof attributes.expires === 'number') { 54 | var expires = new Date(); 55 | expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5); 56 | attributes.expires = expires; 57 | } 58 | 59 | try { 60 | result = JSON.stringify(value); 61 | if (/^[\{\[]/.test(result)) { 62 | value = result; 63 | } 64 | } catch (e) {} 65 | 66 | if (!converter.write) { 67 | value = encodeURIComponent(String(value)) 68 | .replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent); 69 | } else { 70 | value = converter.write(value, key); 71 | } 72 | 73 | key = encodeURIComponent(String(key)); 74 | key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent); 75 | key = key.replace(/[\(\)]/g, escape); 76 | 77 | return (document.cookie = [ 78 | key, '=', value, 79 | attributes.expires ? '; expires=' + attributes.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE 80 | attributes.path ? '; path=' + attributes.path : '', 81 | attributes.domain ? '; domain=' + attributes.domain : '', 82 | attributes.secure ? '; secure' : '' 83 | ].join('')); 84 | } 85 | 86 | // Read 87 | 88 | if (!key) { 89 | result = {}; 90 | } 91 | 92 | // To prevent the for loop in the first place assign an empty array 93 | // in case there are no cookies at all. Also prevents odd result when 94 | // calling "get()" 95 | var cookies = document.cookie ? document.cookie.split('; ') : []; 96 | var rdecode = /(%[0-9A-Z]{2})+/g; 97 | var i = 0; 98 | 99 | for (; i < cookies.length; i++) { 100 | var parts = cookies[i].split('='); 101 | var cookie = parts.slice(1).join('='); 102 | 103 | if (cookie.charAt(0) === '"') { 104 | cookie = cookie.slice(1, -1); 105 | } 106 | 107 | try { 108 | var name = parts[0].replace(rdecode, decodeURIComponent); 109 | cookie = converter.read ? 110 | converter.read(cookie, name) : converter(cookie, name) || 111 | cookie.replace(rdecode, decodeURIComponent); 112 | 113 | if (this.json) { 114 | try { 115 | cookie = JSON.parse(cookie); 116 | } catch (e) {} 117 | } 118 | 119 | if (key === name) { 120 | result = cookie; 121 | break; 122 | } 123 | 124 | if (!key) { 125 | result[name] = cookie; 126 | } 127 | } catch (e) {} 128 | } 129 | 130 | return result; 131 | } 132 | 133 | api.set = api; 134 | api.get = function (key) { 135 | return api.call(api, key); 136 | }; 137 | api.getJSON = function () { 138 | return api.apply({ 139 | json: true 140 | }, [].slice.call(arguments)); 141 | }; 142 | api.defaults = {}; 143 | 144 | api.remove = function (key, attributes) { 145 | api(key, '', extend(attributes, { 146 | expires: -1 147 | })); 148 | }; 149 | 150 | api.withConverter = init; 151 | 152 | return api; 153 | } 154 | 155 | return init(function () {}); 156 | })); 157 | -------------------------------------------------------------------------------- /src/main/resources/static/js/utils.js: -------------------------------------------------------------------------------- 1 | // First, checks if it isn't implemented yet. 2 | if (!String.prototype.format) { 3 | String.prototype.formatX = function () { 4 | var args = arguments; 5 | return this.replace(/{(\d+)}/g, function (match, number) { 6 | return typeof args[number] != 'undefined' 7 | ? args[number] 8 | : match 9 | ; 10 | }); 11 | }; 12 | } 13 | 14 | if (!String.prototype.contains) { 15 | String.prototype.contains = function (it) { 16 | return this.indexOf(it) != -1; 17 | }; 18 | } 19 | 20 | if (!Array.prototype.getUnique) { 21 | Array.prototype.getUnique = function () { 22 | var u = {}, a = []; 23 | for (var i = 0, l = this.length; i < l; ++i) { 24 | if (u.hasOwnProperty(this[i])) { 25 | continue; 26 | } 27 | a.push(this[i]); 28 | u[this[i]] = 1; 29 | } 30 | return a; 31 | } 32 | } 33 | 34 | if (!String.prototype.replaceAll) { 35 | 36 | function escapeRegExp(str) { 37 | return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); 38 | } 39 | 40 | String.prototype.replaceAll = function(search, replacement) { 41 | var target = this; 42 | return target.replace(new RegExp(escapeRegExp(search), 'g'), replacement); 43 | }; 44 | } 45 | 46 | 47 | // Copies a string to the clipboard. Must be called from within an 48 | // event handler such as click. May return false if it failed, but 49 | // this is not always possible. Browser support for Chrome 43+, 50 | // Firefox 42+, Safari 10+, Edge and IE 10+. 51 | // IE: The clipboard feature may be disabled by an administrator. By 52 | // default a prompt is shown the first time the clipboard is 53 | // used (per session). 54 | function copyToClipboard(text) { 55 | if (window.clipboardData && window.clipboardData.setData) { 56 | // IE specific code path to prevent textarea being shown while dialog is visible. 57 | return clipboardData.setData("Text", text); 58 | 59 | } else if (document.queryCommandSupported && document.queryCommandSupported("copy")) { 60 | var textarea = document.createElement("textarea"); 61 | textarea.textContent = text; 62 | textarea.style.position = "fixed"; // Prevent scrolling to bottom of page in MS Edge. 63 | document.body.appendChild(textarea); 64 | textarea.select(); 65 | try { 66 | return document.execCommand("copy"); // Security exception may be thrown by some browsers. 67 | } catch (ex) { 68 | console.warn("Copy to clipboard failed.", ex); 69 | return false; 70 | } finally { 71 | document.body.removeChild(textarea); 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /src/main/resources/templates/footer.html: -------------------------------------------------------------------------------- 1 |
2 |

vitasek/@/avast.com 3 | , Gradle Dependency Viewer  1.0.0

5 |
6 | -------------------------------------------------------------------------------- /src/main/resources/templates/gradle.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Gradle Dependencies Viewer 6 | 7 | 8 | 9 | 10 | 12 | 13 | 15 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | 24 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 43 |
44 |
45 |
46 |

Gradle Dependencies Viewer

47 | 51 | 52 |
53 |
54 |
55 |
56 |
57 | 61 | 65 |
66 |
67 |
68 |
69 | 70 | 71 |
72 |
73 |
74 |
75 |
76 | 79 |
80 |
81 |
82 |
83 | 85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 | 93 | 94 |
95 | 96 | 97 | 98 |
99 |
100 |
101 |
102 |
103 |

Input

104 | 107 |
108 |
109 |
110 | 111 | 113 | 114 |
115 | 118 | 122 |
123 |
124 |
125 |
126 |
127 |
128 |

Gradle command line hints

129 |
    130 |
  • Subproject dependencies only .... gradle sub1:dependencies
  • 131 |
  • All dependencies with subprojects .... check 133 | this code
  • 134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 | Use right click on tree to exclude dependency 142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 | 151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /src/main/resources/templates/menu.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/test/java/com/avast/server/libver/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2015 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.avast.server.libver; 18 | 19 | import static org.hamcrest.Matchers.containsString; 20 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 21 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; 22 | 23 | import org.junit.jupiter.api.Test; 24 | import org.springframework.beans.factory.annotation.Autowired; 25 | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; 26 | import org.springframework.boot.test.context.SpringBootTest; 27 | import org.springframework.test.web.servlet.MockMvc; 28 | 29 | @SpringBootTest 30 | @AutoConfigureMockMvc 31 | public class ApplicationTest { 32 | 33 | @Autowired 34 | private MockMvc mockMvc; 35 | 36 | @Test 37 | public void testIndex() throws Exception { 38 | mockMvc.perform(get("/")) 39 | .andExpect(content().string(containsString("html"))); 40 | } 41 | } -------------------------------------------------------------------------------- /src/test/java/com/avast/server/libver/service/GradleServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.avast.server.libver.service; 2 | 3 | 4 | import com.avast.server.libver.model.gradle.GradleDepsDescriptor; 5 | import com.avast.server.libver.service.impl.GradleServiceImpl; 6 | import org.junit.jupiter.api.Test; 7 | 8 | import java.net.URI; 9 | import java.nio.file.Files; 10 | import java.nio.file.Paths; 11 | import java.util.stream.Collectors; 12 | 13 | /** 14 | * @author Vitasek L. 15 | */ 16 | public class GradleServiceTest { 17 | @Test 18 | public void parseGradle() throws Exception { 19 | final URI uri = GradleServiceTest.class.getResource("/dep.txt").toURI(); 20 | final String data = Files.lines(Paths.get(uri)).collect(Collectors.joining("\n")); 21 | final GradleDepsDescriptor gradleDesc = new GradleServiceImpl().parse(data); 22 | System.out.println("gradleDesc = " + gradleDesc); 23 | } 24 | 25 | @Test 26 | public void parseGradle2() throws Exception { 27 | final URI uri = GradleServiceTest.class.getResource("/dep2.txt").toURI(); 28 | final String data = Files.lines(Paths.get(uri)).collect(Collectors.joining("\n")); 29 | final GradleDepsDescriptor gradleDesc = new GradleServiceImpl().parse(data); 30 | System.out.println("gradleDesc = " + gradleDesc); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /web/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avast/gradle-dependencies-viewer/1dedefefa0509b0ebcaa5db816ed76726f6194af/web/screenshot.png --------------------------------------------------------------------------------