
org.hotswap.agent.distribution.PluginDocs Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hotswap-agent Show documentation
Show all versions of hotswap-agent Show documentation
Distribution of HotswapAgent core and all plugins in all-in-one JAR.
The newest version!
package org.hotswap.agent.distribution;
import org.hotswap.agent.config.PluginManager;
import org.hotswap.agent.annotation.Plugin;
import org.hotswap.agent.distribution.markdown.MarkdownProcessor;
import org.hotswap.agent.util.IOUtils;
import org.hotswap.agent.util.scanner.ClassPathAnnotationScanner;
import org.hotswap.agent.util.scanner.ClassPathScanner;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
/**
* Generate plugin info and documentation into target/html.
*
* FIXME - if generated via maven, resources are inside JAR and generation fails with URI is not hierarchical exception
* need to resolve path inside JAR. Currently it can be launched from the IDE.
*/
public class PluginDocs {
public static final String TARGET_DIR = "/target/web-sources/";
MarkdownProcessor markdownProcessor = new MarkdownProcessor();
/**
* Generate the docs.
* @param args no arguments necessary.
*/
public static void main(String[] args) {
try {
new PluginDocs().scan();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* From a class definition resolve base URL common for all files in a maven project (project base directory).
*
* @param clazz class to use
* @return base path (e.g. file:/J:/HotswapAgent/HibernatePlugin)
*/
public static String getBaseURL(Class clazz) {
String clazzUrl = clazz.getResource(clazz.getSimpleName() + ".class").toString();
// strip path to the plugin from maven root directory
String classPath = clazz.getName().replace(".", "/");
return clazzUrl.replace("/target/classes/" + classPath, "").replace(".class", "");
}
/**
*
* @throws Exception
*/
public void scan() throws Exception {
StringBuilder html = new StringBuilder();
addHtmlHeader(html);
ClassPathAnnotationScanner scanner = new ClassPathAnnotationScanner(Plugin.class.getName(), new ClassPathScanner());
for (String plugin : scanner.scanPlugins(getClass().getClassLoader(), PluginManager.PLUGIN_PACKAGE.replace(".", "/"))) {
Class pluginClass = Class.forName(plugin);
Plugin pluginAnnotation = (Plugin) pluginClass.getAnnotation(Plugin.class);
String pluginName = pluginAnnotation.name();
String pluginDocFile = "plugin/" + pluginName + ".html";
String pluginLink = "ha-plugins/" + pluginName.toLowerCase() + "-plugin";
URL url = new URL(getBaseURL(getClass()) + TARGET_DIR + pluginDocFile);
boolean docExists = markdownProcessor.processPlugin(pluginClass, url);
addHtmlRow(html, pluginAnnotation, docExists ? pluginLink : null);
}
addHtmlFooter(html);
writeHtml(new URL(getBaseURL(getClass()) + TARGET_DIR + "plugins.html"), html.toString());
String mainReadme = markdownProcessor.markdownToHtml(IOUtils.streamToString(new URL(
getBaseURL(getClass()) + "/../README.md"
).openStream()));
writeMainReadme(mainReadme);
}
private void writeMainReadme(String mainReadme) throws MalformedURLException {
writeHtml(new URL(getBaseURL(getClass()) + TARGET_DIR + "README.html"), mainReadme);
// each section
for (String section : mainReadme.split("\\")) {
if (section.isEmpty())
continue;
// create label as content between and
int h1EndIndex = section.indexOf("
");
if (h1EndIndex > 0) {
String label = section.substring(0, h1EndIndex);
// strip off header, the web page already contains it
String content = section.substring(h1EndIndex+5);
// make user-friendly valid file name
label = label.replaceAll("\\s", "-");
label = label.replaceAll("[^A-Za-z0-9-]", "");
label = label.toLowerCase();
// name file after section name
writeHtml(new URL(getBaseURL(getClass()) + TARGET_DIR + "section/" + label + ".html"), content);
}
}
}
private void addHtmlRow(StringBuilder html, Plugin annot, String pluginDocFile) {
html.append("");
html.append("");
html.append(annot.name());
html.append(" ");
html.append("");
html.append(annot.description());
html.append(" ");
html.append("");
commaSeparated(html, annot.testedVersions());
html.append(" ");
html.append("");
commaSeparated(html, annot.expectedVersions());
html.append(" ");
html.append("");
if (pluginDocFile != null) {
html.append("Documentation");
}
html.append(" ");
html.append(" ");
}
private void addHtmlHeader(StringBuilder html) {
html.append("
");
}
private void addHtmlFooter(StringBuilder html) {
html.append("
");
}
private void commaSeparated(StringBuilder html, String[] strings) {
boolean first = true;
for (String s : strings) {
if (!first)
html.append(", ");
html.append(s);
first = false;
}
}
private void writeHtml(URL url, String html) {
try {
assertDirExists(url);
PrintWriter out = new PrintWriter(url.getFile());
out.print(html);
out.close();
} catch (FileNotFoundException e) {
throw new IllegalArgumentException("Unable to open file " + url + " to write HTML content.");
}
}
/**
* Create all required directories in path for a file
*/
public static void assertDirExists(URL targetFile) {
File parent = null;
try {
parent = new File(targetFile.toURI()).getParentFile();
} catch (URISyntaxException e) {
throw new IllegalStateException(e);
}
if(!parent.exists() && !parent.mkdirs()){
throw new IllegalStateException("Couldn't create dir: " + parent);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy