Collect custom Doc annotations in Java/Kotlin project? - java

I'm going to use lots of custom documentation notes all around code base of Kotlin and Java project. Seems like reasonable choice would be to use annotation.
As far as I know annotation is some sort of magic, handled by build tools. But I need to work with it in the Kotlin/Java code.
So we have two files /src/some/thing.kt
package some
annotation class Doc
#Doc
private fun some_doc() {
println("some doc")
}
and /src/generate_docs.kt
fun main() {
Find and call all the functions over all
the codebase marked with #Doc
And then run some other code to process
those notes and output HTML docs
}
How could it be done? Basically I can do it by manually writing all those calls, but I hope there's a better way.
fun main() {
some_doc()
another_doc()
yet_another_doc()
...
couple tens or hundreds more lines
And then run some other code to process
those notes and output HTML docs
}
If possible I would like to avoid Maven plugins and magic and just have plain old Java/Kotlin code I can run as java GenerateDocsKt.

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.

Identify the tools behind this REST application?

I am having to make use of some existing code. I cannot contact the previous developer. Part of it is a REST application. I can see how it works, but there is a lot of stuff that looks like code duplication. Or there is a tool of some kind which is taking some of the sources and creating articfacts and other sources from that, or it is creating templates, in which code was added. It looks a bit like Jersey but I have not used this in work, so I am not sure. I tried searching for the annotations, but that is not helpful. I may be missing the build files. It was in an eclipse project and I do not seem to have the .project directory.
This project has a lot of partial implementations that got set aside. I am having problems distringushing those from code that should work.
Looking for just "UserEmail", I see:
src/com/gs/dao/user/UserEmailDao.java
src/com/gs/dao/user/UserEmailDaoImpl.java
src/com/gs/service/UserEmailService.java
src/com/gs/service/UserEmailServiceImpl.java
This is not just 4 times the necessary code. Something is driving this structure. But what is it? Any suggestions?
I am seeing code like:
#ApiController("1.0")
public class UserEndpoint extends BaseEndpoint {
Logger logger = Logger.getLogger(UserEndpoint.class);
#Autowired
public UserService userService;
#Autowired
public UserContactService userContactService;
....
The directory structure looks like this:
src/com/gs/cache
src/com/gs/cache/local
src/com/gs/cache/mem
src/com/gs/servlet
src/com/gs/constants
src/com/gs/common
src/com/gs/dao
src/com/gs/dao/service
src/com/gs/dao/service/attr
src/com/gs/dao/user
src/com/gs/dao/user/attr
src/com/gs/dao/comm
src/com/gs/dao/comm/attr
src/com/gs/dao/vg
src/com/gs/dao/vg/attr
src/com/gs/dao/general
src/com/gs/dao/general/attr
src/com/gs/dao/exception
src/com/gs/elasticsearch
src/com/gs/service
src/com/gs/service/utils
src/com/gs/service/helper
src/com/gs/graph
src/com/gs/graph/gateway
src/com/gs/threads
src/com/gs/async
src/com/gs/async/test
src/com/gs/async/handler
src/com/gs/async/impl
src/com/gs/util
src/com/gs/util/xss
src/com/gs/nlp
src/com/gs/exception
src/com/gs/cassandra
src/com/gs/cassandra/dao
src/com/gs/search
src/com/gs/search/service
src/com/gs/rest
src/com/gs/rest/common
src/com/gs/rest/api
src/com/gs/rest/api/test
What the heck is all this stuff? :-)
You're probbaly not going to get one response that answers this. And you may get shut down for the question being too broad, but I will try. First off:
src/com/gs/dao/user/UserEmailDao.java
src/com/gs/dao/user/UserEmailDaoImpl.java
src/com/gs/service/UserEmailService.java
src/com/gs/service/UserEmailServiceImpl.java
That's a pretty common java pattern, You have an email service, and you split that into an interface and an implementation. You might consider it overkill (if the implementation never changes), but some of the tools being used might require interfaces. Same thing with the UserEmailDao data access object. It's pretty normal for java developers to split everything into an interface and an implementation, though it drives people using dynamic languages crazy.
As for what's generating the REST app, you need to track down where the ApiController annotation is coming from. It looks like it might be wrapper around a Spring MVC class. Post the import statement for that annotation, or just follow it your IDE.
Spring is definitely being used to wire the entire app together.
It looks like a pretty typical medium sized java application to me. From the directory structure, I doubt there is any code generation going on.
If there's a pom.xml (maven file) in the application root, that'll tell you everything you need to know about the application.

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.

Methods for getting annotation metadata in Java

I'm working on a JSR-303 validation framework for GWT. Some of you may have heard of it even though it is a small project. Here is gwt-validation.
In the old days (v1.0) it used a marker interface for each class and each class had metadata generated separately. This was bad because it was not part of the JSR-303 standard and we moved on to the next idea.
In version 2.0 it scans the classpath at runtime using Reflections. This is great. The downside is that it doesn't seem to be able to work inside of containerized environments or those with special restrictions.
This is probably my fault, look at the following code:
//this little snippet goes through the classpath urls and ommits jars that are on the forbidden list.
//this is intended to remove jars from the classpath that we know are not ones that will contain patterns
Set<URL> classPathUrls = ClasspathHelper.forJavaClassPath();
Set<URL> useableUrls = new HashSet<URL>();
for(URL url : classPathUrls) {
boolean use = true;
for(String jar : this.doNotScanJarsInThisList) {
if(url.toString().contains(jar)) {
use = false;
break;
}
}
if(use) {
useableUrls.add(url);
}
use = false;
}
ConfigurationBuilder builder = new ConfigurationBuilder()
.setUrls(useableUrls)
.setScanners( new TypeAnnotationsScanner(),
new FieldAnnotationsScanner(),
new MethodAnnotationsScanner(),
new SubTypesScanner()
)
.useParallelExecutor()
;
this.reflections = new Reflections(builder);
I'm using the filter to remove jars that I know can't have annotations in them that I'm interested in. As I mention this gives a huge speed boost (especially on large classpaths) but the ClasspathHelper.forJavaClassPath() that I'm basing this on probably isn't the best way to go in container environments. (e.g. Tomcat, JBoss)
Is there a better way or at least a way that will work with a container environment and still let my users filter out classes they don't want?
I've looked, some, into how the Hibernate Validation project (the reference implementation for JSR-303) and they appear to at least be using (at least in part) the Annotations Processing in Java 6. This can't be all of the story because that didn't show up until JDK6 and Hibernate Validator is JDK5 compatible. (See: hibernate documentation)
So, as always, there's more to the story.
I've read these threads, for reference:
About Scannotation which has been pretty much replaced by Reflections.
This one but it uses File and I'm not sure what the implications are of that in things like GAE (Google App Engine) or Tomcat.
Another that goes over a lot of the things I've talked about already.
These threads have only helped so much.
I've also read about the annotation processing framework and I must be missing something. It appears to do what I want but then again it appears to only work at compile time which I know isn't what is done by Hibernate Validator. (Can anyone explain how it does scanning? It works on GAE which means it can't use any of the IO packages.)
Further, would this code work better than what I have above?
Set<URL> classPathUrls = ClasspathHelper.forClassLoader(Thread.currentThread().getContextClassLoader());
Could that correctly get the classloader inside of a Tomcat or JBoss container? It seems scan a smaller set of classes and still finish okay.
So, in any case, can anyone help me get pointed in the right direction? Or am I just stuck with what I've got?
You could take a look at Spring's annotation support.
Spring can scan annotations in files (using asm IIRC), and works in and out of a container.
It may not be easy because it goes through Spring's Resource abstraction, but it should be doable to reuse (or extract) the relevant code.

Categories

Resources