Java - Using Ant to automatically generate boilerplate code - java

Intro:
I'm asking this before I try, fail and get frustrated as I have 0 experience with Apache Ant. A simple 'yes this will work' may suffice, or if it won't please tell me what will.
Situation:
I'm working on a project that uses JavaFX to create a GUI. JavaFX relies on Java Bean-like objects that require a lot of boilerplate code for it's properties. For example, all functionality I want to have is a String called name with default value "Unnamed", or in a minimal Java syntax:
String name = "Unnamed";
In JavaFX the minimum amount of code increases a lot to give the same functionality (where functionality in this case means to me that I can set and get a certain variable to use in my program):
private StringProperty name = new StringProperty("Unnamed");
public final String getName() { return name.get(); }
public final void setName(String value) { name.set(value); }
Question: Can I use Ant to generate this boilerplate code?
It seems possible to make Ant scripts that function as (Java) preprocessors. For instance by using the regex replace (https://ant.apache.org/manual/Tasks/replaceregexp.html) functions. I'm thinking of lines of code similar to this in my code, which then will be auto-replaced:
<TagToSignifyReplaceableLine> StringProperty person "Unnamed"
Final remark: As I've said before I have never used Ant before, so I want to check with you if 1) this can be done and 2) if this is a good way to do it or if there are better ways.
Thanks!

Yes, possible. You can even implement your own Ant task, that does this job very easily.
Something like so in ant:
<taskdef name="codegen" classpath="bin/" classname="com.example.CodeGen" />
and then
<codegen className="Test.java">
<Property name="StringProperty.name" value="Unnamed"/>
</codegen>
The CodeGen.java then like so:
public class CodeGen extends Task {
private String className = null;
private List properties = new ArrayList();
public void setClassName(String className) {
this.className = className;
}
/**
* Called by ant for every <property> tag of the task.
*
* #param property The property.
*/
public void addConfiguredProperty(Property property) {
properties.add(property);
}
public void execute() throws BuildException {
// here we go!
}
}

I know it can be done because my previous firm used ant to generate model objects in java.
The approach they used was to define model objects in an XML file and run an ant task to generate the pojo and dto.
I quickly googled and saw that there are tools that allow you to generate java from XML. You could probably give your schema/default values etc in XML and have an nt task to run the tool.

I would look at JSR-269 specifically: genftw which makes JSR-269 easier...
And yes it will work with Ant with out even having to write a plugin and will work better than a brittle RegEx.
The other option if your really adventurous is to check out XText for code generation but it is rather complicated.

Yes, it can be done :-)
I once wrote a webservices adapter that used a WSDL document (XML file describing a SOAP based webservice) to generate the POJO Java class that implemented the functional interface to my product. What lead me to do this was the mindlessly repetitive Java code which was necessary to talk to our proprietary system.
The technical solution used an XSLT stylesheet to transform the input XML document into an output Java text file which was subsequently compiled by ANT.
<!-- Generate the implementation classes -->
<xslt force="true" style="${resources.dir}/javaServiceStub.xsl" in="${src.dir}/DemoService.wsdl" out="${build.dir}/DemoService/src/com/myspotontheweb/DemoServiceSkeleton.java" classpathref="project.path">
<param name="package" expression="com.myspotontheweb"/>
..
..
</xslt>
Unfortunately XSLT is the closest thing to a templating engine supported by native ANT.
Best of luck!

Related

Is there any way auto generate graphql schema from protobuf?

I am developing springboot with GraphQL. Since the data structure is already declared within Protobuf, I tried to use it. This is example of my code.
#Service
public class Query implements GraphQLQueryResolver {
public MyProto getMyProto() {
/**/
}
}
I want make code like upper structure. To to this, I divided job into 2 sections.
Since ".proto file" can be converted to java class, I will use this class as return type.
And The second section is a main matter.
Also Schema is required. At first, I tried to code schema with my hand. But, the real size of proto is about 1000 lines. So, I want to know Is there any way to convert ".proto file" to ".graphqls file".
There is a way. I am using the a protoc plugin for that purpose: go-proto-gql
It is fairly simple to be used, for example:
protoc --gql_out=paths=source_relative:. -I=. ./*.proto
Hope this is working for you as well.

Create custom gradle plugin to analyze java source code and generate codes

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.

How start with UIMA and simple NLP tasks?

I've recently found out about UIMA (http://uima.apache.org/). It looks promising for simple NLP tasks, such as tokenizing, sentence splitting, part-of-speech tagging etc.
I've managed to get my hands on an already configured minimal java sample that is using OpenNLP components for its pipeline.
The code looks like this:
public void ApplyPipeline() throws IOException, InvalidXMLException,
ResourceInitializationException, AnalysisEngineProcessException {
XMLInputSource in = new XMLInputSource(
"opennlp/OpenNlpTextAnalyzer.xml");
ResourceSpecifier specifier = UIMAFramework.getXMLParser()
.parseResourceSpecifier(in);
AnalysisEngine ae = UIMAFramework.produceAnalysisEngine(specifier);
JCas jcas = ae.newJCas();
jcas.setDocumentText("This is my text.");
ae.process(jcas);
this.doSomethingWithResults(jcas);
jcas.reset();
ae.destroy();
}
private void doSomethingWithResults(JCas jcas) {
AnnotationIndex<Annotation> idx = jcas.getAnnotationIndex();
FSIterator<Annotation> it = idx.iterator();
while (it.hasNext()) {
System.out.println(it.next().toString());
}
}
Excerpt from OpenNlpTextAnalyzer.xml:
<delegateAnalysisEngine key="SentenceDetector">
<import location="SentenceDetector.xml" />
</delegateAnalysisEngine>
<delegateAnalysisEngine key="Tokenizer">
<import location="Tokenizer.xml" />
</delegateAnalysisEngine>
The java code produces output like this:
Token
sofa: _InitialView
begin: 426
end: 435
pos: "NNP"
I'm trying to get the same information from each Annotation object that the toString() method uses. I've already looked into UIMA's source code to understand where the values are coming from. My attempts to retrieve them sort of works, but they aren't smart in any way.
I'm struggling to find easy examples that, extract information out of the JCas objects.
I'm looking for a way to get for instance all Annotations produces by my PosTagger or by the SentenceSplitter for further usage.
I guess
List<Feature> feats = it.next().getType().getFeatures();
is a start to get values, but due to UIMA owns classes for primitive types, even the source code of the toString method in the annotation class reads like a slap in the face.
Where do I find java code that uses basic UIMA stuff and where are good tutorials (except javadoc from the framework itself)?
Generate JCas wrapper classes for your annotation types (you can do this using the type system editor UIMA plugin for Eclipse that comes with UIMA). This will provide you with Java classes that you can use to access the annotations - these offer getters and setters for features.
You should have a look at uimaFIT, which provides a more convenient API including convenience methods to retrieve annotations from the JCas, e.g. select(jcas, Token.class) (where Token.class is one of the classes you generated with the type system editor).
You could find some quick-starting Groovy scripts and a collection of UIMA components on the DKPro Core page.
There is material from the UIMA#GSCL 2013 tutorial (slides and sample code) which might be useful for you. Go here and scroll down to "Tutorial".
Disclosure: I'm developer on UIMA, uimaFIT, DKPro Core and co-organizer on the UIMA#GSCL 2013 workshop.

How to cleanly deal with structured selections in eclipse?

I'm writing an eclipse plugin, where I want to contribute an action to the JDT package explorer. In order for the action to be executed, there must be two different files selected. Therefore I retrieve the active selection of the JDT package explorer in the command handler for that action. That is where my problem is.
Currently the code that extracts the selected files from IStructuredSelection involves multiple local variables with multiple if statements and multiple returns in about 30 lines of code. And of course this code looks at least a bit ugly.
What concept(s) and or patterns should I use to make this code more cleaner?
The eclipse platform recommends to use the adapter pattern. So I thought of creating a pojo like this:
public class FooCommandArgs {
private IFile xmlFile;
private IFile csvFile;
//getters and setters here ...
}
and creating the necessary adapters for it from IStructuredSelection. However doing this would just move the ugly code to some other places.
So as the field names suggest, each item I want to extract from the IStructuredSelection has to fulfill some conditions. My idea is to use bean validation api for this. The pojo would then look like this:
public class FooCommandArgs {
#NotNull
#FileExtension("xml")
#Content(type=ContentType.XML, value="http://my.schema.location/schema.xsd")
private IFile xmlFile;
#NotNull
#FileExtension("csv")
private IFile csvFile;
//getters and setters here ...
}
The Validator interface of the bean validation api provides the method <T> Set<ConstraintViolation<T>> validateValue(Class<T> beanType, String propertyName, Object value, Class<?>... groups) which I could use for that. I just would have to introspect the java bean properties and then invoke that method for every combination of an IStructuredSelection item and pojo property. If the result is that every item could be assigned to a bean property with no constraint violations than I can just go on with handling the actual command. Ambiguities might as well be handled.
EDIT:
I have implemented this suggestion and it works out quite nice. Using this technique, it is also very easy to explain to a user programmatically, why a certain command isn't enabled or can not be executed.
I don't want to forget to mention JCommander at this point, which is the inspiration for this idea.

Eclipse Code Hinting on JSP with Custom Tags (taglib)

I'm developing a JSP tag that have an attribute that works with a set of possible values.
I don't need to enforce this values, but I would like my IDE (Eclipse) do some code hinting or auto-completion.
Suppose a tag like this <mytag:sometag someattribute="value" />.
The attribute someattribute can have any value (remember, I don't need to enforce), but I would like it to suggest you the following list of values: ValueA, ValueB and ValueC
Nitin Dahyabhai at the Eclipse Community Forums suggested writing a plugin based on org.eclipse.wst.xml.core.modelQueryExtensions or create templates with the values.
The problem with templates is that I have hundreds of possible values and I have multiple tags.
The problem with writing a plugin is that I haven't time or knowledge to do it.
Is there another way to do it?
In case you end up with writing Eclipse extension for modelQueryExtensions, that should be as simple as:
Create new plug-in: com.my.taglib, and add to its plugin.xml:
<extension point="org.eclipse.wst.xml.core.modelQueryExtensions">
<modelQueryExtension
class="com.my.taglib.MyTaglibModelQueryExtension"
contentType="org.eclipse.wst.html.core.htmlsource">
</modelQueryExtension>
</extension>
Then implement com.my.taglib.MyTaglibModelQueryExtension class:
public class MyTaglibModelQueryExtension extends ModelQueryExtension {
public String[] getAttributeValues(Element e, String namespace, String name) {
// See XSDModelQueryExtension for an example implementation of this...
}
}

Categories

Resources