Abstract Class in Acceleo Transformation - transformation

how to show the abstract class in generate.mtl file of Accelo transformation into java.
Currently, I am writing this code but it's not working...
[if (aClass.isAbstract=true)]
public abstract class [aClass.name.toUpperFirst()/]
[/if]
[if (aClass.isAbstract=false)]
public class [aClass.name.toUpperFirst()/]
[/if]

Related

How to determine the effective class (Bean) to be used when using an interface as a class member using Spring Boot?

Is it possible to achieve the following?
I want to determine the type of a class to be used at runtime with Spring Boot. Hence, I defined an interface MyInterface defining the required methods:
public interface MyInterface<C extends DocumentContext> {
MyResult<C> doForX(C documentContext);
MyResult<C> doForY(C documentContext);
}
An abstract base class implements this interface and provide some common methods:
#Slf4j
#Component
public abstract class BaseClass<C extends DocumentContext> implements MyInterface<C> {
private MyInterface myInterface;
...
public MyResult<C> doForX(C documentContext) { ... }
public Myresult<C> doForY(C documentContext) { ... }
}
This base class is the parent for two subclasses:
#RequiredArgsConstructor
#Slf4j
#Component
#ConditionalOnProperty(name = "sanitizerType", havingValue = "REGEX", matchIfMissing = false)
public class FirstClass<C extends documentContext> extends BaseClass<C> implements<MyInterface<C> {
...override base methods
}
#RequiredArgsConstructor
#Slf4j
#Component
#ConditionalOnProperty(name = "sanitizerType", havingValue = "SAX", matchIfMissing = false)
public class SecondClass<C extends documentContext> extends BaseClass<C> implements<MyInterface<C> {
...override base methods
}
A class using one of the two concrete subclasses:
public class MyUsingClass extends AnotherClass {
public MyUsingclass(MyInterface<ADocumentContext> myInterfaceImpl, ...)
...
}
This compiles but when I try to run the application I get:
*************************** APPLICATION FAILED TO START
Description:
Parameter 1 of constructor in MyUsingClass required a bean of type
'MyInterface' that could not be found.
Action:
Consider defining a bean of type 'MyInterface' in your configuration.
In my application.properties I have:
# ... [SAX | REGEX]
#sanitizerType=REGEX
...and I have a Properties class:
#Value("${sanitizerType:REGEX}")
private SanitizerType sanitizerType;
, whereby SanitizerType is just:
public enum SanitizerType {
REGEX, SAX
}
You said you would like to "determine the type of a class to be used at runtime with Spring Boot".
I'm not sure if you want your "class to be used" change while your application is running depending on current condidionts or set once when the application boots and use it always until the app is running.
If you uncomment this line of your application.properties #sanitizerType=REGEX
Your code should work - but it simply defines the SanitizerType (hence your MyInterface implementation) once when you start your application.
Please note that by setting a private field of Properties class you don't set the property globally (at least not the way you showed in the question), but only set the private field value either according what's set in your properties file or (if value is missing in properties) to "REGEX".
If you want to use it in different places of your program you need to inject it differently

Add to Jhipster generator AbstractServices and use them in ElasticsearchIndexService

we suggest an possible improve to jhipster generator future versions.
Is possible you add this abstract classes to the generator and when generator create services extends of that by default, then you reduce a lot of duplication code.
And improve changing JPARepositories list to AbstractServices list in ElasticsearchIndexService.
When we use DTOs:
public abstract class AbstractCrudElasticServiceImpl, S extends ElasticsearchRepository> implements ElasticCrudMethodService { ...
public abstract class AbstractCrudElasticServiceImpl, S extends ElasticsearchRepository> implements ElasticCrudMethodService { ...
When we donĀ“t use DTOs:
public abstract class AbstractCrudDomainElasticServiceImpl> implements ElasticCrudMethodService ...
public abstract class AbstractCrudDomainServiceImpl implements CrudMethodService { ...
Detail:
All services extends any of these Abstract clases without methods.
Abstract clases contains generic methods, you only #Override in subclases when you have a particular behaviour.
And very important we add a new method reindexData in Elastic services that by default calls to findAll, then in ElasticsearchIndexService we call to reindexData of:
=> private final List servicesList;

How to write test class with #Autowired variable for inherited class

I have problem with writing test cases using SPOCK. Could anyone please help me?
I have classes & interfaces like below,
//Helper class
public class ObjClass{
//Defining all property variables & corresponding getters & setters methods.
}
//Interface
public interface B{
//Declaring custom methods for Mongo repository.
public int getId();
}
public interface A extends MongoRepository<ObjClass, Serializable>, B{
//Defining some standard MongoRepository methods here
}
// Implementation Classes
public class Aimpl implements B{
//implementing all B interface methods
}
public class ctrlClass{
#Autowired
A aObj;
public int getIdValue(){
return aObj.getId();
}
}
And below is the corresponding SPOCK test cases:
class test extends Specification
{
ctrlClass obj1
A obj2 //interface class object
def setup(){
obj1 = new ctrlClass();
obj2 = new Aimpl(); //Creating object for interface using impl class.
obj1.aObj = obj2
}
def "test"(){
when:
def a = obj2.getIdValue()
then:
//validating some conditions here with 'a' value
}
}
Getting below error while executing above test case,
Cannot cast object Aimpl to class A.
The same above scenario is working fine with Spring #Autowired. But not in Spock.
*
Is there any alternate available for #Autowired in SPOCK? Please suggest me some solutions & your comments.
*
The problem you have is the ability of Spring to bind the interface with the related implementation.
If your interface has only one implementation and the single implementation has the annotation #Component with Spring's component scan enabled, than Spring framework success to infer the relationship between the interface and its implementation.
In case the component scan is not enabled, then the bean should be explicitly defined in your spring configuration file (such as application-config.xml).
The casting of Aimpl and A cannot succeed because the inheritance classes/interface are different.
You should change the code like the following:
public class ctrlClass{
#Autowired
Aimpl aObj;
public int getIdValue(){
return aObj.getId();
}
}
And in the test class make the following change:
A obj2 //interface class object
Should be changed to:
Aimpl obj2

Auto-wiring Multiple implementation of a Abstract class

I have been working on a spring MVC project structure where multiple concrete service classes extends from a Abstract Class.
In my controller, i am trying to autowire the abstract class and choose the implementation based on the user choice. Here's the relevant portion of Controller class:
#Controller
#RequestMapping("/")
public class DashboardController {
#Autowired
LogAnalyzerAbstract logAnalyzer;//new LogAnalyzer();
private static final Log logger =LogFactory.getLog(DashboardController.class);
....
logAnalyzer.process();
}
I want to the controller to use the implementation based on the user input and used the Abstract class LogAnalyzer reference in the further implementaion.
Is my logic valid? Can you guide me through?
If I understand what you ask correctly, what you need to do is to create several Spring-MVC controllers, one for each use case, with its own base path, and to autowire there the abstract service class (or the service interface), based on the bean name of the concrete service (if you use the annotation #Service on concrete service classes, the bean name should be the name of the concrete service class, starting with a lowercase letter).
For example, something like the following:
#Service
public class MyFirstUseCaseService extends AbstractService {
...
}
and in the controller
#Controller
#RequestMapping("/firstUseCaseBaseUrl")
MyFirstUseCaseController {
#Autowired
#Qualifier("myFirstUseCaseService")
private AbstractService service;
....
}

Inject a list of classes that extends an abstract class with Spring

Hy,
I have the next code:
public abstract class MyClass{
protected abstract void method1();
}
Classes that extend the first one:
#Component
public class MyClass1 extends MyClass{
.....
}
#Component
public class MyClass2 extends MyClass{
.....
}
My class where I try to inject list of classes that extends an abstract class
#Component
public class SpringClass{
#Autowired **//It doesnt work, nothing is inyected!**
List<MyClass> classes
}
My problem is it doesnt work, it doesnt inject the list of classes that extend MyClass in property classes. Why?
Thanks
You can remove #Autowired annotation for the instance variable and add it to the setter method. After doing this your spring class would be
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
#Component
public class SpringClass {
List<MyClass> classes;
#Autowired
public void setClasses(List<MyClass> classes) {
this.classes = classes;
}
}
Hope this helps.
#Component
public class SpringClass {
#Autowired
private Map<String, YourInterface> map;
}
String in map will be contain all classes name that implements the YourInterface as String.
if you want to get all instances - use map.values()
if you want to get specific instance - get it by class name.
in additional, you can customize the key by another recognize such as Enum.
in this case - you need to configure this as #Bean
as bellow :
#Configuration
public class CalculationHandlerConfig {
#Bean
public HashMap<OperatorTypeEnum, CalculatorService> CalculationHandlers(Map<String, CalculatorService> beansMap) {
HashMap<OperatorTypeEnum, CalculatorService> map = new HashMap<>();
for (CalculatorService bean : beansMap.values()) {
map.put(bean.getOperatorType(), bean);
}
return map;
}
}
It looks like it could be dependent on the version of Spring being used, however, you may also want to try using an interface that all the desired classes implement, and injecting the list referencing the interface.
In other words, instead of this..
List<AbstractOrConcreteBaseClass>
use...
List<Interface>

Resources