Here is an implementation of multiline string literals in Java, using Javadoc comments, an annotation and an annotation processor.
This method works by annotating a String
field with a @Multiline
annotation, placing the fields initialisation value in a Javadoc comment, then using an annotation processor to set the fields value to the contents of the Javadoc comment at compile time.
First off, the @Multiline
annotation.
Multiline.java
1 2 3 4 5 6 7 8 9 10 11 | package org.adrianwalker.multilinestring; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target (ElementType.FIELD) @Retention (RetentionPolicy.SOURCE) public @interface Multiline { } |
Next, the annotation processor to insert the value of the Javadoc comment into the String
field.
MultilineProcessor.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | package org.adrianwalker.multilinestring; import com.sun.tools.javac.model.JavacElements; import com.sun.tools.javac.processing.JavacProcessingEnvironment; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.TreeMaker; import java.util.Set; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; @SupportedAnnotationTypes ({ "org.adrianwalker.multilinestring.Multiline" }) public final class MultilineProcessor extends AbstractProcessor { private JavacElements elementUtils; private TreeMaker maker; @Override public void init( final ProcessingEnvironment procEnv) { super .init(procEnv); JavacProcessingEnvironment javacProcessingEnv = (JavacProcessingEnvironment) procEnv; this .elementUtils = javacProcessingEnv.getElementUtils(); this .maker = TreeMaker.instance(javacProcessingEnv.getContext()); } @Override public boolean process( final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnv) { Set<? extends Element> fields = roundEnv.getElementsAnnotatedWith(Multiline. class ); for (Element field : fields) { String docComment = elementUtils.getDocComment(field); if ( null != docComment) { JCTree.JCVariableDecl fieldNode = (JCTree.JCVariableDecl) elementUtils.getTree(field); fieldNode.init = maker.Literal(docComment); } } return true ; } } |
And finally, a class which demonstrates the usage of the annotation.
MultilineStringUsage.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | package org.adrianwalker.multilinestring; public final class MultilineStringUsage { /** <html> <head/> <body> <p> Hello<br/> Multiline<br/> World<br/> </p> </body> </html> */ @Multiline private static String html; public static void main( final String[] args) { System.out.println(html); } } |
Maven
Remember to include an <annotationProcessor>
element when compiling classes which use @Multiline
in the compiler plugin configuration when using Maven.
pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | ... < plugin > < groupId >org.apache.maven.plugins</ groupId > < artifactId >maven-compiler-plugin</ artifactId > < version >2.3.2</ version > < configuration > < source >1.6</ source > < target >1.6</ target > < annotationProcessors > < annotationProcessor > org.adrianwalker.multilinestring.MultilineProcessor </ annotationProcessor > </ annotationProcessors > </ configuration > </ plugin > ... |
Eclipse
To use in a non Maven Java project with Eclipse, try this: https://github.com/benelog/multiline/wiki/Non-Maven-Java-project-with-Eclipse
Source Code
- Github - multiline-string
Usage
Build and install the Multiline String project which contains the @Multiline
annotation and annotation processor, using 'mvn clean install
'.
Build and install the Multiline String Usage project which contains an example of how to use the @Multiline
annotation, using 'mvn clean install
'.
Run the MultilineStringUsage
class to output the multiline string.