Can a Java annotation spread over multiple lines? - java

I use GWT I18N, which relies on annotations for messages with parameters.
Exemple :
#DefaultMessage("Here is a message <br/> with a param:{0}")
String messageToLocalize(String param);
In absence of a localized translation, the default message will be used.
I have some quite long strings to handle, which I would like to type in sevral lines for code readability (I don't speak about multiple lines for the rendered message).
I tried this :
#DefaultMessage("Here is a long \
message <br/> with a \
param:{0}")
String messageToLocalize(String param);
It fails (GWT PlugIn 4.2 and SDK 2.5.1) with an error "Invalid Escape Sequence".
Did I miss something ?
Is it a constraint on Java annotations or GWT ? (I am afraid so but couldn't find anything on that)
Is there a workaround ?
Thanks
Edit : Given first answers, the question must be rephrased : is it possible, and which character should I use to show continuation (if any) ?
The annotation processor obviously needs something to tell him.
I tried "\" because it is the char to use in property file ...
"+" does not work either.

Java doesn't support C-style string-lines representation, so you could not use such multi-line style neither in annotations declarations, neither in other places of code.
If you want multiply lines of single string, you have to do something like this:
#DefaultMessage("Here is a long " +
"message <br/> with a " +
"param:{0}")

As Andremoniy said, it must be cut using Java-style.
But otherwise, I recommend you to have a look at i18nCreator. It allows you to manage your i18n in properties files and have these Messages interfaces files automatically generated:
https://developers.google.com/web-toolkit/doc/latest/RefCommandLineTools#i18nCreator
(There is also a maven plugin: http://mojo.codehaus.org/gwt-maven-plugin/user-guide/i18n.html)

Try string concatenation that is done at compile time, so:
#DefaultMessage("Here is a long"+
"message <br/> with a " +
"param:{0}"")

Related

Does X-definition possess an instruction similar to xsl:value-of in XSLT?

I put Saxon on my classpath so that it was subsequently available for the X-definition API to discover, but in order for the results of my Xpath 3.1 expressions to be shown consistently, it was necessary that I fall back on Xpath's serialize() function:
<?xml version="1.0" encoding="UTF-8"?>
<xd:def xmlns:xd="http://www.xdef.org/xdef/4.0" name="frontend" root="code">
<xd:declaration>
String myxpathexpression = "let $b := 'away I go' return (0 to string-length($b)) ! ('
' || substring($b,1,string-length($b) - .))";
String valueofmyxpathexpression = "serialize(" + myxpathexpression + ")";
</xd:declaration>
<code xd:script="occurs +;init {outln(xpath(valueofmyxpathexpression));}"/>
<!--<code xd:script="occurs +;init {outln(xpath(myxpathexpression));}"/>-->
</xd:def>
(As a comment posted in response to this question has since established, the Xpath expression used in the above code happened to already not be up to the task it ostensibly had set for itself. Because the Xpath expression furnished by Martin Honnen in his comment takes full account of the sequence of items returned where the previous expression can have taken barely any, the code printed below can afford to dispense with the expedient that was resorted to before:
<?xml version="1.0" encoding="UTF-8"?>
<xd:def xmlns:xd="http://www.xdef.org/xdef/4.0" name="frontend" root="code">
<xd:declaration>
<!-- https://stackoverflow.com/questions/68171810/does-x-definition-possess-an-instruction-similar-to-xslvalue-of-in-xslt -->
String myxpathexpression = "string-join(let $b := 'away I go' return (0 to string-length($b)) ! ('
' || substring($b,1,string-length($b) - .)), ' ')";
</xd:declaration>
<code xd:script="occurs +;init {outln(xpath(myxpathexpression));}"/>
</xd:def>
Apologies are needless to say offered for having permitted poor code to distract from a question others could well wish to ask in future).
(Both articles of code were run by piping echo "<code/>" to the Java command and assigning /dev/stdin as the source of the XML).
When the line where the variable bound to the Xpath expression itself (myxpathexpression) was passed to X-script's xpath() function is uncommented (and the corresponding line commented out), it seems that a second parameter to xpath() is implied and that the function is really designed to populate a Container based on the data available from an Element or the like, rather than to populate one with the items produced by an Xpath expression per se. It did not look feasible to pass null explicitly as the second parameter.
Have I overlooked anything in X-definition's XML vocabulary or its X-script language that shall work similarly to XSLT's xsl:value-of instruction? I have consulted the user documentation, including the Lexicon, to the best of my ability, but it unfortunately is not at all unlike me to miss things out the more they are obvious.
If you have Saxon on your classpath you can use the method "xquery" instead of "xpath". Then you can use full XQuery language. Then the following command will work correctly in the code from your question:
<code xd:script="occurs +;init {outln(xquery(myxpathexpression));}"/>
Note you can try it on the web:
http://xdef.syntea.cz/tutorial/examples/validate.html

Automatic `log.info` completion in IntelliJ IDEA?

I am using Java and I log things like:
log.info("createArticle userId={} articleId={} title={} content={}", userId, articleId, title, content);
As you can see, when inputting this line into my IDE, I have to manually write down those characters like "userId={} ". Ideally, I hope I can simply type the userId, and Intellij IDEA will automatically help me fill out both "userId={} " (in the format string) and , userId (in the arguments list).
Question: How can I do that in IntelliJ IDEA? Or, is there any other ways to type such logging lines faster?
Thanks for any suggestions!
It is possible to implement it with Live Templates and groovyScript for one of the variables: take the second segment, split it by comma, concat in something like part=${part}:
groovyScript("_1.split(',').collect { it.trim() + '={}' }.join(' ')", B)
See video

Structured logging where logger argument not wanted in message

I'm using structured logging in a Spring Boot app using logstash and sometimes I want to include key values in the log that I don't want to be used in the message of the log. Is there a StructuredArgument or similar that allows for this?
An example of what I am doing currently is something like this:
// import lombok.extern.slf4j.Slf4j;
// import static net.logstash.logback.argument.StructuredArguments.kv;
// import static net.logstash.logback.argument.StructuredArguments.v;
log.info(
"My message with one arg {}",
v("key1":"arg I want to include value in place of placeholder in message and in json as key/value"),
kv("key2", "arg I only want in the json and not in the message"))
Everything works as I intended, by which I mean the log includes both key value pairs and the message only includes the first value in place of the placeholder. The issue is that I get a warning from the compiler which is flagged by intellij (PlaceholderCountMatchesArgumentCount) about the second structured argument and I would like to avoid this without resorting to suppressing/ignoring it
You can use Markers and pass it before your logging message - more details on github.
logger.info(append("key2", "only json"),
"My message with one arg {}",
v("key1":"arg in msg and json"));
I personally don't like this because markers have different purpose, so if structured argument works for you, just ignore warning in IDE.
Anyway, all this json/structured implementations are workarounds for SLF4J 1.*, which has not built for that. There was SLF4J 2.0.0-alpha1 release almost a yeah ago, but it is still in alpha and I haven't used it. But it's API should be ready for key-values that are crusial in nowadays distributed log management systems.
You can make the log message as a constant String, then the code quality checks will not warn this
You can make the structured argument print nothing into the formatted message:
(1) include the second placeholder {} inside the message
(2) use keyValue() instead of kv()
(3) provide the optional messageFormatPattern parameter (JavaDoc) equal to ""
Adjusting your example:
log.info(
"My message with one arg {}{}", //note (1)
v("key1":"arg I want to include value in place of placeholder in message and in json as key/value"),
keyValue("key2", "arg I only want in the json and not in the message", "")) //note (2) + (3)
This will effectively replace the second placeholder with an empty string.

Doxygen annotation/attribute are ignored

I use doxygen to generate xml which then i transform to a custom documentation.
Is there a possibility that doxygen includes the annotation of a field / class / function.
The annotation are ignored in both java and c#.
ex:
class User
{
[Required]
string UserName {get;set;}
}
the "Required" annotation is not parsed/displayed in doxygen.
What I would like to have in the xml / html output of doxygen is all the annotated Annotations of a property / field / class (in the ex. "[Required]").
EXTRACT_ALL=YES is useless in this case. Look at this answer, I think it is good idea:
Doxygen and add a value of an attribute to the output documentation
So you have to create filter (for example in phyton) which will be used by Doxygen to convert annotation to comment. Don’t forget to inform Doxygen about your filter: INPUT_FILTER = doxygenFilter.py
I have the same problem so I modified that example in this way:
#!/usr/bin/env python
import sys
import re
if (len(sys.argv) < 2):
print "No input file"
else:
f = open(sys.argv[1])
line = f.readline()
while line:
re1 = re.compile("\s*\[(.*)]\s*")
re1.search(line)
sys.stdout.write(re1.sub(r"/// <para>Annotation: [\1]</para>\n", line))
#sys.stdout.write(line)
line = f.readline()
f.close()
So code like
[AnyAnnotation()]
Will be converted to:
/// <param> Annotation [AnyAnnotation()] </param>`
So I got very nice result. Tag <param> is to avoid Doxygen put this annotation description to main description. Instead it will put it to remarks section.
I'm not sure what you're asking but I will say a few things that might help you.
Doxygen must be configured to produce documentation for code elements that have no Doxygen comments. In other words, you can tell Doxygen to produce documentation for all functions, variables, macros, etc even if they aren't documented in the code. Set EXTRACT_ALL=YES in your config file.
If you run DoxyWizard you will get a better feel for all of the available options and the effect of each option. DoxyWizard is the GUI front end to Doxygen.
And by the way, bravo for documenting your code!

Using Gradle to generate JavaDoc with newline characters in the "header"

UPDATE: Made a posting on the Gradle forum. Please star this issue so that it gets more attention http://gsfn.us/t/4jedo
I'm in the process of transitioning from a primarily Ant build environment into a Gradle one. One sticking point is injecting Google Analytics and Adsense code into the JavaDoc. This is done by putting java script code into the header or bottom panels. For an example of what I'm currently doing, look at this question CDATA.
The problem with Gradle is that it can't handle newline characters in the string which is to be inserted. If you filter out those characters you break the script. Here is a code sniplet:
task alljavadoc(type: Javadoc) {
source = javadocProjects.collect { project(it).sourceSets.main.allJava }
classpath = files(javadocProjects.collect { project(it).sourceSets.main.compileClasspath })
destinationDir = file("${buildDir}/docs/javadoc")
configure(options) {
header = "this is\na test which should fail"
}
}
The critical part is "header =". If you remove the '\n' character it will work just fine. Otherwise the call to javadoc, which Gradle makes, will fail with the following error:
Successfully started process 'command '/opt/jdk/jdk1.7.0_21/bin/javadoc''
javadoc: error - Illegal package name: ""
javadoc: warning - No source files for package a
javadoc: warning - No source files for package test
javadoc: warning - No source files for package which
javadoc: warning - No source files for package should
javadoc: warning - No source files for package fail
The actual java script that I wish to include is below. Note that I can't hack it by removing new line characters since that will break the script.
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- banner -->
<ins class="adsbygoogle"
style="display:inline-block;width:468px;height:60px"
data-ad-client="ca-pub-xxxxxxxxxxxxxxxxx"
data-ad-slot="xxxxxxxxx"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
As a sanity check I also passed in a string with new line characters directly to javadoc (manual) on the command line and it works just fine.
javadoc foo.java -header "This is a test
and so is this"
The output HTML:
<div class="aboutLanguage"><em>This is a test
and so is this</em></div>
</div>
I have an explanation, but i don't have a solution except for creating a new feature request in Gradle JIRA.
To generate a javadoc Gradle first generates the so-called argfile at build\tmp\javadocTaskName\javadoc.options that contains all individual options and than executes javadoc #full\path\to\build\tmp\javadocTaskName\javadoc.options command.
It is actually quite useful as you can debug the contents of that file by simply invoking javadoc #javadoc.options yourself from the command line.
It is possible to define multi-line values in the argfile by using the \ character at the end of each line inside the multi-line value.
The example header = "this is\na test which should fail" results in
-header 'this is
a test which should fail'
but we need to get
-header 'this is\
a test which should fail'
to tell javadoc that the value continues on the next line.
Now the problem is how to output that \ on each line.
The obvious attempt at header = "this is\\\na test which should fail" does not work, it will result in
-header 'this is\\
a test which should fail'
And even Groovy multi-line or slashy strings will not work and will result in similar double back slashes.
Because Gradle just replaces all single backslashes in the option values. The JavadocOptionFileWriterContext.writeValue(String) method is the culprit, the replaceAll("\\\\", "\\\\\\\\") line in particular (a regex that matches single backslash and replaces it with double backslash ).
This escaping is required for backslashes inside a line, but it should not escape a single backslash followed by the new line character. My regex-fu is not strong enough to write such a pattern, but it is surely possible.
Or even better, the escaping mechanism inside that method should replace newline characters with a single backslash followed by the newline to hide all this stuff and allow users to declare multi-line javadoc options without the need to think or even know that feature.
I would appreciate if somebody can create an issue in Gradle tracker as i can't do so from my current location. This sentence should be replaced with the link to the issue so that people with similar problem can vote and track its progress.
I tried to implement it in Gradle but I couldn't get it to work reliably on windows. If the options file has this:
-header 'this is\
a test which should fail'
It works nicely on linux/mac but fails on windows (tried on win7/java7 and some other windows+java6). I've tried with vanilla javadoc executable (without Gradle).
I'll get the fix into Gradle and it will work out of the box for linux/mac but not quite for windows. If you want to help out with windows support catch us at http://issues.gradle.org/browse/GRADLE-3099

Categories