├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── j2d-cli └── src │ └── main │ └── java │ └── com │ └── megatome │ └── j2d │ └── Main.java ├── j2d-gradle └── src │ ├── main │ ├── groovy │ │ └── com │ │ │ └── megatome │ │ │ └── javadoc2dash │ │ │ ├── Javadoc2DashPlugin.groovy │ │ │ └── tasks │ │ │ ├── Javadoc2DashFeedTask.groovy │ │ │ └── Javadoc2DashTask.groovy │ └── resources │ │ └── META-INF │ │ └── gradle-plugins │ │ └── com.megatome.javadoc2dash.properties │ └── test │ ├── groovy │ └── com │ │ └── megatome │ │ └── javadoc2dash │ │ ├── Javadoc2DashPluginSpec.groovy │ │ └── tasks │ │ └── Javadoc2DashTaskSpec.groovy │ └── resources │ └── TestProject │ └── icon.png ├── j2d-sample └── src │ └── main │ └── java │ └── com │ └── megatome │ └── j2d │ └── sample │ ├── annotation │ └── SampleAnnotation.java │ ├── clazz │ └── SampleClass.java │ ├── enums │ └── SampleEnum.java │ ├── error │ └── SampleError.java │ ├── exception │ └── SampleException.java │ └── iface │ └── SampleInterface.java ├── javadoc2dash-api ├── gradle.properties └── src │ ├── main │ └── java │ │ └── com │ │ └── megatome │ │ └── j2d │ │ ├── DocsetCreator.java │ │ ├── exception │ │ └── BuilderException.java │ │ ├── support │ │ ├── DBSupport.java │ │ ├── DocSetSupport.java │ │ ├── JavadocSupport.java │ │ └── MatchType.java │ │ └── util │ │ ├── IndexData.java │ │ ├── LogUtility.java │ │ └── SearchIndexValue.java │ └── test │ ├── java │ └── com │ │ └── megatome │ │ └── j2d │ │ ├── DocsetCreatorTest.java │ │ └── support │ │ ├── DBSupportTest.java │ │ ├── DocSetSupportTest.java │ │ ├── ExpectedDataUtil.java │ │ └── JavadocSupportTest.java │ └── resources │ ├── blank.png │ ├── com │ └── megatome │ │ └── j2d │ │ └── support │ │ └── index-all-bad-tag.html │ └── not-javadoc │ └── hello.txt └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .gradle 3 | .idea 4 | build 5 | *.iml -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: groovy 2 | jdk: 3 | - oraclejdk8 4 | env: 5 | - TERM=dumb 6 | after_success: 7 | - ./gradlew jacocoRootReport coveralls 8 | notifications: 9 | slack: 10 | secure: alp5GJJqdBSH11BZ8jR9BB1TtYBi+p+F9UFHltLpGBJHv+AEHf+pBmY4vM0tulNeZpvOhDRkJ014RQpm7bLjvnoxyt60zCVDSpKLp3Pp7IrrgsgQ4oycwEwSExCzfehHxurP+eIi3I3RkdYvnxXkVobvaCzbGgikRM0qNTRPYEE= 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## [1.1.0](https://github.com/iamthechad/javadoc2dash/tree/1.1.0) (2017-05-11) 4 | [Full Changelog](https://github.com/iamthechad/javadoc2dash/compare/1.0.8...1.1.0) 5 | 6 | **Implemented enhancements:** 7 | 8 | - Improve parsing [\#11](https://github.com/iamthechad/javadoc2dash/pull/11) ([datalogics-kam](https://github.com/datalogics-kam)) 9 | 10 | **Fixed bugs:** 11 | 12 | - Better report bad tagging [\#10](https://github.com/iamthechad/javadoc2dash/pull/10) ([datalogics-kam](https://github.com/datalogics-kam)) 13 | 14 | ## [1.0.8](https://github.com/iamthechad/javadoc2dash/tree/1.0.8) (2016-08-16) 15 | [Full Changelog](https://github.com/iamthechad/javadoc2dash/compare/1.0.7...1.0.8) 16 | 17 | **Fixed bugs:** 18 | 19 | - Failed to create docset: Failed to index javadoc files [\#8](https://github.com/iamthechad/javadoc2dash/issues/8) 20 | - Fields are not supported [\#7](https://github.com/iamthechad/javadoc2dash/issues/7) 21 | - fix bug \#8: function properly even if some java classes use unicode class names [\#9](https://github.com/iamthechad/javadoc2dash/pull/9) ([emmanueltouzery](https://github.com/emmanueltouzery)) 22 | 23 | ## [1.0.7](https://github.com/iamthechad/javadoc2dash/tree/1.0.7) (2015-07-23) 24 | [Full Changelog](https://github.com/iamthechad/javadoc2dash/compare/1.0.6...1.0.7) 25 | 26 | ## [1.0.6](https://github.com/iamthechad/javadoc2dash/tree/1.0.6) (2015-07-23) 27 | [Full Changelog](https://github.com/iamthechad/javadoc2dash/compare/1.0.5...1.0.6) 28 | 29 | **Implemented enhancements:** 30 | 31 | - Support errors, fields, and methods [\#5](https://github.com/iamthechad/javadoc2dash/issues/5) 32 | 33 | **Fixed bugs:** 34 | 35 | - Incorrect documentation for CLI [\#6](https://github.com/iamthechad/javadoc2dash/issues/6) 36 | 37 | ## [1.0.5](https://github.com/iamthechad/javadoc2dash/tree/1.0.5) (2015-06-03) 38 | [Full Changelog](https://github.com/iamthechad/javadoc2dash/compare/1.0.4...1.0.5) 39 | 40 | **Implemented enhancements:** 41 | 42 | - Support creating Dash feed [\#2](https://github.com/iamthechad/javadoc2dash/issues/2) 43 | 44 | **Fixed bugs:** 45 | 46 | - Gradle plugin depends on wrong API resource [\#3](https://github.com/iamthechad/javadoc2dash/issues/3) 47 | 48 | ## [1.0.4](https://github.com/iamthechad/javadoc2dash/tree/1.0.4) (2015-05-05) 49 | [Full Changelog](https://github.com/iamthechad/javadoc2dash/compare/1.0.3...1.0.4) 50 | 51 | ## [1.0.3](https://github.com/iamthechad/javadoc2dash/tree/1.0.3) (2015-05-05) 52 | [Full Changelog](https://github.com/iamthechad/javadoc2dash/compare/1.0.2...1.0.3) 53 | 54 | **Fixed bugs:** 55 | 56 | - API does not properly detect non-Javadoc directories [\#1](https://github.com/iamthechad/javadoc2dash/issues/1) 57 | 58 | ## [1.0.2](https://github.com/iamthechad/javadoc2dash/tree/1.0.2) (2015-05-04) 59 | [Full Changelog](https://github.com/iamthechad/javadoc2dash/compare/v1.0.1...1.0.2) 60 | 61 | ## [v1.0.1](https://github.com/iamthechad/javadoc2dash/tree/v1.0.1) (2015-04-27) 62 | [Full Changelog](https://github.com/iamthechad/javadoc2dash/compare/v1.0.0...v1.0.1) 63 | 64 | ## [v1.0.0](https://github.com/iamthechad/javadoc2dash/tree/v1.0.0) (2015-04-27) 65 | 66 | 67 | \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2015 Megatome Technologies, LLC 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/iamthechad/javadoc2dash.svg)](https://travis-ci.org/iamthechad/javadoc2dash) 2 | [![Coverage Status](https://coveralls.io/repos/github/iamthechad/javadoc2dash/badge.svg?branch=master)](https://coveralls.io/github/iamthechad/javadoc2dash?branch=master) 3 | [![Download](https://api.bintray.com/packages/iamthechad/maven/javadoc2dash-api/images/download.svg) ](https://bintray.com/iamthechad/maven/javadoc2dash-api/_latestVersion) 4 | [![License](http://img.shields.io/:license-apache-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0.html) 5 | ![Maintenance](https://img.shields.io/maintenance/yes/2019) 6 | [![Badges](http://img.shields.io/:badges-5/5-ff6799.svg)](https://github.com/badges/badgerbadgerbadger) 7 | 8 | 9 | 10 | **Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* 11 | 12 | - [Javadoc2Dash - Build Dash docsets from Javadoc](#javadoc2dash---build-dash-docsets-from-javadoc) 13 | - [Gradle plugin](#gradle-plugin) 14 | - [Add the plugin to your project](#add-the-plugin-to-your-project) 15 | - [Specify settings](#specify-settings) 16 | - [Create the docset](#create-the-docset) 17 | - [Example](#example) 18 | - [Creating the docset feed](#creating-the-docset-feed) 19 | - [Example](#example-1) 20 | - [Using the API](#using-the-api) 21 | - [Add dependencies to your project](#add-dependencies-to-your-project) 22 | - [Use the API](#use-the-api) 23 | - [Using the CLI](#using-the-cli) 24 | - [Download the CLI](#download-the-cli) 25 | - [Running in a cloned repository](#running-in-a-cloned-repository) 26 | - [Running a release zip](#running-a-release-zip) 27 | - [Creating a docset](#creating-a-docset) 28 | - [Examples](#examples) 29 | 30 | 31 | 32 | # Javadoc2Dash - Build Dash docsets from Javadoc 33 | 34 | This project is based off of https://github.com/Kapeli/javadocset. This is a Java-based solution so that Dash docsets 35 | can be easily created from many environments, not just those that run OS X. 36 | 37 | There are three ways to create Dash-compatible docsets from Javadoc using this project: 38 | 39 | 1. Use the Gradle plugin 40 | 1. Use the API 41 | 1. Use the CLI 42 | 43 | # Gradle plugin 44 | 45 | ## Add the plugin to your project 46 | 47 | Build script snippet for use in all Gradle versions: 48 | 49 | 50 | buildscript { 51 | repositories { 52 | maven { 53 | url "https://plugins.gradle.org/m2/" 54 | } 55 | } 56 | dependencies { 57 | classpath "gradle.plugin.com.megatome.javadoc2dash:j2d-gradle:1.1.0" 58 | } 59 | } 60 | 61 | apply plugin: "com.megatome.javadoc2dash" 62 | 63 | Build script snippet for new, incubating, plugin mechanism introduced in Gradle 2.1: 64 | 65 | plugins { 66 | id "com.megatome.javadoc2dash" version "1.1.0" 67 | } 68 | 69 | ## Specify settings 70 | 71 | javadoc2dash { 72 | displayName = "My Cool Project" 73 | } 74 | 75 | If no settings are provided, the plugin tries to use sensible defaults. 76 | 77 | Setting Name | Type | Description | Default 78 | -------------|------|-------------|-------- 79 | `docsetName` | `String` | File name of the created docset | `project.name` 80 | `javadocRoot`| `File` | Location of the javadoc files | `${project.docsDir}/javadoc` 81 | `outputLocation`| `File` | Location to create the docset | `${project.buildDir}` 82 | `displayName`| `String` | Name displayed in Dash | `project.name` 83 | `keyword` | `String` | Keyword used for the docset in Dash | `project.name` 84 | `iconFile` | `File` | File to be used as the docset icon | `null` 85 | `javadocTask` | `String` | Name of the javadoc task that the `javadoc2dash` task will depend on | `javadoc` 86 | 87 | **Some Caveats:** 88 | 89 | * The `iconFile` should be a 32x32 PNG file, but the plugin does **not** verify this. 90 | * You should only need to set the `javadocTask` property when the task you use to create Javadoc is non-standard. For example, there may be a task called `allJavadoc` in a multi-module 91 | project to create an aggregated Javadoc. In this instance, `javadocTask` should be set to `allJavadoc` to ensure that the correct documentation is built before creating the docset. 92 | * This plugin applies the `java` plugin to the project it's run under. This means that in a multi-module project, a top level task named `javadoc` cannot be created to aggregate the 93 | subprojects' documentation. The `java` plugin creates a `javadoc` task, so a different name is required - perhaps `allJavadoc`. 94 | 95 | ## Create the docset 96 | 97 | Create the docset with the `javadoc2dash` task. 98 | 99 | ### Example 100 | 101 | apply plugin: 'java' 102 | 103 | sourceCompatibility = 1.5 104 | version = '1.0' 105 | 106 | buildscript { 107 | repositories { 108 | maven { 109 | url "https://plugins.gradle.org/m2/" 110 | } 111 | } 112 | dependencies { 113 | classpath "gradle.plugin.com.megatome.javadoc2dash:j2d-gradle:1.1.0" 114 | } 115 | } 116 | 117 | apply plugin: "com.megatome.javadoc2dash" 118 | 119 | javadoc2dash { 120 | docsetName = "MyProject" 121 | displayName = "My Awesome Project" 122 | keyword = "mp" 123 | } 124 | 125 | ## Creating the docset feed 126 | 127 | If you want to host your own docsets, you need to create a feed per the [Dash instructions](https://kapeli.com/docsets#dashdocsetfeed). 128 | 129 | Creating feeds uses the `javadoc2dashfeed` task. 130 | 131 | javadoc2dashfeed { 132 | feedLocations = [ "http://someserver.com/feeds", "http://someotherserver.com/feeds" ] 133 | } 134 | 135 | If no settings are provided, the plugin tries to use sensible defaults. 136 | 137 | Setting Name | Type | Description | Default 138 | -------------|------|-------------|-------- 139 | `feedName` | `String` | File name to use for feed XML file | `project.name` 140 | `feedVersion`| `String` | Version to use in feed XML file | `project.version` 141 | `feedLocations` | `List` | List of root URLs for hosting the docset | `null` 142 | 143 | ### Example 144 | 145 | apply plugin: 'java' 146 | 147 | sourceCompatibility = 1.5 148 | version = '1.0' 149 | 150 | buildscript { 151 | repositories { 152 | maven { 153 | url "https://plugins.gradle.org/m2/" 154 | } 155 | } 156 | dependencies { 157 | classpath "gradle.plugin.com.megatome.javadoc2dash:j2d-gradle:1.1.0" 158 | } 159 | } 160 | 161 | apply plugin: "com.megatome.javadoc2dash" 162 | 163 | javadoc2dash { 164 | docsetName = "MyProject" 165 | displayName = "My Awesome Project" 166 | keyword = "mp" 167 | } 168 | 169 | javadoc2dashfeed { 170 | feedName = "myproject" 171 | feedLocations = [ "http://someserver.com/feeds", "http://someotherserver.com/feeds" ] 172 | } 173 | 174 | This will generate a `feed` directory in the `javadoc2dash.outputLocation` directory. This directory will contain an XML file describing the feed 175 | (named `myproject.xml` in this case), and a compressed version of the docset (named `myproject.tgz` in this case). 176 | 177 | For this example, the XML file will look like this: 178 | 179 | 180 | 1.0 181 | http://someserver.com/feeds/myproject.tgz 182 | http://someotherserver.com/feeds/myproject.tgz 183 | 184 | 185 | The XML file should be copied to a location where it can be [shared with Dash users](https://kapeli.com/docsets#sharedocsetfeed), and the `tgz` file copied to the locations specified in `feedLocations`. 186 | 187 | # Using the API 188 | 189 | ## Add dependencies to your project 190 | 191 | For Gradle: 192 | 193 | repositories { 194 | jcenter() 195 | } 196 | 197 | dependencies { 198 | compile "com.megatome.javadoc2dash:javadoc2dash-api:1.1.0" 199 | } 200 | 201 | For Maven: 202 | 203 | 204 | com.megatome.javadoc2dash 205 | javadoc2dash-api 206 | 1.1.0 207 | 208 | 209 | ## Use the API 210 | 211 | DocsetCreator.Builder builder = new DocsetCreator.Builder(docsetName, javadocLocation); 212 | // Optionally - 213 | builder.displayName("Some Name").keyword("keyword"); 214 | DocsetCreator creator = builder.build(); 215 | 216 | try { 217 | creator.makeDocset(); 218 | } catch (BuilderException e) { 219 | // Something failed! 220 | } 221 | 222 | # Using the CLI 223 | 224 | ## Download the CLI 225 | 226 | Clone the project or grab the [latest release](https://github.com/iamthechad/javadoc2dash/releases). Running the utility will vary a bit depending on how you retrieve the project. 227 | 228 | ### Running in a cloned repository 229 | 230 | Running the CLI directly from a Gradle task is not currently supported. A distribution must be created via `gradlew :j2d-cli:distZip` to create a zip file containing everything needed to run. 231 | 232 | ### Running a release zip 233 | 234 | * Either download a release or create a distribution zip as outlined above. 235 | * Unzip the archive to a desired location. 236 | * Open a terminal or command prompt and navigate to the unzipped directory. 237 | * Navigate to the `bin` directory and run `./j2d-cli` (for \*NIX/OSX) or `j2d-cli.bat` (for Windows environments). 238 | * You should see a usage message. 239 | 240 | ## Creating a docset 241 | 242 | Docset creation requires at minimum two options: the name of the docset and the location of the Javadoc files to include in the docset. 243 | 244 | ./j2d-cli --name Sample --javadoc /some/path/to/apidoc 245 | 246 | This will create a docset named Sample in the current directory. Docset creation can be customized with optional arguments: 247 | 248 | * `--displayName`: Will set the name as shown in Dash. This is handy if you create a docset with name `SampleProject` but display name `Sample Project` instead. 249 | * This setting will default to the value of `--name` if omitted. 250 | * `--keyword`: Will set the keyword used to search in Dash. You could set the keyword for `SampleProject` to `sp`, for example. 251 | * This setting will default to the value of `--name` if omitted. 252 | * `--icon`: Specify an icon to be used for the docset. Should be a 32x32 PNG, but this tool **does not verify the file's content**. 253 | * No icon will be used if this is omitted. 254 | * `--out`: Specify a directory to create the docset in. 255 | * The docset will be created in the current directory if omitted. 256 | 257 | ### Examples 258 | 259 | Bare minimum: `j2d-cli --name Sample --javadoc /path/to/apidoc` 260 | 261 | Full options: `j2d-cli --name Sample --javadoc /path/to/apidoc --displayName "Awesome Sample API" --keyword asa --iconFile /path/to/icon.png --out /path/to/output` 262 | 263 | Abbreviated options. Most command-line options can be abbreviated. `j2d-cli -n Sample -j /path/to/apidoc -d "Awesome Sample API" -k asa -i /path/to/icon.png -o /path/to/output` 264 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | ext.projectVersion = '1.1.0' 2 | ext.projectLocation = "https://github.com/iamthechad/javadoc2dash" 3 | 4 | apply plugin: 'com.github.kt3k.coveralls' 5 | 6 | buildscript { 7 | repositories { 8 | jcenter() 9 | maven { 10 | url "https://plugins.gradle.org/m2/" 11 | } 12 | } 13 | dependencies { 14 | classpath 'org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.6.3' 15 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.0' 16 | classpath "com.gradle.publish:plugin-publish-plugin:0.9.5" 17 | } 18 | } 19 | 20 | allprojects { 21 | apply plugin: 'java' 22 | apply plugin: 'jacoco' 23 | 24 | repositories { 25 | jcenter() 26 | } 27 | } 28 | 29 | subprojects { 30 | sourceCompatibility = 1.7 31 | version = "$projectVersion" 32 | group = "com.megatome.javadoc2dash" 33 | 34 | def javaApiUrl = 'http://docs.oracle.com/javase/1.7.0/docs/api/' 35 | def groovyApiUrl = 'http://groovy-lang.org/gapi/' 36 | tasks.withType(Javadoc) { 37 | options.links(javaApiUrl, groovyApiUrl) 38 | } 39 | 40 | jacocoTestReport { 41 | reports { 42 | xml.enabled = true // coveralls plugin depends on xml format report 43 | html.enabled = true 44 | } 45 | } 46 | 47 | apply plugin: 'findbugs' 48 | findbugs { 49 | toolVersion = "3.0.0" 50 | // Don't worry about test classes 51 | sourceSets = [sourceSets.main] 52 | } 53 | 54 | tasks.withType(FindBugs) { 55 | reports { 56 | xml.enabled = false 57 | html.enabled = true 58 | } 59 | } 60 | } 61 | 62 | def publishedProjects = subprojects.findAll { 63 | !it.path.startsWith(':j2d-cli') && !it.path.startsWith(':j2d-sample') 64 | } 65 | 66 | task jacocoRootReport(type: JacocoReport) { 67 | dependsOn = subprojects.test 68 | additionalSourceDirs = files(publishedProjects.sourceSets.main.allSource.srcDirs) 69 | sourceDirectories = files(publishedProjects.sourceSets.main.allSource.srcDirs) 70 | classDirectories = files(publishedProjects.sourceSets.main.output) 71 | executionData = files(publishedProjects.jacocoTestReport.executionData) 72 | reports { 73 | html.enabled = true 74 | xml.enabled = true 75 | csv.enabled = false 76 | } 77 | onlyIf = { 78 | true 79 | } 80 | doFirst { 81 | executionData = files(executionData.findAll { 82 | it.exists() 83 | }) 84 | } 85 | } 86 | 87 | coveralls { 88 | sourceDirs = publishedProjects.sourceSets.main.allSource.srcDirs.flatten() 89 | jacocoReportPath = "${buildDir}/reports/jacoco/jacocoRootReport/jacocoRootReport.xml" 90 | } 91 | 92 | project(":j2d-cli") { 93 | apply plugin:'application' 94 | 95 | mainClassName = "com.megatome.j2d.Main" 96 | 97 | dependencies { 98 | compile project(":javadoc2dash-api") 99 | compile 'net.sf.jopt-simple:jopt-simple:4.8' 100 | } 101 | 102 | test { 103 | jacoco { 104 | excludes = ["com.megatome.j2d.Main"] 105 | } 106 | } 107 | } 108 | 109 | project(":j2d-gradle") { 110 | apply plugin: 'groovy' 111 | apply plugin: 'maven' 112 | apply plugin: "com.gradle.plugin-publish" 113 | 114 | archivesBaseName = 'javadoc2dash-plugin' 115 | 116 | dependencies { 117 | compile gradleApi() 118 | compile localGroovy() 119 | compile project(":javadoc2dash-api") 120 | 121 | testCompile group: 'junit', name: 'junit', version: '4.11' 122 | testCompile("org.spockframework:spock-core:1.0-groovy-2.3") { 123 | exclude group: "org.codehaus.groovy" 124 | } 125 | } 126 | 127 | uploadArchives { 128 | repositories { 129 | mavenDeployer { 130 | repository(url: "file://$projectDir/../../repo") 131 | } 132 | } 133 | } 134 | 135 | pluginBundle { 136 | website = "$projectLocation" 137 | vcsUrl = "$projectLocation" 138 | description = 'Create Dash docsets from Javadoc' 139 | tags = ['javadoc', 'dash'] 140 | 141 | plugins { 142 | javadoc2dashPlugin { 143 | id = 'com.megatome.javadoc2dash' 144 | displayName = 'Javadoc to Dash' 145 | } 146 | } 147 | } 148 | } 149 | 150 | project(":javadoc2dash-api") { 151 | apply plugin: 'maven' 152 | apply plugin: 'maven-publish' 153 | apply plugin: 'com.jfrog.bintray' 154 | 155 | archivesBaseName = 'javadoc2dash-api' 156 | 157 | dependencies { 158 | compile 'commons-io:commons-io:2.4' 159 | compile 'org.apache.commons:commons-lang3:3.3.2' 160 | compile 'org.xerial:sqlite-jdbc:3.8.7' 161 | compile 'org.jsoup:jsoup:1.8.2' 162 | compile "org.slf4j:slf4j-api:1.7.12" 163 | compile "org.slf4j:slf4j-simple:1.7.12" 164 | 165 | testCompile group: 'junit', name: 'junit', version: '4.11' 166 | testCompile 'org.hamcrest:hamcrest-all:1.3' 167 | testCompile 'com.googlecode.plist:dd-plist:1.16' 168 | } 169 | 170 | tasks.withType(Test) { task -> 171 | task.dependsOn ":j2d-sample:javadoc" 172 | task.dependsOn ":j2d-sample:javadocSplit" 173 | def sampleProject = findProject(":j2d-sample") 174 | systemProperties 'j2d-sample-javadoc': "${sampleProject.docsDir}/javadoc" 175 | systemProperties 'j2d-sample-javadoc-split': "${sampleProject.docsDir}/javadocSplit" 176 | } 177 | 178 | uploadArchives { 179 | repositories { 180 | mavenDeployer { 181 | repository(url: "file://$projectDir/../../repo") 182 | } 183 | } 184 | } 185 | 186 | def pomConfig = { 187 | scm { 188 | connection "scm:git:git@github.com:iamthechad/javadoc2dash.git" 189 | developerConnection "scm:git:git@github.com:iamthechad/javadoc2dash.git" 190 | url "$projectLocation" 191 | } 192 | issueManagement { 193 | system "Github Issue Tracker" 194 | url "$projectLocation/issues" 195 | } 196 | licenses { 197 | license { 198 | name "The Apache Software License, Version 2.0" 199 | url "http://www.apache.org/licenses/LICENSE-2.0.txt" 200 | distribution "repo" 201 | } 202 | } 203 | developers { 204 | developer { 205 | id "iamthechad" 206 | name "Chad Johnston" 207 | email "cjohnston@megatome.com" 208 | } 209 | } 210 | } 211 | 212 | publishing { 213 | publications { 214 | mavenJava(MavenPublication) { 215 | from components.java 216 | artifactId archivesBaseName 217 | artifact sourceJar 218 | artifact javadocJar 219 | 220 | pom.withXml { 221 | def root = asNode() 222 | root.appendNode('name', 'Javadoc to Dash API') 223 | root.appendNode('url', "$projectLocation") 224 | root.appendNode('description', 'API for creating Dash docsets from Javadoc') 225 | root.children().last() + pomConfig 226 | } 227 | } 228 | } 229 | } 230 | 231 | bintray { 232 | user = project.hasProperty('bintray_user') ? project.bintray_user : System.getenv('bintray_user') 233 | key = project.hasProperty('bintray_key') ? project.bintray_key : System.getenv('bintray_key') 234 | publications = ['mavenJava'] 235 | dryRun = false 236 | publish = false 237 | pkg { 238 | repo = 'maven' 239 | name = 'javadoc2dash-api' 240 | desc = 'API for creating Dash docsets from Javadoc' 241 | websiteUrl = "$projectLocation" 242 | issueTrackerUrl = "$projectLocation/issues" 243 | vcsUrl = projectLocation + ".git" 244 | licenses = ['Apache-2.0'] 245 | labels = ['javadoc', 'dash', 'api'] 246 | publicDownloadNumbers = true 247 | version { 248 | name = project.version 249 | vcsTag = projectVersion 250 | } 251 | } 252 | } 253 | 254 | task sourceJar(type: Jar) { 255 | from sourceSets.main.allSource 256 | classifier = 'sources' 257 | } 258 | task javadocJar(type: Jar, dependsOn: javadoc) { 259 | classifier = 'javadoc' 260 | from javadoc.destinationDir 261 | } 262 | } 263 | 264 | project(":j2d-sample") { 265 | javadoc { 266 | options.splitIndex = false 267 | } 268 | 269 | task javadocSplit(type: Javadoc) { 270 | source = sourceSets.main.allJava 271 | destinationDir = file("${project.docsDir}/javadocSplit") 272 | options.splitIndex = true 273 | } 274 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iamthechad/javadoc2dash/b35179e8621cbc99beb945ddeb96c4452669cc7c/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Apr 23 15:35:09 MDT 2015 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.2-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /j2d-cli/src/main/java/com/megatome/j2d/Main.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Megatome Technologies, LLC 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 | package com.megatome.j2d; 17 | 18 | import com.megatome.j2d.exception.BuilderException; 19 | import joptsimple.OptionException; 20 | import joptsimple.OptionParser; 21 | import joptsimple.OptionSet; 22 | import joptsimple.OptionSpec; 23 | import org.apache.commons.io.FileUtils; 24 | 25 | import java.io.File; 26 | import java.io.IOException; 27 | import java.util.Arrays; 28 | 29 | import static com.megatome.j2d.util.LogUtility.log; 30 | import static com.megatome.j2d.util.LogUtility.setVerbose; 31 | 32 | public class Main { 33 | public static void main(String... args) { 34 | final OptionParser parser = new OptionParser(); 35 | final OptionSpec docsetName = parser.accepts("name", "Name of the generated docset").withRequiredArg().ofType(String.class).required(); 36 | final OptionSpec javadocRoot = parser.accepts("javadoc", "Directory containing Javadoc to bundle in the docset.").withRequiredArg().ofType(File.class).required(); 37 | final OptionSpec outputLocation = parser.accepts("out", "Directory where the docset will be created.").withRequiredArg().ofType(File.class).defaultsTo(FileUtils.getFile(".")); 38 | final OptionSpec displayName = parser.accepts("displayName", "Name to show for the docset in Dash. Defaults to value of 'name' if not specified.").withRequiredArg().ofType(String.class); 39 | final OptionSpec keyword = parser.accepts("keyword", "Keyword to use for the docset in Dash. Defaults to value of 'name' if not specified.").withRequiredArg().ofType(String.class); 40 | final OptionSpec iconFile = parser.accepts("icon", "Icon file to use for the docset. No icon will be used if not specified.").withRequiredArg().ofType(File.class).describedAs("32x32 PNG"); 41 | final OptionSpec verbose = parser.accepts("verbose", "Show more information"); 42 | final OptionSpec help = parser.acceptsAll( Arrays.asList("h", "?"), "Show help" ).forHelp(); 43 | 44 | final OptionSet options; 45 | try { 46 | options = parser.parse(args); 47 | if (options.has(help)) { 48 | usage(parser); 49 | return; 50 | } 51 | } catch (OptionException e) { 52 | usage(parser); 53 | return; 54 | } 55 | 56 | setVerbose(options.has(verbose)); 57 | final DocsetCreator.Builder builder = new DocsetCreator.Builder(options.valueOf(docsetName), options.valueOf(javadocRoot)) 58 | .displayName(options.valueOf(displayName)) 59 | .displayName(options.valueOf(keyword)) 60 | .iconFile(options.valueOf(iconFile)) 61 | .outputDirectory(options.valueOf(outputLocation)); 62 | final DocsetCreator docsetCreator = builder.build(); 63 | try { 64 | docsetCreator.makeDocset(); 65 | } catch (BuilderException e) { 66 | log("Failed to create docset: {}", e.getMessage()); 67 | } 68 | } 69 | 70 | private static void usage(OptionParser parser) { 71 | try { 72 | parser.printHelpOn(System.out); 73 | } catch (IOException e) { 74 | e.printStackTrace(); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /j2d-gradle/src/main/groovy/com/megatome/javadoc2dash/Javadoc2DashPlugin.groovy: -------------------------------------------------------------------------------- 1 | package com.megatome.javadoc2dash 2 | 3 | import com.megatome.javadoc2dash.tasks.Javadoc2DashFeedTask 4 | import com.megatome.javadoc2dash.tasks.Javadoc2DashTask 5 | import org.gradle.api.Plugin 6 | import org.gradle.api.Project 7 | import org.gradle.api.plugins.JavaPlugin 8 | import org.gradle.api.tasks.bundling.Compression 9 | import org.gradle.api.tasks.bundling.Tar 10 | 11 | class Javadoc2DashPlugin implements Plugin { 12 | private static final String EXTENSION_NAME = "javadoc2dash" 13 | private static final String FEED_EXTENSION_NAME = "javadoc2dashfeed" 14 | private static final String FEED_LOCATION = "feed" 15 | 16 | @Override 17 | void apply(Project project) { 18 | project.plugins.apply(JavaPlugin) 19 | project.extensions.create(EXTENSION_NAME, Javadoc2DashPluginExtension, project) 20 | project.extensions.create(FEED_EXTENSION_NAME, Javadoc2DashFeedPluginExtension, project) 21 | addTasks(project) 22 | } 23 | 24 | private void addTasks(Project project) { 25 | def baseExtension = project.extensions.findByName(EXTENSION_NAME) 26 | project.task('javadoc2dash', type: Javadoc2DashTask) { 27 | dependsOn({ baseExtension.javadocTask }) 28 | conventionMapping.docsetName = { baseExtension.docsetName } 29 | conventionMapping.displayName = { baseExtension.displayName } 30 | conventionMapping.keyword = { baseExtension.keyword } 31 | conventionMapping.javadocRoot = { baseExtension.javadocRoot } 32 | conventionMapping.outputLocation = { baseExtension.outputLocation } 33 | conventionMapping.iconFile = { baseExtension.iconFile } 34 | } 35 | 36 | def feedExtension = project.extensions.findByName(FEED_EXTENSION_NAME) 37 | def feedLocation = project.file("${baseExtension.outputLocation}/${FEED_LOCATION}") 38 | 39 | project.task('javadoc2dashtar', type: Tar) { 40 | dependsOn({ 'javadoc2dash' }) 41 | description = 'Create a tarred version of the docset.'; 42 | group = 'Javadoc2Dash' 43 | conventionMapping.baseName = { feedExtension.feedName } 44 | version = null 45 | conventionMapping.extension = { "tgz" } 46 | conventionMapping.compression = { Compression.GZIP } 47 | from project.files("${baseExtension.outputLocation}") { 48 | exclude FEED_LOCATION 49 | } 50 | conventionMapping.destinationDir = { feedLocation } 51 | } 52 | 53 | project.task('javadoc2dashfeed', type: Javadoc2DashFeedTask) { 54 | dependsOn({ 'javadoc2dashtar' }) 55 | conventionMapping.feedName = { feedExtension.feedName } 56 | conventionMapping.docsetFile = { feedExtension.feedName + ".tgz" } 57 | conventionMapping.outputLocation = { feedLocation } 58 | conventionMapping.feedVersion = { feedExtension.feedVersion } 59 | conventionMapping.feedLocations = { feedExtension.feedLocations } 60 | } 61 | } 62 | } 63 | 64 | class Javadoc2DashPluginExtension { 65 | String docsetName 66 | File javadocRoot 67 | File outputLocation 68 | String displayName 69 | String keyword 70 | File iconFile 71 | String javadocTask 72 | 73 | Javadoc2DashPluginExtension(Project project) { 74 | docsetName = project.name 75 | displayName = project.name 76 | keyword = project.name 77 | javadocRoot = project.file("${project.docsDir}/javadoc") 78 | outputLocation = project.file("${project.buildDir}/javadoc2dash") 79 | iconFile = null 80 | javadocTask = "javadoc" 81 | } 82 | } 83 | 84 | class Javadoc2DashFeedPluginExtension { 85 | String feedName 86 | String feedVersion 87 | List feedLocations 88 | 89 | Javadoc2DashFeedPluginExtension(Project project) { 90 | feedName = project.name 91 | feedVersion = project.version 92 | feedLocations = null 93 | } 94 | } -------------------------------------------------------------------------------- /j2d-gradle/src/main/groovy/com/megatome/javadoc2dash/tasks/Javadoc2DashFeedTask.groovy: -------------------------------------------------------------------------------- 1 | package com.megatome.javadoc2dash.tasks 2 | 3 | import groovy.xml.MarkupBuilder 4 | import org.gradle.api.DefaultTask 5 | import org.gradle.api.GradleException 6 | import org.gradle.api.tasks.Input 7 | import org.gradle.api.tasks.TaskAction 8 | 9 | class Javadoc2DashFeedTask extends DefaultTask { 10 | @Input String feedName 11 | @Input String docsetFile 12 | @Input String feedVersion 13 | @Input List feedLocations 14 | @Input File outputLocation 15 | 16 | Javadoc2DashFeedTask() { 17 | this.description = 'Create a Dash feed from a docset'; 18 | group = 'Javadoc2Dash' 19 | } 20 | 21 | @TaskAction 22 | void start() { 23 | withExceptionHandling { 24 | if (!outputLocation.exists()) { 25 | project.mkdir(outputLocation) 26 | } 27 | 28 | def fw = new FileWriter(project.file("${outputLocation}/${feedName}.xml")) 29 | def xml = new MarkupBuilder(fw) 30 | 31 | xml.entry() { 32 | version(feedVersion) 33 | feedLocations.each { 34 | def feedUrl = it 35 | if (!it.endsWith('/')) { 36 | feedUrl += '/' 37 | } 38 | url(feedUrl + docsetFile) 39 | } 40 | } 41 | } 42 | } 43 | 44 | private static void withExceptionHandling(Closure c) { 45 | try { 46 | c() 47 | } catch (Exception e) { 48 | throw new GradleException(e.message); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /j2d-gradle/src/main/groovy/com/megatome/javadoc2dash/tasks/Javadoc2DashTask.groovy: -------------------------------------------------------------------------------- 1 | package com.megatome.javadoc2dash.tasks 2 | 3 | import com.megatome.j2d.DocsetCreator 4 | import org.gradle.api.DefaultTask 5 | import org.gradle.api.GradleException 6 | import org.gradle.api.tasks.Input 7 | import org.gradle.api.tasks.Optional; 8 | import org.gradle.api.tasks.TaskAction 9 | 10 | class Javadoc2DashTask extends DefaultTask { 11 | @Input String docsetName 12 | @Input File javadocRoot 13 | @Input File outputLocation 14 | @Input String displayName 15 | @Input String keyword 16 | 17 | @Input 18 | @Optional 19 | File iconFile 20 | 21 | Javadoc2DashTask() { 22 | this.description = 'Create a Dash docset from Javadoc'; 23 | group = 'Javadoc2Dash' 24 | } 25 | 26 | @TaskAction 27 | void start() { 28 | withExceptionHandling { 29 | DocsetCreator.Builder builder = new DocsetCreator.Builder(docsetName, javadocRoot) 30 | .displayName(displayName) 31 | .keyword(keyword) 32 | .outputDirectory(outputLocation) 33 | .iconFile(iconFile) 34 | DocsetCreator creator = builder.build() 35 | creator.makeDocset() 36 | } 37 | } 38 | 39 | private static void withExceptionHandling(Closure c) { 40 | try { 41 | c() 42 | } catch (Exception e) { 43 | throw new GradleException(e.message); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /j2d-gradle/src/main/resources/META-INF/gradle-plugins/com.megatome.javadoc2dash.properties: -------------------------------------------------------------------------------- 1 | implementation-class=com.megatome.javadoc2dash.Javadoc2DashPlugin -------------------------------------------------------------------------------- /j2d-gradle/src/test/groovy/com/megatome/javadoc2dash/Javadoc2DashPluginSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.megatome.javadoc2dash 2 | 3 | import org.gradle.api.Project 4 | import org.gradle.api.Task 5 | import org.gradle.api.plugins.JavaPlugin 6 | import org.gradle.testfixtures.ProjectBuilder 7 | import spock.lang.Specification 8 | 9 | class Javadoc2DashPluginSpec extends Specification { 10 | static final TASK_NAME = "javadoc2dash" 11 | static final EXTENSION_NAME = "javadoc2dash" 12 | static final PLUGIN_ID = 'com.megatome.javadoc2dash' 13 | 14 | Project project 15 | 16 | def setup() { 17 | ProjectBuilder builder = ProjectBuilder.builder() 18 | builder.withProjectDir(new File("src/test/resources/TestProject")) 19 | project = builder.build() 20 | } 21 | 22 | def "Apply plugin and use default extension values"() { 23 | expect: 24 | project.tasks.findByName(TASK_NAME) == null 25 | when: 26 | project.apply plugin: PLUGIN_ID 27 | then: 28 | project.plugins.hasPlugin(JavaPlugin) 29 | def baseExtension = project.extensions.findByName(EXTENSION_NAME) 30 | baseExtension != null 31 | Task j2dTask = project.tasks.findByName(TASK_NAME) 32 | j2dTask != null 33 | j2dTask.docsetName == project.name 34 | j2dTask.displayName == project.name 35 | j2dTask.keyword == project.name 36 | j2dTask.javadocRoot == project.file("${project.docsDir}/javadoc") 37 | j2dTask.outputLocation == project.file("${project.buildDir}/javadoc2dash") 38 | j2dTask.iconFile == null 39 | baseExtension.javadocTask == "javadoc" 40 | } 41 | 42 | def "Apply plugin and set all extension values"() { 43 | expect: 44 | project.tasks.findByName(TASK_NAME) == null 45 | when: 46 | project.apply plugin: PLUGIN_ID 47 | 48 | project.javadoc2dash { 49 | docsetName = "Project Name" 50 | displayName = "Display Name" 51 | keyword = "Keyword" 52 | javadocRoot = project.file("${project.docsDir}/docs") 53 | outputLocation = project.file("${project.buildDir}/docsets") 54 | iconFile = project.file("icon.png") 55 | javadocTask = "allJavadoc" 56 | } 57 | then: 58 | project.plugins.hasPlugin(JavaPlugin) 59 | def baseExtension = project.extensions.findByName(EXTENSION_NAME) 60 | baseExtension != null 61 | Task j2dTask = project.tasks.findByName(TASK_NAME) 62 | j2dTask != null 63 | j2dTask.docsetName == "Project Name" 64 | j2dTask.displayName == "Display Name" 65 | j2dTask.keyword == "Keyword" 66 | j2dTask.javadocRoot == project.file("${project.docsDir}/docs") 67 | j2dTask.outputLocation == project.file("${project.buildDir}/docsets") 68 | j2dTask.iconFile == project.file("icon.png") 69 | baseExtension.javadocTask == "allJavadoc" 70 | } 71 | 72 | def "Apply plugin and set some extension values"() { 73 | expect: 74 | project.tasks.findByName(TASK_NAME) == null 75 | when: 76 | project.apply plugin: PLUGIN_ID 77 | 78 | project.javadoc2dash { 79 | displayName = "Display Name" 80 | keyword = "Keyword" 81 | outputLocation = project.file("${project.buildDir}/docsets") 82 | } 83 | then: 84 | project.plugins.hasPlugin(JavaPlugin) 85 | project.extensions.findByName(EXTENSION_NAME) != null 86 | Task j2dTask = project.tasks.findByName(TASK_NAME) 87 | j2dTask != null 88 | j2dTask.docsetName == project.name 89 | j2dTask.displayName == "Display Name" 90 | j2dTask.keyword == "Keyword" 91 | j2dTask.javadocRoot == project.file("${project.docsDir}/javadoc") 92 | j2dTask.outputLocation == project.file("${project.buildDir}/docsets") 93 | j2dTask.iconFile == null 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /j2d-gradle/src/test/groovy/com/megatome/javadoc2dash/tasks/Javadoc2DashTaskSpec.groovy: -------------------------------------------------------------------------------- 1 | package com.megatome.javadoc2dash.tasks 2 | 3 | import org.gradle.api.GradleException 4 | import org.gradle.api.Project 5 | import org.gradle.api.Task 6 | import org.gradle.testfixtures.ProjectBuilder 7 | import spock.lang.Specification 8 | 9 | class Javadoc2DashTaskSpec extends Specification{ 10 | static final TASK_NAME = "javadoc2dash" 11 | static final PLUGIN_ID = 'com.megatome.javadoc2dash' 12 | 13 | Project project 14 | 15 | def setup() { 16 | ProjectBuilder builder = ProjectBuilder.builder() 17 | builder.withProjectDir(new File("src/test/resources/TestProject")) 18 | project = builder.build() 19 | } 20 | 21 | def "Execute task with bad information"() { 22 | expect: 23 | project.tasks.findByName(TASK_NAME) == null 24 | when: 25 | project.apply plugin: PLUGIN_ID 26 | project.javadoc2dash { 27 | docsetName = null 28 | javadocRoot = null 29 | } 30 | Task j2dTask = project.tasks.findByName(TASK_NAME) 31 | j2dTask.start() 32 | then: 33 | thrown(GradleException) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /j2d-gradle/src/test/resources/TestProject/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iamthechad/javadoc2dash/b35179e8621cbc99beb945ddeb96c4452669cc7c/j2d-gradle/src/test/resources/TestProject/icon.png -------------------------------------------------------------------------------- /j2d-sample/src/main/java/com/megatome/j2d/sample/annotation/SampleAnnotation.java: -------------------------------------------------------------------------------- 1 | package com.megatome.j2d.sample.annotation; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.Target; 6 | 7 | import static java.lang.annotation.ElementType.METHOD; 8 | import static java.lang.annotation.RetentionPolicy.CLASS; 9 | 10 | /** 11 | * Sample annotation 12 | */ 13 | @Target(METHOD) 14 | @Retention(CLASS) 15 | @Documented 16 | public @interface SampleAnnotation { 17 | /** 18 | * Sample value. 19 | * 20 | * @return Description 21 | */ 22 | String value() default ""; 23 | } 24 | -------------------------------------------------------------------------------- /j2d-sample/src/main/java/com/megatome/j2d/sample/clazz/SampleClass.java: -------------------------------------------------------------------------------- 1 | package com.megatome.j2d.sample.clazz; 2 | 3 | /** 4 | * Sample class 5 | */ 6 | public class SampleClass { 7 | /** 8 | * Sample field 9 | */ 10 | public static String FOO = "FOO"; 11 | 12 | /** 13 | * Sample static method 14 | */ 15 | public static void staticMethod() { 16 | throw new UnsupportedOperationException(); 17 | } 18 | 19 | /** 20 | * Sample method 21 | */ 22 | public void method() { 23 | throw new UnsupportedOperationException(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /j2d-sample/src/main/java/com/megatome/j2d/sample/enums/SampleEnum.java: -------------------------------------------------------------------------------- 1 | package com.megatome.j2d.sample.enums; 2 | 3 | /** 4 | * Sample Enum 5 | */ 6 | public enum SampleEnum { 7 | ONE, TWO, THREE 8 | } 9 | -------------------------------------------------------------------------------- /j2d-sample/src/main/java/com/megatome/j2d/sample/error/SampleError.java: -------------------------------------------------------------------------------- 1 | package com.megatome.j2d.sample.error; 2 | 3 | /** 4 | * Sample Error 5 | */ 6 | public class SampleError extends Error { 7 | /** 8 | * Sample ctor 9 | * @param message Message 10 | */ 11 | public SampleError(String message) { 12 | super(message); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /j2d-sample/src/main/java/com/megatome/j2d/sample/exception/SampleException.java: -------------------------------------------------------------------------------- 1 | package com.megatome.j2d.sample.exception; 2 | 3 | /** 4 | * Sample exception 5 | */ 6 | public class SampleException extends Exception { 7 | /** 8 | * Sample ctor 9 | */ 10 | public SampleException() { 11 | } 12 | 13 | /** 14 | * Sample ctor 15 | * {@inheritDoc} 16 | */ 17 | public SampleException(String message) { 18 | super(message); 19 | } 20 | 21 | /** 22 | * Sample ctor 23 | * {@inheritDoc} 24 | */ 25 | public SampleException(String message, Throwable cause) { 26 | super(message, cause); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /j2d-sample/src/main/java/com/megatome/j2d/sample/iface/SampleInterface.java: -------------------------------------------------------------------------------- 1 | package com.megatome.j2d.sample.iface; 2 | 3 | /** 4 | * Sample interface 5 | */ 6 | public interface SampleInterface { 7 | /** 8 | * Sample interface method 9 | */ 10 | void interfaceMethod(); 11 | } 12 | -------------------------------------------------------------------------------- /javadoc2dash-api/gradle.properties: -------------------------------------------------------------------------------- 1 | bintray_user = invalid 2 | bintray_key = ABC123 -------------------------------------------------------------------------------- /javadoc2dash-api/src/main/java/com/megatome/j2d/DocsetCreator.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Megatome Technologies, LLC 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 | package com.megatome.j2d; 17 | 18 | import com.megatome.j2d.exception.BuilderException; 19 | import com.megatome.j2d.util.IndexData; 20 | import org.slf4j.Logger; 21 | 22 | import java.io.File; 23 | 24 | import static com.megatome.j2d.support.DBSupport.createIndex; 25 | import static com.megatome.j2d.support.DocSetSupport.*; 26 | import static com.megatome.j2d.support.JavadocSupport.findIndexFile; 27 | import static com.megatome.j2d.support.JavadocSupport.findSearchIndexValues; 28 | import static com.megatome.j2d.util.LogUtility.log; 29 | import static com.megatome.j2d.util.LogUtility.setLogger; 30 | import static org.apache.commons.io.FilenameUtils.concat; 31 | 32 | /** 33 | * Class responsible for creating the docset. 34 | */ 35 | public class DocsetCreator { 36 | private final String docsetName; 37 | private final String displayName; 38 | private final String keyword; 39 | private final File iconFilePath; 40 | private final File javadocRoot; 41 | private final File outputDirectory; 42 | 43 | /** 44 | * Builder for specifying options used in docset creation 45 | */ 46 | public static class Builder { 47 | private final String docsetName; 48 | private final File javadocRoot; 49 | 50 | private String displayName; 51 | private String keyword; 52 | private File iconFilePath = null; 53 | private File outputDirectory = new File("."); 54 | 55 | /** 56 | * Ctor 57 | * @param docsetName File name of docset to create 58 | * @param javadocRoot Root directory of the Javadoc to create the docset from 59 | */ 60 | public Builder(String docsetName, File javadocRoot) { 61 | if (null == docsetName || docsetName.isEmpty()) { 62 | throw new IllegalArgumentException("The docsetName must be specified"); 63 | } 64 | if (null == javadocRoot) { 65 | throw new IllegalArgumentException("The javadocRoot must be specified"); 66 | } 67 | this.docsetName = docsetName; 68 | this.javadocRoot = javadocRoot; 69 | this.displayName = docsetName; 70 | this.keyword = docsetName; 71 | } 72 | 73 | /** 74 | * Specify the display name 75 | * @param displayName Name to display in Dash. Defaults to docsetName if unspecified 76 | * @return Builder instance 77 | */ 78 | public Builder displayName(String displayName) { 79 | if (null != displayName && !displayName.isEmpty()) { 80 | this.displayName = displayName; 81 | } 82 | return this; 83 | } 84 | 85 | /** 86 | * Specify the keyword 87 | * @param keyword Keyword to associate this docset with. Defaults to docsetName is unspecified 88 | * @return Builder instance 89 | */ 90 | public Builder keyword(String keyword) { 91 | if (null != keyword && !keyword.isEmpty()) { 92 | this.keyword = keyword; 93 | } 94 | return this; 95 | } 96 | 97 | /** 98 | * Specify the output directory 99 | * @param outputDirectory Location for the created docset 100 | * @return Builder instance 101 | */ 102 | public Builder outputDirectory(File outputDirectory) { 103 | if (null != outputDirectory) { 104 | this.outputDirectory = outputDirectory; 105 | } 106 | return this; 107 | } 108 | 109 | /** 110 | * Specify the iconf ile 111 | * @param iconFile Path to an icon to include in the docset. Should be a 32x32 PNG. No icon will be used if this is unspecified. 112 | * @return Builder instance 113 | */ 114 | public Builder iconFile(File iconFile) { 115 | if (null != iconFile) { 116 | this.iconFilePath = iconFile; 117 | } 118 | return this; 119 | } 120 | 121 | public DocsetCreator build() { 122 | return new DocsetCreator(this); 123 | } 124 | } 125 | 126 | private DocsetCreator(Builder builder) { 127 | this.docsetName = builder.docsetName; 128 | this.displayName = builder.displayName; 129 | this.keyword = builder.keyword; 130 | this.iconFilePath = builder.iconFilePath; 131 | this.javadocRoot = builder.javadocRoot; 132 | this.outputDirectory = builder.outputDirectory; 133 | } 134 | 135 | /** 136 | * Build the docset. 137 | * @param logger Optional logger to be used during docset creation. If not specified all messages will be directed 138 | * to the console. 139 | * @throws BuilderException If an error occurs creating the docset 140 | */ 141 | public void makeDocset(Logger logger) throws BuilderException { 142 | setLogger(logger); 143 | final String docsetRoot = concat(outputDirectory.getAbsolutePath(), docsetName); 144 | createDocSetStructure(docsetRoot); 145 | copyIconFile(iconFilePath, docsetRoot); 146 | final IndexData indexData = findIndexFile(javadocRoot); 147 | copyFiles(javadocRoot, docsetRoot); 148 | createPList(docsetName, displayName, keyword, indexData.getDocsetIndexFile(), docsetRoot); 149 | createIndex(findSearchIndexValues(indexData.getFilesToIndex()), getDBDir(docsetRoot)); 150 | log("Finished creating docset: {}", docsetRoot); 151 | } 152 | 153 | /** 154 | * Build the docset. 155 | * @throws BuilderException If an error occurs creating the docset 156 | */ 157 | public void makeDocset() throws BuilderException { 158 | makeDocset(null); 159 | } 160 | 161 | /** 162 | * Get the docset name 163 | * @return Docset name 164 | */ 165 | public String getDocsetName() { 166 | return docsetName; 167 | } 168 | 169 | /** 170 | * Get the display name 171 | * @return Display name 172 | */ 173 | public String getDisplayName() { 174 | return displayName; 175 | } 176 | 177 | /** 178 | * Get the keyword 179 | * @return Keyword 180 | */ 181 | public String getKeyword() { 182 | return keyword; 183 | } 184 | 185 | /** 186 | * Get the icon file path 187 | * @return Icon file path 188 | */ 189 | public File getIconFilePath() { 190 | return iconFilePath; 191 | } 192 | 193 | /** 194 | * Get the Javadoc root directory 195 | * @return Javadoc directory 196 | */ 197 | public File getJavadocRoot() { 198 | return javadocRoot; 199 | } 200 | 201 | /** 202 | * Get the output directory 203 | * @return Output directory 204 | */ 205 | public File getOutputDirectory() { 206 | return outputDirectory; 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /javadoc2dash-api/src/main/java/com/megatome/j2d/exception/BuilderException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Megatome Technologies, LLC 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 | package com.megatome.j2d.exception; 17 | 18 | /** 19 | * Simple named exception to capture docset build errors. 20 | */ 21 | public class BuilderException extends Exception { 22 | /** 23 | * {@inheritDoc} 24 | */ 25 | public BuilderException(String message) { 26 | super(message); 27 | } 28 | 29 | /** 30 | * {@inheritDoc} 31 | */ 32 | public BuilderException(String message, Throwable cause) { 33 | super(message, cause); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /javadoc2dash-api/src/main/java/com/megatome/j2d/support/DBSupport.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Megatome Technologies, LLC 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 | package com.megatome.j2d.support; 17 | 18 | import com.megatome.j2d.exception.BuilderException; 19 | import com.megatome.j2d.util.SearchIndexValue; 20 | 21 | import java.sql.*; 22 | import java.util.List; 23 | 24 | import static com.megatome.j2d.util.LogUtility.logVerbose; 25 | import static org.apache.commons.io.FilenameUtils.concat; 26 | 27 | /** 28 | * Utility class for SQLite DB manipulation of the docset. 29 | */ 30 | public final class DBSupport { 31 | private static final String DB_FILE = "docSet.dsidx"; 32 | 33 | private DBSupport() {} 34 | 35 | private static final String CREATE_INDEX_SQL = "CREATE TABLE searchIndex(id INTEGER PRIMARY KEY, name TEXT, type TEXT, path TEXT)"; 36 | private static final String INSERT_INDEX_SQL = "INSERT INTO searchIndex(name, type, path) VALUES (?, ?, ?)"; 37 | 38 | /** 39 | * Create a new DB file, and insert all of the specified index values. 40 | * @param indexValues Index values to insert into the DB 41 | * @param dbFileDir Directory to create the DB file in. 42 | * @throws BuilderException 43 | */ 44 | public static void createIndex(List indexValues, String dbFileDir) throws BuilderException { 45 | 46 | final String dbFile = concat(dbFileDir, DB_FILE); 47 | // Create DB file 48 | try (final Connection connection = DriverManager.getConnection("jdbc:sqlite:" + dbFile); 49 | final Statement stmt = connection.createStatement()){ 50 | stmt.execute(CREATE_INDEX_SQL); 51 | // Update DB 52 | try (final PreparedStatement pst = connection.prepareStatement(INSERT_INDEX_SQL)) { 53 | for (final SearchIndexValue value : indexValues) { 54 | pst.setString(1, value.getName()); 55 | pst.setString(2, value.getType().getTypeName()); 56 | pst.setString(3, value.getPath()); 57 | pst.execute(); 58 | } 59 | } 60 | } catch (SQLException e) { 61 | throw new BuilderException("Error writing to SQLite DB", e); 62 | } 63 | logVerbose("Created the SQLite search index"); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /javadoc2dash-api/src/main/java/com/megatome/j2d/support/DocSetSupport.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Megatome Technologies, LLC 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 | package com.megatome.j2d.support; 17 | 18 | import com.megatome.j2d.exception.BuilderException; 19 | 20 | import java.io.File; 21 | import java.io.IOException; 22 | 23 | import static org.apache.commons.io.FileUtils.*; 24 | import static org.apache.commons.io.FilenameUtils.concat; 25 | import static com.megatome.j2d.util.LogUtility.*; 26 | 27 | /** 28 | * Utility class for operations on the docset. 29 | */ 30 | public class DocSetSupport { 31 | private DocSetSupport() {} 32 | 33 | static final String CONTENTS = "Contents"; 34 | static final String RESOURCES = "Resources"; 35 | static final String DOCUMENTS = "Documents"; 36 | 37 | private static final String PLIST_FILE = "Info.plist"; 38 | private static final String ICON_FILE = "icon.png"; 39 | private static final String DOCSET_SUFFIX = ".docset"; 40 | 41 | /** 42 | * Create the docset package. Will delete an existing docset if one already exists at the specified location. 43 | * @param docsetDir Location of the docset to create 44 | * @throws BuilderException 45 | */ 46 | public static void createDocSetStructure(String docsetDir) throws BuilderException { 47 | final File docsetRootDir = getFile(getDocsetRoot(docsetDir)); 48 | // Create dir 49 | if (docsetRootDir.exists()) { 50 | logVerbose("A docset named {} already exists. Trying to remove.", docsetDir); 51 | try { 52 | deleteDirectory(docsetRootDir); 53 | } catch (IOException e) { 54 | throw new BuilderException("Failed to delete existing docset.", e); 55 | } 56 | } 57 | 58 | final File documentsDir = getFile(docsetRootDir, CONTENTS, RESOURCES, DOCUMENTS); 59 | try { 60 | forceMkdir(documentsDir); 61 | } catch (IOException e) { 62 | throw new BuilderException("Failed to create new docset directory.", e); 63 | } 64 | logVerbose("Docset directory structure created"); 65 | } 66 | 67 | /** 68 | * Copy an icon file to the docset. If the file path is not specified, no error happens. 69 | * @param iconFile File to copy as the docset icon. 70 | * @param docsetDir Directory of the docset 71 | * @throws BuilderException 72 | */ 73 | public static void copyIconFile(File iconFile, String docsetDir) throws BuilderException { 74 | if (null == iconFile) { 75 | return; 76 | } 77 | 78 | try { 79 | copyFile(iconFile, getFile(getDocsetRoot(docsetDir), ICON_FILE)); 80 | logVerbose("Icon file copied"); 81 | } catch (IOException e) { 82 | throw new BuilderException("Failed to copy icon file to docset", e); 83 | } 84 | } 85 | 86 | /** 87 | * Copy all files and folders from a source location into the docset. 88 | * @param sourceDir Source directory to copy from 89 | * @param docsetDir Directory of the docset 90 | * @throws BuilderException 91 | */ 92 | public static void copyFiles(final String sourceDir, String docsetDir) throws BuilderException { 93 | copyFiles(getFile(sourceDir), docsetDir); 94 | } 95 | 96 | /** 97 | * Copy all files and folders from a source location into the docset. 98 | * @param sourceDir Source directory to copy from 99 | * @param docsetDir Directory of the docset 100 | * @throws BuilderException 101 | */ 102 | public static void copyFiles(final File sourceDir, String docsetDir) throws BuilderException { 103 | try { 104 | copyDirectory(sourceDir, getFile(getDocsetRoot(docsetDir), CONTENTS, RESOURCES, DOCUMENTS)); 105 | logVerbose("Copied javadoc files into docset"); 106 | } catch (IOException e) { 107 | throw new BuilderException("Could not copy files into the docset", e); 108 | } 109 | } 110 | 111 | /** 112 | * Create the plist file in the docset. 113 | * @param bundleIdentifier Bundle identifier of the docset 114 | * @param displayName Name used to display the docset in Dash 115 | * @param keyword Keyword used for the docset in Dash 116 | * @param indexFile The file to be used as the docset index 117 | * @param docsetDir Directory of the docset 118 | * @throws BuilderException 119 | */ 120 | public static void createPList(String bundleIdentifier, String displayName, String keyword, String indexFile, String docsetDir) throws BuilderException { 121 | final String plist = String.format("CFBundleIdentifier%sCFBundleName%sDocSetPlatformFamily%sdashIndexFilePath%sDashDocSetFamilyjavaisDashDocset", 122 | bundleIdentifier, displayName, keyword, indexFile); 123 | // CFBundleIdentifier = ? 124 | // CFBundleName = Display Name 125 | // DocSetPlatformFamily = keyword 126 | try { 127 | write(getFile(getDocsetRoot(docsetDir), CONTENTS, PLIST_FILE), plist); 128 | logVerbose("Created the plist file in the docset"); 129 | } catch (IOException e) { 130 | throw new BuilderException("Failed to write plist file into docset", e); 131 | } 132 | } 133 | 134 | /** 135 | * Get the directory within the docset that holds the SQLite DB. 136 | * @param docsetDir Directory of the docset 137 | * @return Directory 138 | */ 139 | public static String getDBDir(String docsetDir) { 140 | return concat(concat(getDocsetRoot(docsetDir), CONTENTS), RESOURCES); 141 | } 142 | 143 | static String getDocsetRoot(String docsetDir) { 144 | return docsetDir + DOCSET_SUFFIX; 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /javadoc2dash-api/src/main/java/com/megatome/j2d/support/JavadocSupport.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Megatome Technologies, LLC 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 | package com.megatome.j2d.support; 17 | 18 | import com.megatome.j2d.exception.BuilderException; 19 | import com.megatome.j2d.util.IndexData; 20 | import com.megatome.j2d.util.SearchIndexValue; 21 | import org.apache.commons.io.FileUtils; 22 | import org.jsoup.Jsoup; 23 | import org.jsoup.nodes.Document; 24 | import org.jsoup.nodes.Element; 25 | import org.jsoup.select.Elements; 26 | 27 | import java.io.File; 28 | import java.io.IOException; 29 | import java.io.UnsupportedEncodingException; 30 | import java.net.URLDecoder; 31 | import java.util.ArrayList; 32 | import java.util.Arrays; 33 | import java.util.List; 34 | import java.util.regex.Pattern; 35 | 36 | import static com.megatome.j2d.util.LogUtility.logVerbose; 37 | import static org.apache.commons.io.FileUtils.getFile; 38 | import static org.apache.commons.lang3.StringUtils.containsIgnoreCase; 39 | import static org.apache.commons.lang3.StringUtils.equalsIgnoreCase; 40 | 41 | /** 42 | * Utility class to support Javadoc related docset tasks. 43 | */ 44 | public final class JavadocSupport { 45 | private static final Pattern parentPattern = Pattern.compile("span|code|i|b", Pattern.CASE_INSENSITIVE); 46 | private static final List extraIndexingTypes = Arrays.asList(MatchType.CLASS, MatchType.INTERFACE, MatchType.ENUM, MatchType.EXCEPTION, MatchType.ERROR); 47 | 48 | private JavadocSupport() {} 49 | 50 | /** 51 | * Find the file to be used as the docset index and locate all Javadoc files to be indexed. 52 | * @param javadocDir Directory where the Javadoc is located 53 | * @return IndexData object 54 | * @throws BuilderException 55 | * @see IndexData 56 | */ 57 | public static IndexData findIndexFile(File javadocDir) throws BuilderException { 58 | final IndexData indexData = new IndexData(); 59 | if (!javadocDir.exists() || !javadocDir.isDirectory()) { 60 | throw new BuilderException(String.format("%s does not exist, or is not a directory", javadocDir.getAbsolutePath())); 61 | } 62 | 63 | logVerbose("Looking for javadoc files"); 64 | 65 | String docsetIndexFile = "overview-summary.html"; 66 | 67 | if (!getFile(javadocDir, docsetIndexFile).exists()) { 68 | docsetIndexFile = null; 69 | } 70 | 71 | final File indexFilesDir = getFile(javadocDir, "index-files"); 72 | if (indexFilesDir.exists() && indexFilesDir.isDirectory()) { 73 | docsetIndexFile = (docsetIndexFile != null) ? docsetIndexFile : "index-1.html"; 74 | for (File f : FileUtils.listFiles(indexFilesDir, new String[]{"html"}, false)) { 75 | if (f.getName().startsWith("index-")) { 76 | indexData.addFileToIndex(f); 77 | } 78 | } 79 | } else if (getFile(javadocDir, "index-all.html").exists()){ 80 | docsetIndexFile = (docsetIndexFile != null) ? docsetIndexFile : "index-all.html"; 81 | indexData.addFileToIndex(getFile(javadocDir, "index-all.html")); 82 | } 83 | 84 | if (!indexData.hasFilesToIndex()) { 85 | throw new BuilderException(String.format("Did not find any javadoc files. Make sure that %s is a directory containing javadoc", javadocDir.getAbsolutePath())); 86 | } 87 | 88 | indexData.setDocsetIndexFile(docsetIndexFile); 89 | logVerbose("Found javadoc files"); 90 | return indexData; 91 | } 92 | 93 | /** 94 | * Find all values to be indexed within the specified list of files. 95 | * @param filesToIndex List of Javadoc files to parse 96 | * @return List of relevant values to be indexed in the docset 97 | * @throws BuilderException 98 | */ 99 | public static List findSearchIndexValues(List filesToIndex) throws BuilderException { 100 | final List values = new ArrayList<>(); 101 | for (final File f : filesToIndex) { 102 | final List indexValues = indexFile(f); 103 | values.addAll(indexValues); 104 | } 105 | return values; 106 | } 107 | 108 | private static List indexFile(File f) throws BuilderException { 109 | final List values = new ArrayList<>(); 110 | final Elements elements = loadAndFindLinks(f); 111 | for (final Element e : elements) { 112 | Element parent = e.parent(); 113 | if (!parent.child(0).equals(e)) { 114 | continue; 115 | } 116 | String parentTagName = parent.tagName(); 117 | if (parentPattern.matcher(parentTagName).matches()) { 118 | parent = parent.parent(); 119 | parentTagName = parent.tagName(); 120 | if (!parent.child(0).equals(e.parent())) { 121 | continue; 122 | } 123 | } 124 | if (!containsIgnoreCase(parentTagName, "dt")) { 125 | continue; 126 | } 127 | final String text = parent.text(); 128 | final String name = e.text(); 129 | final String className = parent.className(); 130 | 131 | final MatchType type = getMatchingType(text, className); 132 | 133 | if (null == type) { 134 | System.err.println(String.format("Unknown type found. Please submit a bug report. (Text: %s, Name: %s, className: %s)", text, name, className)); 135 | continue; 136 | } 137 | try { 138 | final String linkPath = URLDecoder.decode(e.attr("href"), "UTF-8"); 139 | 140 | if (name.isEmpty() || linkPath.isEmpty()) { 141 | System.err.println(String.format("Something went wrong with parsing a link, possibly unescaped tags in Javadoc. (Name: %s, Type: %s, Link: %s)", name, type, linkPath)); 142 | if (values.size() > 0) { 143 | final SearchIndexValue last = values.get(values.size() - 1); 144 | System.err.println(String.format("Most recently parsed value was: (Name: %s, Type: %s, Path: %s)", last.getName(), last.getType(), last.getPath())); 145 | } 146 | continue; 147 | } 148 | values.add(new SearchIndexValue(name, type, linkPath)); 149 | } catch (UnsupportedEncodingException ex) { 150 | throw new BuilderException("Error decoding a link", ex); 151 | } 152 | } 153 | return values; 154 | } 155 | 156 | private static Elements loadAndFindLinks(final File f) throws BuilderException { 157 | try { 158 | final Document doc = Jsoup.parse(f, "UTF-8"); 159 | return doc.select("a"); 160 | } catch (IOException e) { 161 | throw new BuilderException("Failed to index javadoc files", e); 162 | } 163 | } 164 | 165 | private static MatchType getMatchingType(String text, String className) { 166 | for (final MatchType matchType : MatchType.values()) { 167 | if (matchType.matches(text, className)) { 168 | return matchType; 169 | } 170 | } 171 | return null; 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /javadoc2dash-api/src/main/java/com/megatome/j2d/support/MatchType.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Megatome Technologies, LLC 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 | package com.megatome.j2d.support; 17 | 18 | import java.util.ArrayList; 19 | import java.util.Collections; 20 | import java.util.List; 21 | 22 | import static org.apache.commons.lang3.StringUtils.containsIgnoreCase; 23 | 24 | /** 25 | * Enumeration for matching types from parsed Javadoc files 26 | */ 27 | public enum MatchType { 28 | CLASS("Class", "class", "Class in", "- class"), 29 | STATIC_METHOD("Method", "method", "Static method in"), 30 | FIELD("Field", "field", "Static variable in", "Field in", "field.summary"), 31 | CONSTRUCTOR("Constructor", "constructor", "Constructor"), 32 | METHOD("Method", null, "Method in", "method.summary"), 33 | VARIABLE("Field", null, "Variable in"), 34 | INTERFACE("Interface", "interface", "Interface in", "- interface"), 35 | EXCEPTION("Exception", "exception", "Exception in", "- exception"), 36 | ERROR("Error", "error", "Error in", "- error"), 37 | ENUM("Enum", "enum", "Enum in", "- enum"), 38 | TRAIT("Trait", null, "Trait in"), 39 | NOTATION("Notation", "annotation", "Annotation Type"), 40 | PACKAGE("Package", "package", "package"); 41 | 42 | private String typeName; 43 | private List matchingText = new ArrayList<>(); 44 | private String classSuffix; 45 | 46 | MatchType(String typeName, String classSuffix, String... textMatches) { 47 | this.typeName = typeName; 48 | Collections.addAll(this.matchingText, textMatches); 49 | this.classSuffix = classSuffix; 50 | } 51 | 52 | public String getTypeName() { 53 | return typeName; 54 | } 55 | 56 | public boolean matches(String target, String className) { 57 | for (final String searchString : matchingText) { 58 | if (containsIgnoreCase(target, searchString)) { 59 | return true; 60 | } 61 | } 62 | 63 | return null != classSuffix && null != className && containsIgnoreCase(className, classSuffix); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /javadoc2dash-api/src/main/java/com/megatome/j2d/util/IndexData.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Megatome Technologies, LLC 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 | package com.megatome.j2d.util; 17 | 18 | import java.io.File; 19 | import java.util.ArrayList; 20 | import java.util.Collections; 21 | import java.util.List; 22 | 23 | /** 24 | * Class that identifies the docset index file and any files that need to be parsed and indexed. 25 | */ 26 | public class IndexData { 27 | private String docsetIndexFile; 28 | private List filesToIndex = new ArrayList<>(); 29 | 30 | /** 31 | * Set the docset index file 32 | * @param docsetIndexFile Index file 33 | */ 34 | public void setDocsetIndexFile(String docsetIndexFile) { 35 | this.docsetIndexFile = docsetIndexFile; 36 | } 37 | 38 | /** 39 | * Get the docset index file 40 | * @return Index file 41 | */ 42 | public String getDocsetIndexFile() { 43 | return docsetIndexFile; 44 | } 45 | 46 | /** 47 | * Add a file to be indexed 48 | * @param fileToIndex File 49 | */ 50 | public void addFileToIndex(File fileToIndex) { 51 | if (null != fileToIndex) { 52 | filesToIndex.add(fileToIndex); 53 | } 54 | } 55 | 56 | /** 57 | * Get the list of files to index 58 | * @return List of files 59 | */ 60 | public List getFilesToIndex() { 61 | return Collections.unmodifiableList(filesToIndex); 62 | } 63 | 64 | /** 65 | * Determine if there are any files to index 66 | * @return True if one or more files have been added to index 67 | */ 68 | public boolean hasFilesToIndex() { 69 | return !filesToIndex.isEmpty(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /javadoc2dash-api/src/main/java/com/megatome/j2d/util/LogUtility.java: -------------------------------------------------------------------------------- 1 | package com.megatome.j2d.util; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.helpers.MessageFormatter; 5 | 6 | /** 7 | * Simple class that wraps all logging. 8 | */ 9 | public class LogUtility { 10 | private static Logger logger; 11 | private static boolean verbose = false; 12 | 13 | /** 14 | * Specify a logger to use. Log messages will go to System.out if no logger is specified. 15 | * @param logger Logger instance to use 16 | */ 17 | public static void setLogger(final Logger logger) { 18 | if (null != logger) { 19 | LogUtility.logger = logger; 20 | } 21 | } 22 | 23 | /** 24 | * Specify if messages that are more verbose should be shown. 25 | * @param verbose True to set a higher verbosity 26 | */ 27 | public static void setVerbose(boolean verbose) { 28 | LogUtility.verbose = verbose; 29 | } 30 | 31 | /** 32 | * Log a message. If a logger has been specified, log the message at INFO level. Otherwise the message is logged 33 | * to System.out. 34 | * @param format Message, formatted per SLF4J requirements 35 | * @param arguments Arguments to substitute into the message before logging 36 | */ 37 | public static void log(String format, Object... arguments) { 38 | if (null != logger) { 39 | logger.info(format, arguments); 40 | } else { 41 | System.out.println(MessageFormatter.arrayFormat(format, arguments).getMessage()); 42 | } 43 | } 44 | 45 | /** 46 | * Log a message only if the verbose flag has been set. If a logger has been specified, log the message at INFO level. Otherwise the message is logged 47 | * to System.out. 48 | * @param format Message, formatted per SLF4J requirements 49 | * @param arguments Arguments to substitute into the message before logging 50 | */ 51 | public static void logVerbose(String format, Object... arguments) { 52 | if (verbose) { 53 | log(format, arguments); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /javadoc2dash-api/src/main/java/com/megatome/j2d/util/SearchIndexValue.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 Megatome Technologies, LLC 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 | package com.megatome.j2d.util; 17 | 18 | import com.megatome.j2d.support.MatchType; 19 | 20 | /** 21 | * Represents information that needs to be saved to the docset index. 22 | */ 23 | public class SearchIndexValue { 24 | private final String name; 25 | private final MatchType type; 26 | private final String path; 27 | 28 | /** 29 | * Ctor. 30 | * @param name Entry name 31 | * @param type Entry type 32 | * @param path Path to the entry 33 | */ 34 | public SearchIndexValue(String name, MatchType type, String path) { 35 | this.name = name; 36 | this.type = type; 37 | this.path = path; 38 | } 39 | 40 | /** 41 | * Get the entry name 42 | * @return Name 43 | */ 44 | public String getName() { 45 | return name; 46 | } 47 | 48 | /** 49 | * Get the entry type 50 | * @return Type 51 | */ 52 | public MatchType getType() { 53 | return type; 54 | } 55 | 56 | /** 57 | * Get the entry path 58 | * @return Path 59 | */ 60 | public String getPath() { 61 | return path; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /javadoc2dash-api/src/test/java/com/megatome/j2d/DocsetCreatorTest.java: -------------------------------------------------------------------------------- 1 | package com.megatome.j2d; 2 | 3 | import org.apache.commons.io.FileUtils; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | import java.io.File; 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | public class DocsetCreatorTest { 14 | private static final File CURRENT_DIR = FileUtils.getFile("."); 15 | private static final Map expectedValues = new HashMap<>(); 16 | private static final String DOCSET_NAME = "DOCSET_NAME"; 17 | private static final String DISPLAY_NAME = "DISPLAY_NAME"; 18 | private static final String JAVADOC_DIR = "JAVADOC_DIR"; 19 | private static final String KEYWORD = "KEYWORD"; 20 | private static final String OUTPUT_DIR = "OUTPUT_DIR"; 21 | private static final String ICON_FILE = "ICON_FILE"; 22 | 23 | @Before 24 | public void setup() { 25 | expectedValues.clear(); 26 | expectedValues.put(DOCSET_NAME, "Foo"); 27 | expectedValues.put(JAVADOC_DIR, CURRENT_DIR); 28 | expectedValues.put(DISPLAY_NAME, "Foo"); 29 | expectedValues.put(KEYWORD, "Foo"); 30 | expectedValues.put(OUTPUT_DIR, CURRENT_DIR); 31 | expectedValues.put(ICON_FILE, null); 32 | } 33 | 34 | @Test(expected = IllegalArgumentException.class) 35 | public void testCreateNullName() { 36 | final DocsetCreator.Builder builder = new DocsetCreator.Builder(null, CURRENT_DIR); 37 | builder.build(); 38 | } 39 | 40 | @Test(expected = IllegalArgumentException.class) 41 | public void testCreateEmptyName() { 42 | final DocsetCreator.Builder builder = new DocsetCreator.Builder("", CURRENT_DIR); 43 | builder.build(); 44 | } 45 | 46 | @Test(expected = IllegalArgumentException.class) 47 | public void testCreateMissingJavadocRoot() { 48 | final DocsetCreator.Builder builder = new DocsetCreator.Builder("Foo", null); 49 | builder.build(); 50 | } 51 | 52 | @Test 53 | public void testCreateMinimalBuilder() throws Exception { 54 | final DocsetCreator.Builder builder = new DocsetCreator.Builder("Foo", CURRENT_DIR); 55 | verifyCreatorValues(builder.build()); 56 | } 57 | 58 | @Test 59 | public void testBuildWithDisplayName() throws Exception { 60 | final DocsetCreator.Builder builder = new DocsetCreator.Builder("Foo", CURRENT_DIR); 61 | builder.displayName(null); 62 | verifyCreatorValues(builder.build()); 63 | 64 | builder.displayName(""); 65 | verifyCreatorValues(builder.build()); 66 | 67 | builder.displayName("Bar"); 68 | expectedValues.put(DISPLAY_NAME, "Bar"); 69 | verifyCreatorValues(builder.build()); 70 | } 71 | 72 | @Test 73 | public void testBuildWithKeyword() throws Exception { 74 | final DocsetCreator.Builder builder = new DocsetCreator.Builder("Foo", CURRENT_DIR); 75 | builder.keyword(null); 76 | verifyCreatorValues(builder.build()); 77 | 78 | builder.keyword(""); 79 | verifyCreatorValues(builder.build()); 80 | 81 | builder.keyword("Bar"); 82 | expectedValues.put(KEYWORD, "Bar"); 83 | verifyCreatorValues(builder.build()); 84 | } 85 | 86 | @Test 87 | public void testBuildWithOutputDirectory() throws Exception { 88 | final DocsetCreator.Builder builder = new DocsetCreator.Builder("Foo", CURRENT_DIR); 89 | builder.outputDirectory(null); 90 | verifyCreatorValues(builder.build()); 91 | 92 | final File newDir = FileUtils.getFile("src"); 93 | builder.outputDirectory(newDir); 94 | expectedValues.put(OUTPUT_DIR, newDir); 95 | verifyCreatorValues(builder.build()); 96 | } 97 | 98 | @Test 99 | public void testBuildWithIconFile() throws Exception { 100 | final DocsetCreator.Builder builder = new DocsetCreator.Builder("Foo", CURRENT_DIR); 101 | builder.iconFile(null); 102 | verifyCreatorValues(builder.build()); 103 | 104 | final File newDir = FileUtils.getFile("src"); 105 | builder.iconFile(newDir); 106 | expectedValues.put(ICON_FILE, newDir); 107 | verifyCreatorValues(builder.build()); 108 | } 109 | 110 | private void verifyCreatorValues(final DocsetCreator creator) { 111 | verifyCreatorValues(expectedValues, creator); 112 | } 113 | 114 | private void verifyCreatorValues(final Map expectedValueMap, final DocsetCreator creator) { 115 | assertNotNull(creator); 116 | assertEquals(expectedValueMap.get(DOCSET_NAME), creator.getDocsetName()); 117 | assertEquals(expectedValueMap.get(DISPLAY_NAME), creator.getDisplayName()); 118 | assertEquals(expectedValueMap.get(JAVADOC_DIR), creator.getJavadocRoot()); 119 | assertEquals(expectedValueMap.get(KEYWORD), creator.getKeyword()); 120 | assertEquals(expectedValueMap.get(OUTPUT_DIR), creator.getOutputDirectory()); 121 | assertEquals(expectedValueMap.get(ICON_FILE), creator.getIconFilePath()); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /javadoc2dash-api/src/test/java/com/megatome/j2d/support/DBSupportTest.java: -------------------------------------------------------------------------------- 1 | package com.megatome.j2d.support; 2 | 3 | import com.megatome.j2d.exception.BuilderException; 4 | import com.megatome.j2d.util.IndexData; 5 | import com.megatome.j2d.util.SearchIndexValue; 6 | import org.apache.commons.io.FileUtils; 7 | import org.apache.commons.io.FilenameUtils; 8 | import org.junit.Rule; 9 | import org.junit.Test; 10 | import org.junit.rules.TemporaryFolder; 11 | 12 | import java.io.File; 13 | import java.sql.Connection; 14 | import java.sql.DriverManager; 15 | import java.sql.PreparedStatement; 16 | import java.sql.ResultSet; 17 | import java.util.ArrayList; 18 | import java.util.List; 19 | import java.util.Map; 20 | 21 | import static org.apache.commons.io.FileUtils.getFile; 22 | import static org.junit.Assert.assertEquals; 23 | import static org.junit.Assert.assertTrue; 24 | import static org.hamcrest.MatcherAssert.assertThat; 25 | import static org.hamcrest.Matchers.*; 26 | 27 | public class DBSupportTest { 28 | private static final File javadocLocation = getFile(System.getProperty("j2d-sample-javadoc")); 29 | 30 | private static final String QUERY = "SELECT COUNT(*) FROM searchIndex WHERE type = ?"; 31 | 32 | @Rule 33 | public TemporaryFolder temporaryFolder = new TemporaryFolder(); 34 | 35 | @Test 36 | public void testCreateIndexDB() throws Exception { 37 | assertThat(javadocLocation, notNullValue()); 38 | final IndexData indexData = JavadocSupport.findIndexFile(javadocLocation); 39 | final List indexValues = JavadocSupport.findSearchIndexValues(indexData.getFilesToIndex()); 40 | final String docFileRoot = FilenameUtils.concat(temporaryFolder.getRoot().getPath(), "Foo"); 41 | final String dbDirName = DocSetSupport.getDBDir(docFileRoot); 42 | final File dbDir = getFile(dbDirName); 43 | FileUtils.forceMkdir(dbDir); 44 | DBSupport.createIndex(indexValues, dbDirName); 45 | final File dbFile = getFile(dbDir, "docSet.dsidx"); 46 | assertTrue("DB file does not exist", dbFile.exists()); 47 | 48 | final Map expectedTypes = ExpectedDataUtil.getExpectedData().getExpectedDataBaseTypes(); 49 | try (final Connection connection = DriverManager.getConnection("jdbc:sqlite:" + dbFile); 50 | final PreparedStatement stmt = connection.prepareStatement(QUERY)){ 51 | 52 | for (Map.Entry expectedEntry : expectedTypes.entrySet()) { 53 | stmt.setString(1, expectedEntry.getKey()); 54 | try (final ResultSet rs = stmt.executeQuery()) { 55 | while (rs.next()) { 56 | final int count = rs.getInt(1); 57 | assertThat(expectedEntry.getValue().intValue(), is(count)); 58 | } 59 | } 60 | } 61 | } 62 | } 63 | 64 | @Test(expected = BuilderException.class) 65 | public void testCreateIndexDBBadPath() throws Exception { 66 | final List indexValues = new ArrayList<>(); 67 | final String docFileRoot = FilenameUtils.concat(temporaryFolder.getRoot().getPath(), "Foo"); 68 | final String dbDirName = DocSetSupport.getDBDir(docFileRoot); 69 | final File dbDir = getFile(dbDirName); 70 | FileUtils.forceMkdir(dbDir); 71 | DBSupport.createIndex(indexValues, dbDirName + "FOO"); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /javadoc2dash-api/src/test/java/com/megatome/j2d/support/DocSetSupportTest.java: -------------------------------------------------------------------------------- 1 | package com.megatome.j2d.support; 2 | 3 | import com.dd.plist.NSDictionary; 4 | import com.dd.plist.NSObject; 5 | import com.dd.plist.PropertyListParser; 6 | import com.megatome.j2d.exception.BuilderException; 7 | import org.apache.commons.io.FilenameUtils; 8 | import org.junit.Rule; 9 | import org.junit.Test; 10 | import org.junit.rules.TemporaryFolder; 11 | 12 | import java.io.File; 13 | import java.util.Collection; 14 | import java.util.HashSet; 15 | import java.util.Set; 16 | 17 | import static com.megatome.j2d.support.DocSetSupport.*; 18 | import static org.apache.commons.io.FileUtils.*; 19 | import static org.junit.Assert.*; 20 | 21 | public class DocSetSupportTest { 22 | private static final File javadocLocation = getFile(System.getProperty("j2d-sample-javadoc")); 23 | 24 | @Rule 25 | public TemporaryFolder temporaryFolder = new TemporaryFolder(); 26 | 27 | @Test 28 | public void createDocsetDir() throws Exception { 29 | createAndVerifyDocsetStructure("TestDoc"); 30 | } 31 | 32 | @Test 33 | public void overwriteExistingDocsetDir() throws Exception { 34 | final String docsetDir = getDocsetRoot(createAndVerifyDocsetStructure("TestDoc")); 35 | 36 | final File testFile = getFile(docsetDir, "foo.txt"); 37 | write(testFile, "Test Data"); 38 | assertTrue(testFile.exists()); 39 | 40 | createAndVerifyDocsetStructure("TestDoc"); 41 | assertFalse(testFile.exists()); 42 | } 43 | 44 | @Test 45 | public void testCopyFiles() throws Exception { 46 | final String docsetDir = createAndVerifyDocsetStructure("TestDoc"); 47 | 48 | final File destDir = getFile(getDocsetRoot(docsetDir), CONTENTS, RESOURCES, DOCUMENTS); 49 | copyFiles(javadocLocation, docsetDir); 50 | final Collection originalFiles = buildFileCollectionWithoutPath(javadocLocation); 51 | final Collection copiedFiles = buildFileCollectionWithoutPath(destDir); 52 | 53 | assertEquals(originalFiles, copiedFiles); 54 | } 55 | 56 | @Test(expected = BuilderException.class) 57 | public void testCopyFilesError() throws Exception { 58 | final File sourceDir = getFile("src", "test", "resources", "javadoc", "index.html"); 59 | final String fakeRoot = FilenameUtils.concat(temporaryFolder.getRoot().getPath(), "Foo"); 60 | copyFiles(sourceDir, fakeRoot); 61 | } 62 | 63 | @Test 64 | public void testCreatePlist() throws Exception { 65 | final String docsetDir = createAndVerifyDocsetStructure("TestDoc"); 66 | createPList("Identifier", "displayName", "keyword", "indexFile", docsetDir); 67 | final File plist = getFile(getDocsetRoot(docsetDir), CONTENTS, "Info.plist"); 68 | assertNotNull(plist); 69 | assertTrue(plist.exists()); 70 | 71 | final NSDictionary rootDict = (NSDictionary) PropertyListParser.parse(plist); 72 | verifyPlistEntry(rootDict, "CFBundleIdentifier", "Identifier"); 73 | verifyPlistEntry(rootDict, "CFBundleName", "displayName"); 74 | verifyPlistEntry(rootDict, "DocSetPlatformFamily", "keyword"); 75 | verifyPlistEntry(rootDict, "dashIndexFilePath", "indexFile"); 76 | verifyPlistEntry(rootDict, "DashDocSetFamily", "java"); 77 | verifyPlistEntry(rootDict, "isDashDocset", "true"); 78 | } 79 | 80 | @Test 81 | public void testCopyIconFile() throws Exception { 82 | final String docsetDir = createAndVerifyDocsetStructure("TestDoc"); 83 | final File iconFile = getFile(getDocsetRoot(docsetDir), "icon.png"); 84 | copyIconFile(null, docsetDir); 85 | assertFalse(iconFile.exists()); 86 | final File expectedIconFile = getFile("src", "test", "resources", "blank.png"); 87 | copyIconFile(expectedIconFile, docsetDir); 88 | assertTrue(iconFile.exists()); 89 | assertTrue(contentEquals(expectedIconFile, iconFile)); 90 | } 91 | 92 | private void verifyPlistEntry(NSDictionary rootDict, String keyName, String expectedValue) { 93 | final NSObject obj = rootDict.objectForKey(keyName); 94 | assertNotNull(obj); 95 | final String value = obj.toString(); 96 | assertNotNull(value); 97 | assertEquals(expectedValue, value); 98 | } 99 | 100 | private String createAndVerifyDocsetStructure(String docsetName) throws Exception { 101 | final String docFileRoot = FilenameUtils.concat(temporaryFolder.getRoot().getPath(), docsetName); 102 | DocSetSupport.createDocSetStructure(docFileRoot); 103 | 104 | final String[] docsetDirs = {getDocsetRoot(docsetName), CONTENTS, RESOURCES, DOCUMENTS}; 105 | 106 | File f = temporaryFolder.getRoot(); 107 | for (final String dirName : docsetDirs) { 108 | f = getFile(f, dirName); 109 | assertTrue(f.exists()); 110 | assertTrue(f.isDirectory()); 111 | } 112 | return docFileRoot; 113 | } 114 | 115 | private Collection buildFileCollectionWithoutPath(final File targetDir) { 116 | final Set fileCollection = new HashSet<>(); 117 | for (final File f : listFiles(targetDir, null, true)) { 118 | fileCollection.add(f.getPath().replaceFirst(targetDir.getPath(), "")); 119 | } 120 | 121 | return fileCollection; 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /javadoc2dash-api/src/test/java/com/megatome/j2d/support/ExpectedDataUtil.java: -------------------------------------------------------------------------------- 1 | package com.megatome.j2d.support; 2 | 3 | import java.util.Collections; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | public class ExpectedDataUtil { 8 | private final Map EXPECTED_TYPES = new HashMap<>(); 9 | private final Map EXPECTED_DATABASE_TYPES = new HashMap<>(); 10 | private int EXPECTED_ENTRY_COUNT = 0; 11 | 12 | private static final ExpectedDataUtil INSTANCE = new ExpectedDataUtil(); 13 | 14 | private ExpectedDataUtil() { 15 | EXPECTED_TYPES.put(MatchType.CLASS, 1); 16 | EXPECTED_TYPES.put(MatchType.INTERFACE, 1); 17 | EXPECTED_TYPES.put(MatchType.CONSTRUCTOR, 5); 18 | EXPECTED_TYPES.put(MatchType.METHOD, 2); 19 | EXPECTED_TYPES.put(MatchType.PACKAGE, 6); 20 | EXPECTED_TYPES.put(MatchType.EXCEPTION, 1); 21 | EXPECTED_TYPES.put(MatchType.ERROR, 1); 22 | EXPECTED_TYPES.put(MatchType.FIELD, 1); 23 | EXPECTED_TYPES.put(MatchType.ENUM, 1); 24 | EXPECTED_TYPES.put(MatchType.NOTATION, 1); 25 | EXPECTED_TYPES.put(MatchType.STATIC_METHOD, 3); 26 | 27 | for (final Integer count : EXPECTED_TYPES.values()) { 28 | EXPECTED_ENTRY_COUNT += count; 29 | } 30 | 31 | for (final Map.Entry entry : EXPECTED_TYPES.entrySet()) { 32 | final String dbColumnName = entry.getKey().getTypeName(); 33 | int count = entry.getValue(); 34 | if (EXPECTED_DATABASE_TYPES.containsKey(dbColumnName)) { 35 | count += EXPECTED_DATABASE_TYPES.get(dbColumnName); 36 | } 37 | EXPECTED_DATABASE_TYPES.put(dbColumnName, count); 38 | } 39 | } 40 | 41 | public static ExpectedDataUtil getExpectedData() { 42 | return INSTANCE; 43 | } 44 | 45 | public Map getExpectedTypes() { 46 | return Collections.unmodifiableMap(EXPECTED_TYPES); 47 | } 48 | 49 | public Map getExpectedDataBaseTypes() { 50 | return Collections.unmodifiableMap(EXPECTED_DATABASE_TYPES); 51 | } 52 | 53 | public int getExpectedEntryCount() { 54 | return EXPECTED_ENTRY_COUNT; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /javadoc2dash-api/src/test/java/com/megatome/j2d/support/JavadocSupportTest.java: -------------------------------------------------------------------------------- 1 | package com.megatome.j2d.support; 2 | 3 | import com.megatome.j2d.exception.BuilderException; 4 | import com.megatome.j2d.util.IndexData; 5 | import com.megatome.j2d.util.SearchIndexValue; 6 | import org.junit.Test; 7 | 8 | import java.io.ByteArrayOutputStream; 9 | import java.io.File; 10 | import java.io.PrintStream; 11 | import java.net.URI; 12 | import java.util.*; 13 | 14 | import static com.megatome.j2d.support.ExpectedDataUtil.getExpectedData; 15 | import static org.apache.commons.io.FileUtils.getFile; 16 | import static org.hamcrest.MatcherAssert.assertThat; 17 | import static org.hamcrest.Matchers.*; 18 | import static org.junit.Assert.assertNotNull; 19 | 20 | public class JavadocSupportTest { 21 | private static final File resourcesRoot = getFile("src", "test", "resources"); 22 | private static final File regularJavadoc = getFile(System.getProperty("j2d-sample-javadoc")); 23 | private static final File splitJavadoc = getFile(System.getProperty("j2d-sample-javadoc-split")); 24 | private static final String NOT_JAVADOC_DIR = "not-javadoc"; 25 | private static final String INDEX_ALL_BAD_TAG_HTML = "index-all-bad-tag.html"; 26 | 27 | @Test(expected = BuilderException.class) 28 | public void testMissingJavadocDir() throws Exception { 29 | JavadocSupport.findIndexFile(getFile(resourcesRoot, "FOO")); 30 | } 31 | 32 | @Test(expected = BuilderException.class) 33 | public void testJavadocDirIsFile() throws Exception { 34 | JavadocSupport.findIndexFile(getFile(regularJavadoc, "index.html")); 35 | } 36 | 37 | @Test(expected = BuilderException.class) 38 | public void testNonJavadocDir() throws Exception { 39 | JavadocSupport.findIndexFile(getFile(resourcesRoot, NOT_JAVADOC_DIR)); 40 | } 41 | 42 | @Test 43 | public void testBuildIndexDataNonSplit() throws Exception { 44 | verifyFoundIndexValues(getAndVerifyIndexFiles(1, regularJavadoc)); 45 | } 46 | 47 | @Test 48 | public void testBuildIndexDataSplit() throws Exception { 49 | verifyFoundIndexValues(getAndVerifyIndexFiles(6, splitJavadoc)); 50 | } 51 | 52 | @Test 53 | public void testWarnsOfStrayTags() throws Exception { 54 | final URI uri = this.getClass().getResource(INDEX_ALL_BAD_TAG_HTML).toURI(); 55 | final List filesToIndex = Collections.singletonList(new File(uri)); 56 | 57 | final ByteArrayOutputStream errStream = new ByteArrayOutputStream(); 58 | System.setErr(new PrintStream(errStream)); 59 | try { 60 | JavadocSupport.findSearchIndexValues(filesToIndex); 61 | } 62 | finally { 63 | System.setErr(null); 64 | } 65 | 66 | final String err = errStream.toString(); 67 | 68 | assertThat(err, containsString("Something went wrong with parsing a link, possibly unescaped tags" + 69 | " in Javadoc. (Name: , Type: CONSTRUCTOR, Link: )")); 70 | assertThat(err, containsString("Most recently parsed value was: (Name: SampleClass, Type: CLASS," 71 | + " Path: ./com/megatome/j2d/sample/clazz/SampleClass.html)")); 72 | } 73 | 74 | private IndexData getAndVerifyIndexFiles(int expectedFileCount, File javadocDir) throws Exception { 75 | final IndexData indexData = JavadocSupport.findIndexFile(javadocDir); 76 | assertNotNull(indexData); 77 | final String indexFile = indexData.getDocsetIndexFile(); 78 | assertNotNull(indexFile); 79 | assertThat("overview-summary.html", is(indexFile)); 80 | final List files = indexData.getFilesToIndex(); 81 | assertNotNull(files); 82 | assertThat(expectedFileCount, is(files.size())); 83 | return indexData; 84 | } 85 | 86 | private void verifyFoundIndexValues(final IndexData indexData) throws Exception { 87 | final List indexValues = JavadocSupport.findSearchIndexValues(indexData.getFilesToIndex()); 88 | assertNotNull(indexValues); 89 | assertThat(indexValues.size(), is(getExpectedData().getExpectedEntryCount())); 90 | final Map> valueMap = new HashMap<>(); 91 | for (final SearchIndexValue value: indexValues) { 92 | List nameSet = valueMap.get(value.getType()); 93 | if (nameSet == null) { 94 | nameSet = new ArrayList<>(); 95 | } 96 | assertThat(nameSet, not(hasItem(value.getName()))); 97 | nameSet.add(value.getName()); 98 | valueMap.put(value.getType(), nameSet); 99 | } 100 | 101 | final Map expectedTypes = getExpectedData().getExpectedTypes(); 102 | assertThat(valueMap.size(), is(expectedTypes.keySet().size())); 103 | for (final Map.Entry expectedType: expectedTypes.entrySet()) { 104 | assertThat(valueMap, hasKey(expectedType.getKey())); 105 | final List namesForType = valueMap.get(expectedType.getKey()); 106 | assertNotNull(namesForType); 107 | assertThat("Wrong count for " + expectedType, namesForType.size(), is(expectedType.getValue())); 108 | } 109 | } 110 | } 111 | 112 | 113 | -------------------------------------------------------------------------------- /javadoc2dash-api/src/test/resources/blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iamthechad/javadoc2dash/b35179e8621cbc99beb945ddeb96c4452669cc7c/javadoc2dash-api/src/test/resources/blank.png -------------------------------------------------------------------------------- /javadoc2dash-api/src/test/resources/com/megatome/j2d/support/index-all-bad-tag.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Index (j2d-sample 1.0.8 API) 7 | 8 | 9 | 10 | 11 | 17 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 35 |
36 | 63 | 64 |
C F I M S V  65 | 66 | 67 |

C

68 |
69 |
com.megatome.j2d.sample.annotation - package com.megatome.j2d.sample.annotation
70 |
 
71 |
com.megatome.j2d.sample.clazz - package com.megatome.j2d.sample.clazz
72 |
 
73 |
com.megatome.j2d.sample.enums - package com.megatome.j2d.sample.enums
74 |
 
75 |
com.megatome.j2d.sample.error - package com.megatome.j2d.sample.error
76 |
 
77 |
com.megatome.j2d.sample.exception - package com.megatome.j2d.sample.exception
78 |
 
79 |
com.megatome.j2d.sample.iface - package com.megatome.j2d.sample.iface
80 |
 
81 |
82 | 83 | 84 | 85 |

F

86 |
87 |
FOO - Static variable in class com.megatome.j2d.sample.clazz.SampleClass
88 |
89 |
Sample field
90 |
91 |
92 | 93 | 94 | 95 |

I

96 |
97 |
interfaceMethod() - Method in interface com.megatome.j2d.sample.iface.SampleInterface
98 |
99 |
Sample interface method
100 |
101 |
102 | 103 | 104 | 105 |

M

106 |
107 |
method() - Method in class com.megatome.j2d.sample.clazz.SampleClass
108 |
109 |
Sample method
110 |
111 |
112 | 113 | 114 | 115 |

S

116 |
117 |
SampleAnnotation - Annotation Type in com.megatome.j2d.sample.annotation
118 |
119 |
Sample annotation
120 |
121 |
SampleClass - Class in com.megatome.j2d.sample.clazz
122 |
123 |
Sample class; for testing purposes with a stray tag in it
124 |
125 |
SampleClass() - Constructor for class com.megatome.j2d.sample.clazz.SampleClass
126 |
 
127 |
SampleEnum - Enum in com.megatome.j2d.sample.enums
128 |
129 |
Sample Enum
130 |
131 |
SampleError - Error in com.megatome.j2d.sample.error
132 |
133 |
Sample Error
134 |
135 |
SampleError(String) - Constructor for error com.megatome.j2d.sample.error.SampleError
136 |
137 |
Sample ctor
138 |
139 |
SampleException - Exception in com.megatome.j2d.sample.exception
140 |
141 |
Sample exception
142 |
143 |
SampleException() - Constructor for exception com.megatome.j2d.sample.exception.SampleException
144 |
145 |
Sample ctor
146 |
147 |
SampleException(String) - Constructor for exception com.megatome.j2d.sample.exception.SampleException
148 |
149 |
Sample ctor 150 |
151 |
152 |
SampleException(String, Throwable) - Constructor for exception com.megatome.j2d.sample.exception.SampleException
153 |
154 |
Sample ctor 155 |
156 |
157 |
SampleInterface - Interface in com.megatome.j2d.sample.iface
158 |
159 |
Sample interface
160 |
161 |
staticMethod() - Static method in class com.megatome.j2d.sample.clazz.SampleClass
162 |
163 |
Sample static method
164 |
165 |
166 | 167 | 168 | 169 |

V

170 |
171 |
valueOf(String) - Static method in enum com.megatome.j2d.sample.enums.SampleEnum
172 |
173 |
Returns the enum constant of this type with the specified name.
174 |
175 |
values() - Static method in enum com.megatome.j2d.sample.enums.SampleEnum
176 |
177 |
Returns an array containing the constants of this enum type, in 178 | the order they are declared.
179 |
180 |
181 | C F I M S V 
182 | 183 |
184 | 185 | 186 | 187 | 188 | 197 |
198 | 225 | 226 | 227 | 228 | -------------------------------------------------------------------------------- /javadoc2dash-api/src/test/resources/not-javadoc/hello.txt: -------------------------------------------------------------------------------- 1 | This is definitely not Javadoc. -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include "javadoc2dash-api", "j2d-cli", "j2d-gradle", "j2d-sample" 2 | rootProject.name = 'javadoc2dash' 3 | 4 | --------------------------------------------------------------------------------