I am implementing an internationalized GWT application at the moment. I read the related documentation and have created the necessary interface that extends com.google.gwt.i18n.client.Messages. I'd like to use MD5 key generation. The methods are annotated like this:
#DefaultMessage("Demo")
#Description("A menu item's label")
#Meaning("Nothing special so far")
String bucketDemo();
How could I automatically generate the translatable .properties files based on the interface? I see that i18nCreator is for generating the interface and the properties file the same time.
OMG, I missed the point that this file is automatically generated by the GWT Compiler.. :-)
Related
I am trying to create a plugin to generate some java code and write back to the main source module. I was able to create a some simple pojo class using JavaPoet and write to the src/main/java.
To make this useful, it should read the code from src/maim/java folder and analyze the classes using reflection. Look for some annotation then generate some codes. Do I use the SourceTask for this case. Looked like I can only access the classes by the files. Is that possible to read the java classes as the class and using reflection analyze the class?
Since you specified what you want to do:
You'll need to implement an annotation processor. This has absolutely nothing to do with gradle, and a gradle plugin is actually the wrong way to go about this. Please look into Java Annotation Processor and come back with more questions if any come up.
With JavaForger you can read input classes and generate sourcecode based on that. It also provides an API to insert it into existing classes or create new classes based on the input file. In contrast to JavaPoet, JavaForger has a clear separation between code to be generated and settings on where and how to insert it. An example of a template for a pojo can look like this:
public class ${class.name}Data {
<#list fields as field>
private ${field.type} ${field.name};
</#list>
<#list fields as field>
public ${field.type} ${field.getter}() {
return ${field.name};
}
public void ${field.setter}(${field.type} ${field.name}) {
this.${field.name} = ${field.name};
}
</#list>
}
The example below uses a template called "myTemplate.javat" and adds some extra settings like creating the file if it does not exist and changing the path where the file will be created from */path/* to */pathToDto/*. The the path to the input class is given to read the class name and fields and more.
JavaForgerConfiguration config = JavaForgerConfiguration.builder()
.withTemplate("myTemplate.javat")
.withCreateFileIfNotExists(true)
.withMergeClassProvider(ClassProvider.fromInputClass(s -> s.replace("path", "pathToPojo")))
.build();
JavaForger.execute(config, "MyProject/path/inputFile.java");
If you are looking for a framework that allows changing the code more programatticaly you can also look at JavaParser. With this framework you can construct an abstract syntax tree from a java class and make changes to it.
As the title says I need some help with GWT's i18n in use with UiBinder. I want to internationalize my application using static i18n. The book I use for learning only presents a way of internationalizing ui.xml files by having the compiler generate keys for Constants/Messages and a default file, but there has to be an easier way to do this. That's why I tried using the ui:with tag like this to use my internationalized constants (inside the upFace):
<ui:with type="havis.ui.shared.resourcebundle.ConstantsResource" field="lang"></ui:with>
<g:ToggleButton ui:field="observeButton">
<g:upFace>{lang.observe}</g:upFace>
<g:downFace>Observing</g:downFace>
</g:ToggleButton>
This doesn't work, the button shows the text {lang.observe} which also seems logical, but now my question is: Is there any way to use constants like this? And if not could someone explain how I should use constants in UiBinder files instead (without having the compiler generate files and keys)?
Anywhere HTML is accepted (such as within upFace), you can use <ui:msg>, <ui:text> and <ui:safehtml> (and anywhere plain text is expected, you can use <ui:msg> and <ui:text>).
So in your case:
<ui:with type="havis.ui.shared.resourcebundle.ConstantsResource" field="lang"></ui:with>
<g:ToggleButton ui:field="observeButton">
<g:upFace><ui:text from="{lang.observe}"/></g:upFace>
<g:downFace>Observing</g:downFace>
</g:ToggleButton>
See http://www.gwtproject.org/doc/latest/DevGuideUiBinder.html#Hello_Text_Resources and http://www.gwtproject.org/doc/latest/DevGuideUiBinder.html#Hello_Html_Resources about ui:text and ui:safehtml.
You can use constants like this :
.ui.xml :
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'>
<ui:with field="constants" type="my.client.resources.AppResources.AppConstants"/>
<g:FlowPanel>
<g:Label text="{constants.label}"/>
</g:FlowPanel>
and the AppResources interface :
public interface ApplicationResources extends ClientBundle {
public static final ApplicationConstants CONSTANTS = GWT.create(ApplicationConstants.class);
public interface ApplicationConstants extends com.google.gwt.i18n.client.Constants {
#DefaultStringValue("my label")
String label();
}
}
But for i18n you should really follow what the GWT manual says, i.e. there
is no other (clean) way than prepare all the property files (one for each language) and generate all the required permutations. This primarily delegates
to GWT all the language detection-related stuff, and the solution provided by
GWT performs quite well at runtime. The only drawback is that the compile time
is a little higher (since you'll have permutations for every browser in every language you specify).
I'm having trouble finding examples of how to implement partials using the Spullara Mustache java implementation. Their github page doesn't seem to have any straight forward partial examples.
In DefaultMustacheFactory I see methods for compilePartial and resolvePartialPath, but I'm not sure if I am supposed to override them or what.
I currently have this, and it works great without partials. TemplateContent contains the raw template html including mustache syntax.
public Mustache compileMustacheTemplate(String templateCode, String templateContent){
return new DefaultMustacheFactory().compile(new StringReader(templateContent),templateCode);
}
Pretty straight forward. But what if template content had {{>partialName}} inside it? I think I need to somehow specify that template content as well.
Do I need to extend DefaultMustacheFactory or possibly another class to specify the name of my partial and the content for it?
I believe I'm just missing something.
Thanks,
Matt
Assuming your template files are stored in a folder 'src/main/resources/org/example/web/' and you have one template "page.html" file referencing two other template files 'header.html' and 'footer.html'. Your template file "page.html" should look like this:
{{> src/main/resources/org/example/web/header.html}}
... some content ...
{{> src/main/resources/org/example/web/footer.html}}
When I use FlashBuilder to connect to a remote Java object using BlazeDS, FlashBuilder automatically creates a local valueObject matching the object in the remote server.
However, the package name of the remote object gets lost in translation.
Hence if I have two remote Java objects com.foo.A and com.bar.A, I won't be able to distinguish between them in Flex. So I end up having to name my remote classes com.foo.AFoo, com.bar.ABar.
Is there a better way?
I don't see why you you can't used com.foo.A on the flex end as well as the java end. Personally, I think Flex project structure is very different from Java (for instance, Java likes to use DTO naming, while Flex uses Model) and this is why I use RemoteClass metadata to bind the Java DTO to a Flex model.
The Flex class name is not important, and is ignored when sending / receiving classes to / from BlazeDS.
What is important is the name that's specified in the [RemoteClass] metadata on your Flex class.
Eg:
// Actionscript class Apple.as
package com.mangofactory.sample
{
[RemoteClass(alias="org.orchard.Orange")]
public class Apple {
... etc ....
Here, the Actionscript class com.mangofactory.sample.Apple is mapped to the Java class org.orchard.Orange
While the naming of the fields & properties within the class is important, the actual class mapping is specified explicitly using Metadata.
I have application written in spring, it communicate with another application, I received objects and now I have to map text id's to text in specific (given in object) language.
File with text id's and text looks like:
message.id=message
There is one file per language.
I'm looking for solution.
Spring provides some built-in support for internationalization in the form of MessageSources. See 3.13.1 Internationalization using MessageSource.
That's a job for the Java ResouceBundle class.
Basic usage:
ResourceBundle bundle = ResourceBundle.getBundle("path.on.the.classpath", requiredLocale);
String text = bundle.getString(textId);
You should handle MissingResourceExceptions etc. and maybe you even want to cache the bundles like some libraries/webframeworks do.