diff options
91 files changed, 10541 insertions, 163 deletions
@@ -345,6 +345,7 @@ lombok.launch.AnnotationProcessorHider$ClaimingProcessor</echo> <srcdir dir="src/delombok" /> <srcdir dir="src/stubs" /> <srcdir dir="src/testAP" /> + <srcdir dir="src/website" /> <srcdir dir="experimental/src" /> <srcdir dir="test/transform/src" /> <srcdir dir="test/core/src" /> diff --git a/buildScripts/ivy.xml b/buildScripts/ivy.xml index 3a851fcd..caa56012 100644 --- a/buildScripts/ivy.xml +++ b/buildScripts/ivy.xml @@ -35,6 +35,7 @@ <dependency org="projectlombok.org" name="jsch-ant-fixed" rev="0.1.42" conf="buildBase->build" /> <dependency org="projectlombok.org" name="markdownj" rev="1.02b4" conf="buildBase->build" /> <dependency org="de.java2html" name="java2html" rev="5.0" conf="buildBase->default" /> + <dependency org="org.freemarker" name="freemarker" rev="2.3.25-incubating" conf="buildBase->default" /> <dependency org="net.java.openjdk.custom" name="javac6" rev="1.6.0.18" conf="javac6->runtime; contrib->sources" /> <dependency org="net.java.openjdk.custom" name="javac7" rev="1.7.0" conf="javac7->runtime; contrib->sources" /> diff --git a/src/core/lombok/ConfigurationKeys.java b/src/core/lombok/ConfigurationKeys.java index f0e070e2..dec86aa7 100644 --- a/src/core/lombok/ConfigurationKeys.java +++ b/src/core/lombok/ConfigurationKeys.java @@ -460,6 +460,17 @@ public class ConfigurationKeys { */ public static final ConfigurationKey<FlagUsageType> HELPER_FLAG_USAGE = new ConfigurationKey<FlagUsageType>("lombok.helper.flagUsage", "Emit a warning or error if @Helper is used.") {}; + // ----- onX ----- + + /** + * lombok configuration: {@code lombok.onX.flagUsage} = {@code WARNING} | {@code ERROR}. + * + * If set, <em>any</em> usage of {@code onX} results in a warning / error. + * <br /> + * Specifically, this flags usage of {@code @Getter(onMethod=...)}, {@code @Setter(onParam=...)}, {@code @Setter(onMethod=...)}, {@code @XArgsConstructor(onConstructor=...)}. + */ + public static final ConfigurationKey<FlagUsageType> ON_X_FLAG_USAGE = new ConfigurationKey<FlagUsageType>("lombok.onX.flagUsage", "Emit a warning or error if onX is used.") {}; + // ----- UtilityClass ----- /** diff --git a/src/website/log4j.properties b/src/website/log4j.properties new file mode 100644 index 00000000..9cafcc3b --- /dev/null +++ b/src/website/log4j.properties @@ -0,0 +1,6 @@ +log4j.rootLogger=INFO, stdout + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n diff --git a/src/website/lombok/website/WebsiteMaker.java b/src/website/lombok/website/WebsiteMaker.java new file mode 100644 index 00000000..299b4211 --- /dev/null +++ b/src/website/lombok/website/WebsiteMaker.java @@ -0,0 +1,189 @@ +package lombok.website; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import de.java2html.Java2Html; +import freemarker.cache.FileTemplateLoader; +import freemarker.cache.TemplateLoader; +import freemarker.core.HTMLOutputFormat; +import freemarker.template.Configuration; +import freemarker.template.Template; +import freemarker.template.TemplateExceptionHandler; + +public class WebsiteMaker { + private final File baseDir, outputDir; + + public WebsiteMaker(File baseDir, File outputDir) { + this.baseDir = baseDir; + this.outputDir = outputDir; + } + + public static void main(String[] args) throws Exception { + File in, out; + if (args.length == 0) { + in = new File("."); + if (new File(in, "build.xml").isFile() && new File(in, "website2").isDirectory()) in = new File(in, "website2"); + } else { + in = new File(args[0]); + } + + if (args.length < 2) { + if (new File("./build.xml").isFile() && new File("./website2").isDirectory() && new File("./build").isDirectory()) { + out = new File("./build/website2"); + } else { + out = new File(in, "output"); + } + } else { + out = new File(args[1]); + } + WebsiteMaker maker = new WebsiteMaker(in, out); + + maker.buildWebsite(); + } + + public void buildWebsite() throws Exception { + Configuration freemarkerConfig = new Configuration(Configuration.VERSION_2_3_25); + freemarkerConfig.setEncoding(Locale.ENGLISH, "UTF-8"); + freemarkerConfig.setOutputEncoding("UTF-8"); + freemarkerConfig.setOutputFormat(HTMLOutputFormat.INSTANCE); + freemarkerConfig.setTemplateLoader(createLoader()); + freemarkerConfig.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); + + deleteAll(outputDir, 0); + outputDir.mkdirs(); + copyResources(); + convertTemplates(freemarkerConfig); + } + + private static void deleteAll(File outputDir, int depth) { + if (!outputDir.isDirectory()) return; + if (depth > 50) throw new IllegalArgumentException("50 levels is too deep: " + outputDir); + + for (File f : outputDir.listFiles()) { + String n = f.getName(); + if (n.equals(".") || n.equals("..")) continue; + if (f.isDirectory()) deleteAll(f, depth + 1); + f.delete(); + } + } + + private void copyResources() throws Exception { + File resourcesLoc = new File(baseDir, "resources"); + byte[] b = new byte[65536]; + copyResources_(resourcesLoc, outputDir, b, 0); + } + + private void copyResources_(File from, File to, byte[] b, int depth) throws IOException { + if (depth > 50) throw new IllegalArgumentException("50 levels is too deep: " + from); + if (!to.exists()) to.mkdirs(); + for (File f : from.listFiles()) { + if (f.isDirectory()) copyResources_(f, new File(to, f.getName()), b, depth + 1); + if (!f.isFile()) continue; + + FileInputStream fIn = new FileInputStream(f); + try { + FileOutputStream fOut = new FileOutputStream(new File(to, f.getName())); + try { + while (true) { + int r = fIn.read(b); + if (r == -1) break; + fOut.write(b, 0, r); + } + } finally { + fOut.close(); + } + } finally { + fIn.close(); + } + } + } + + private TemplateLoader createLoader() throws IOException { + return new FileTemplateLoader(new File(baseDir, "templates")); + } + + private void convertTemplates(Configuration freemarker) throws Exception { + File basePagesLoc = new File(baseDir, "templates"); + convertTemplates_(freemarker, "", basePagesLoc, outputDir, 0); + } + + private void convertTemplates_(Configuration freemarker, String prefix, File from, File to, int depth) throws Exception { + if (depth > 50) throw new IllegalArgumentException("50 levels is too deep: " + from); + + Map<String, Object> dataModel = createDataModel(); + + for (File f : from.listFiles()) { + if (f.isDirectory()) convertTemplates_(freemarker, prefix + f.getName() + "/", f, new File(to, f.getName()), depth + 1); + if (!f.isFile() || !f.getName().endsWith(".html") || f.getName().startsWith("_")) continue; + to.mkdirs(); + Template template = freemarker.getTemplate(prefix + f.getName()); + FileOutputStream fileOut = new FileOutputStream(new File(to, f.getName())); + try { + Writer wr = new BufferedWriter(new OutputStreamWriter(fileOut, "UTF-8")); + template.process(dataModel, wr); + wr.close(); + } finally { + fileOut.close(); + } + } + } + + private Map<String, Object> createDataModel() { + Map<String, Object> data = new HashMap<String, Object>(); + data.put("version", lombok.core.Version.getVersion()); + data.put("fullVersion", lombok.core.Version.getFullVersion()); + data.put("year", "" + new GregorianCalendar().get(Calendar.YEAR)); + data.put("usages", new HtmlMaker(new File(baseDir, "usageExamples"))); + return data; + } + + public static class HtmlMaker { + private final File usagesDir; + + HtmlMaker(File usagesDir) { + this.usagesDir = usagesDir; + } + + public String pre(String name) throws IOException { + return convert(new File(usagesDir, name + "Example_pre.jpage")); + } + + public String post(String name) throws IOException { + return convert(new File(usagesDir, name + "Example_post.jpage")); + } + + public String convert(File file) throws IOException { + String rawJava = readFully(file); + return Java2Html.convertToHtml(rawJava); + } + } + + public static String readFully(File file) throws IOException { + FileInputStream fis = new FileInputStream(file); + try { + InputStreamReader isr = new InputStreamReader(fis, "UTF-8"); + StringBuilder out = new StringBuilder(); + char[] b = new char[65536]; + while (true) { + int r = isr.read(b); + if (r == -1) break; + out.append(b, 0, r); + } + return out.toString(); + } finally { + fis.close(); + } + } +} diff --git a/website/features/experimental/Helper.html b/website/features/experimental/Helper.html deleted file mode 100644 index da474fc2..00000000 --- a/website/features/experimental/Helper.html +++ /dev/null @@ -1,83 +0,0 @@ -<!DOCTYPE html> -<html><head> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - <link rel="stylesheet" type="text/css" href="../../logi/reset.css" /> - <link rel="stylesheet" type="text/css" href="../features.css" /> - <link rel="shortcut icon" href="../../favicon.ico" type="image/x-icon" /> - <meta name="description" content="Spice up your java" /> - <title>EXPERIMENTAL – @Helper</title> -</head><body><div id="pepper"> - <div class="minimumHeight"></div> - <div class="meat"> - <div class="header"><a href="../../index.html">Project Lombok</a></div> - <h1>@Helper</h1> - <div class="byline">With a little help from my friends... Helper methods for java.</div> - <div class="since"> - <h3>Since</h3> - <p> - <code>@Helper</code> was introduced as an experimental feature in lombok v1.16.6. - </p> - </div> - <div class="experimental"> - <h3>Experimental</h3> - <p> - Experimental because: - <ul> - <li>Lambdas with general function types offer an alternative strategy.</li> - <li>Perhaps a way to make helper methods with less boilerplate is possible, making this feature obsolete.</li> - </ul> - Current status: <em>unknown</em> - We don't have enough experience with this feature to make predictions on its future. - </div> - <div class="overview"> - <h3>Overview</h3> - <p> - This annotation lets you put methods in methods. You might not know this, but you can declare classes inside methods, and the methods in this class can access any (effectively) final local variable or parameter defined and set before the declaration. Unfortunately, to actually call any methods you'd have to make an instance of this method local class first, but that's where <code>@Helper</code> comes in and helps you out! Annotate a method local class with <code>@Helper</code> and it's as if all the methods in that helper class are methods that you can call directly, just as if java had allowed methods to exist inside methods. - </p><p> - Normally you |
