I have recently started to look at OpenApi code generator and I have a few questions that I couldn't find an answer to with the usual resources (google and documentation mostly).
What I want to generate via the components.yaml and the code generator:
An interface with a couple of methods (lets just say getters and setters for example)
Have several model like classes that implement this interface
After several hours of trying to accomplish this I have the following questions:
For item 1: Is this even possible with the code generator? If so can I do it without custom mustache templates and how?
Still for item 1: If mustache template is the only way to go, how can I make sure the object that I defined in components.yaml can point to that specific custom template.
For item 2: How do I make sure that the generated code for the model-like class implements the previously generated interface? Is there a specific key for components.yaml that allows me to do this?
Any help would be greatly appreciated!
Related
When i generate code for Spring from my swagger yaml , usually controller layer is generated using delegate pattern , such that for a single model three files are generated . For example , if i defined a model named Person in my swagger/open API yaml file , three files get generated as :
PersonApi (interface that contains signatures of all person operations/methods)
PersonApiDelegate ( interface that provides default implementation of all PersonApi methods . Meant to be overriden )
PersonApiController (Which has a reference to PersonApiDelegate so that any implementation can override and provide custom implementation)
My question is for anyone who is familiar with building swagger/openapi generated code based apis that what is the significance of having such a pattern , instead of just exposing your service endpoints using a PersonController class , and not going through a PersonApi interface and then to a PersonApiDelegate and finally exposing the service through a PersonApiController ?
What is the valuable design extensibility we gain through this pattern ? I tried to find information from other resources on internet , but couldn't find a good answer in context of swagger first API development approach . Any insights on this will be really helpful .
First of all a clarification: as already mentioned in a comment, you are not forced to use the delegation. On the contrary, the default behavior of the Spring generator is to not use the delegation pattern, as you can easily check in the docs. In this case it will generate only the PersonApi interface and PersonApiController.
Coming to your question, why using delegation?
This allows you to write a class that implements PersonApiDelegate, that can be easily injected in the generated code, without any need to manually touch generated sources, and keeping the implementation safe from possible future changes in the code generation.
Let's think what could happen without delegation.
A naive approach would be to generate the sources and then write directly the implementation inside the generated PersonController. Of course the next time there is a need to run the generator, it would be a big mess. All the implementation would be lost...
A slightly better scenario, but not perfect, would be to write a class that extends PersonController. That would keep the implementation safe from being overwritten during generation, but would not protect it from future changes of the generation engine: as a bare minimum the implementation class would need to implement the PersonController constructor. Right now the constructor of a generated controller has the following signature PersonApiController(ObjectMapper objectMapper, HttpServletRequest request), but the developers of the generator may need to change it in the future. So the implementation would need to change too.
A third approach would be to forget completely about the generated PersonApiController, and just write a class that implements the PersonApi interface. That would be fine, but every time the code is generated you would need to delete the PersonApiController, otherwise Spring router will complain. Still manual work...
But with the delegation, the implementation code is completely safe. No need to manually delete stuff, no need to adapt in case of future changes. Also the class that implements PersonApiDelegate can be treated as an independent service, so you can inject / autowire into it whatever you need.
I have some interface Action, and most of the classes implementing that interface are derived from some base AbstractAction. But I assume there are some classes that implement that interface, but that do not extend that base class.
Is there a way using IntelliJ to identify such classes? (ideally: using the community edition)
Edit: this is not a duplicate of How to show all parents and subclasses of a class in IntelliJ IDEA?, as I am looking to combine a condition like "implements X and NOT extends Y".
Works only in Intellij IDEA Ultimate Edition:
The only thing that comes into my mind to sort of solve your problem directly with Intellij IDEA is to generate the uml class diagramm of your Action interface.
This lets you search visually for hierarchy patterns.
Here is a diagramm for the JTextComponent as an example:
Another approach - Using the right tool for the job
jqassistant is a tool that analyses your java code and its relations and stores that into a neo4j database.
This enables you to describe your problem as graph query with cypher.
The easiest way to get started is to
download the binary distribution
jqassistant
run ./bin/jqassistant.sh scan -f your_application.jar, then
start the server via ./bin/jqassistant.sh server
and open http://localhost:7474/browser/
alternatively use the Intellij plugin for jqassistant
Example:
The query for finding all classes implementing aInteface would look like
MATCH (i:Interface {name:"aIntefaces"} )<-[:IMPLEMENTS]- (c) RETURN i,c
A query to your problem would look like:
MATCH
(i:Interface {name:'Action'} )<-[:IMPLEMENTS|EXTENDS*1..10]- (class),
(abstractAction:Class {name:'AbstractAction'})
where not (class)-->(abstractAction)
RETURN class
I've started learning Liferay (6.2) about a week ago for a project. I've used "pure" Java EE before (JSP, JSF, etc.) with JPA (EclipseLink).
What I can't understand is:
How to use ServiceBuilder to create entities that behave like the ones I defined before For e.g.: if I define a Category and a CategoryProperty entity, which are in a one-to-many relationship, I can only define a finder to the CategoryProperty which returns all the CategoryPropertys by the parent categoryId.
Based on the book I'm reading, I can only modify the implementation of the CategoryLocalServiceImpl and the CategoryPropertyLocalServiceImpl and can't touch the generated entities. So if I want to list every CategoryProperty which belongs to one Category, I have to implement and call CategoryPropertyLocalServiceUtil.findAllByCategoryId(categoryId) which is not what i want. The category.getCategoryProperties() call would be much more natural.
How do I achieve that without messing up the whole structure? Which generated classes can I touch? what is that I am missing?
Thank you!
Shortly, what you understand is right but it's not the whole story.
You can catch what you want implementing method getCategoryProperties() in CategoryImpl class.
That method will use the finder method you previously made and describe in the question.
I was wondering if I can easily annotate Acceleo templates and then get these annotations when working with TraceabilityModel.
Acceleo is now using an annotation to determine entry points for generation:
[comment #main]
So I am asking, if I can use this mechanism to annotate my templates for other purposes, for example:
[comment #org.project.SimpleStatement]
[template public generateSimpleStatement(...)]
...
[/template]
Then, I could be able to get the annotation programmatically when working with traceability model (probably using the org.eclipse.acceleo.traceability.ModuleElement interface).
Acceleo's traceability does not support either annotations or comments : we only record traceability information for the actually generated text bits, not for any of the "extra" information (comments of the module, main annotation, metamodels ...).
That being answered, and though not possible through the means of an annotation, maybe your use case would be worth an enhancement request? Can you describe what you were expecting to achieve through this? (preferrably through the Eclipse M2T forum since stack overflow does not seem to be appropriate for such discussions ;)).
(Note : I am an active developper on Acceleo)
This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
How and where are Annotations used in Java?
Java beans, annotations: What do they do? How do they help me?
Over and over, I read about Java 5's annotations being an 'advanced feature' of the language. Until recently, I haven't much used annotations (other than the usual #Override, &c), but work on a number of webservice-related projects has forced my hand. Since I learned Java pre-5, I never really took the time to sit down and grok the annotation system.
My question- do you guys actually use annotations? How helpful are they to you, day-to-day? How many StackOverflow-ers have had to write a custom annotation?
Perhaps the most useful and used case of Java Annotations is to use POJO + Annotation instead of xml configuration files
I use it a lot since (as you already stated) if you use a web framework (like spring or seam) they usually have plenty of annotations to help you.
I have recently wrote some annotations to build a custom statemachine, validations purpose and annotations of annotations (using the metadata aspect of it). And IMO they help a lot making the code cleaner, easier to understand and manage.
Current project (200KLOC), annotations I use all the time are:
#NotNull / #Nullabe
#Override
#Test
#Ignore
#ThreadSafe
#Immutable
But I haven't written yet my own annotation... Yet!
I have used annotations for:
Hibernate, so I don't need to keep those huge XML files;
XML Serialization, so I describe how the object should be rendered in the object itself;
Warning removal for warnings that I don't want to disable (and for which the particular case cannot be properly solved).
I have created annotations for:
Describe the state required in order for my method to be executed (for example, that a user must be logged in);
Mark my method as executable from a specific platform with additional properties for that platform;
And probably some other similar operations.
The annotations that I have created are read with Reflection when I need to get more information about the object I am working with. It works and it works great.
Annotations are just for frameworks and they do work great in hibernate/jpa. until you write a framework that needs some extra information from passed to it objects you wont write your own annotations.
however there is new and cool junit feature that let you write your own annotations in tests - http://blog.mycila.com/2009/11/writing-your-own-junit-extensions-using.html
I use annotations daily and they are wonderful. I use them with jsf and jpa and find them much easier to manage and work with than the alternative XML configurations.
I use annotations for describing in my state synchronisation system what classes are specialisations of the annotated classes, and the environment in which they should be used (when an object is created, it will work out for its entity lists which are the best entity classes to create for the nodes on the network; i.e., a Player entity for a server node is instead a ServerPlayer entity). Additionally, the attributes inside the classes are described and how they should be synchronised across machines.
We just used annotations to create a simple way to validate our POJO's:
#NotEmpty
#Pattern(regex = "I")
private String value;
Then we run this through the Hibernate validator which will do all our validation for us:
import org.hibernate.validator.ClassValidator;
import org.hibernate.validator.InvalidValue;
public void validate(T validateMe) {
ClassValidator<T> validator = new ClassValidator<T>((Class<T>) validateMe.getClass());
InvalidValue[] errors = validator.getInvalidValues(validateMe);
}
Works great. Nice clean code.
We use custom annotations as a part of our integration testing system:
#Artifact: Associates an integration test with an issue ID. Trace matrices are then automatically generated for our testing and regulatory departments.
#Exclude: Ignores an integration test based on the browser platform / version. Keeps the IE 6 bugs from clogging up our nightly test runs :)
#SeleniumSession: Defines test specific selenium settings for each integration test.
They are a very powerful tool, but you gotta use them carefully. Just have a look at those early .NET Enterprise class files to see what a nightmare mandatory annotations can be :)
We have a report builder as part of our webapp. A user can add a large number of widgets that are all small variations on the same set of themes (graphs, tables, etc).
The UI builds itself based on custom annotations in the widget classes. (e.g. an annotation might contain default value and valid values that would render as a dropdown. Or a flag indicating if the field is mandatory).
It has turned out be be a good way to allow devs to crank out widgets without having to touch the UI.