Setting the #component bean name in mapstruct mapper - mapstruct

I know I can create a mapper like this:
#Mapper(componentModel="spring")
public interface MyMapper{
That will result in:
#Component
public class MyMapperImpl{
How can I set the bean name obtaining:
#Component("name")
public class MyMapperImpl{

This is currently not supported. This is issue mapstruct/mapstruct#1427 requested for this feature.
Depending on how your name should look like you can use a custom AnnotationBeanNameGenerator to generate the mappers that are component scanned.

Related

Can I load a class from a specific class annotation value

I have classes with annotation like below. I know I can use reflections to get all classes with this type of annotation. But is there a way I can just load the class with the specific annotation name="demo1"?
#Demo(name="test_number")
public class Test1{
....
}
#Demo(name="test_string")
public class Test2{
....
}
You can read all the annotated classes, inspect annotation details, and filter classes with name ="demo1" only.
There is an API to read annotations details, read this article:
https://medium.com/#nadundesilva/reading-annotations-at-run-time-using-the-java-reflections-api-ce175ba43b2

AEM ResourceResolverFactory null in HTL component java class

I have a HTL component class like
MyComponent extends WCMUser{
#Reference
private ResourceResolverFactory resourceResolverFactory;
But when i am trying to use it i am getting NullPointerException on same.
I even tried using #Service & #Component SCR tags but no help.
You cannot use #Reference or other annotations with your Java Use API since it is not treated as an OSGi service. Instead use the getSlingScriptHelper() to get the SlingScriptHelper object which can then be used to get the services.
public MyComponent extends WCMUsePojo {
public void activate() {
getSlingScriptHelper().getService(<<SomeService.class>>);
}
}
However if it is only the ResourceResolver that you need you can call the getResourceResolver() method available within WCMUsePojo class.
More information on Java Use-API can be found in this official doc.
Got it, so i can create another service, get ResourceResolverFactory there. Once there i can use ResourceResolverFactory in this service or pass it to WCMUse class.

Is there a global setting in Mapstruct that will trim a string value prior to setting it to a destination bean property

Is it possible to trim a string value before it is set against a bean property of type string in the destination bean?
Dozer offers such a facility through its mapping configuration for example,
<configuration>
<trim-strings>true</trim-strings>
</configuration>
Also see Dozer Global Configuration
With MapStruct 1.0.0.Final I can achieve this through Expressions or Before/After Mapping customization.
But wanted to know if there is a better way to handle such use cases.
Thanks in advance.
It appears MapStruct in its current form does not support this.
However one can achieve this effect with custom mapper methods, for example implement a class with a method that trims a String argument passed to it and then reference this class in the use attribute of the #Mapper annotation.
More at Invoking other mappers
If you require fine gained access control you could use
Selection based on Qualifiers
I was made aware of these approaches in response to a question I posted in mapstruct Google group
Example from #venkat-srinivasan answer's:
public class StringTrimmer {
public String trimString(String value) {
return value.trim();
}
}
and then in your mapper interface or class:
#Mapper(uses = StringTrimmer.class)
public interface MyMapper {

Serialization Exception while making an RPC call

I have created a very basic application. I have only one service class and a corresponding Async class which contains only Java types and no custom classes. But still I get the serialization exception.
My service class looks like this.
public interface MyService extends RemoteService {
public String getName();
public Object getAdditionalDetials(ArrayList<String> ids);
public Date getJoiningDate();
}
My async interface looks like this
public interface MyServiceAsync {
public void getName(AsyncCallback<String> callback);
public void getAdditionalDetials(ArrayList<String> ids, AsyncCallback<Object> callback);
public void getJoiningDate(AsyncCallback<Date> callback);
}
I know I am making some stupid mistake.
I am Naive in gwt rpc and serialization mechanism, but will try to answer your question.
Whenever you write classes involving an RPC, GWT creates a Serialization Policy File. The serialization policy file contains a whitelist of allowed types which may be serialized.
In your Service methods, all the types you mention and refer will be automatically added to this list if they implements IsSerializable. In your case you have used the following two methods,
public String getName();
public Date getJoiningDate();
Here you have used String and Date as your return types and hence it is added to your Serialization Policy File. But in the below method their lies a problem,
public Object getAdditionalDetials(Arraylist<String> ids);
Here you have used ArrayList and String that is not a problem and they will be added to your whitelist, but the problem is you have mentioned return type as Object. Here GWT Compiler does not know what type to be added to whitelist or Serialization Policy and hence it wont pass your RPC call. The solution is use mention a class which implements IsSerializable instead of mentioning the return type of type Object.
FWIW, I was having this problem but my 'Object' type was hidden behind generified classes.
So if one of your rpc methods involves a class:
class Xxx<T> implements IsSerializable {...
It needs to change to:
class Xxx<T extends IsSerializable> implements IsSerializable {...

cannot find my bean using the InitialContext.lookup() method

I have tried to use struts 1.3 API to make a small application with EJB 3.0. Unfortunatelly i cannot use the #EJB annotation to call my bean object from inside my action class. I have solved this problem using different workarounds ( the first one is to use my global jndi name of my bean and the other is to call another class first and use the #EJB annotation from that class). Still these two workarounds have significant disadvantages. I would like to call my EJB directly from my action class. I have read plenty examples using the "java:comp/env/beanName" JNDI name but still haven't figure out how to do it and get name not found axception.
Let the full name of the local EJB class be the com.ejb.myEjbPackage.MyEJBLocal, how can i call it using the context lookup? (can i do it without modifying any of the web.xml and sun-web.xml descriptors?)
I am using glassfish server and Netbeans IDE.
Thank you in advance
#EJB won't work in a standard pojo it can only be done in a managed object (i.e. another session bean)
So...
Here's your bean
#Stateless(mappedName="beanName")
public class beanName implements beanNameRemote {
Here's your lookup
Context context = new InitialContext(); //default lookup pulls from jndi properties file
context.lookup("beanName");
You can do some further reading on the mappedName to see if you want to use it or not.
I found the answer :
If you cannot use the EJB annotation in the class you want to call the bean then :
If you don't want to mess with XML descriptors to define your bean , you have to do it in the bean class itself.
Hence i used the following annotation in the GameBean class
#Stateless
#EJB(name="ejb/GameBean",beanInterface=GameBeanLocal.class,beanName="GameBean")
public class GameBean implements GameBeanLocal {.....
The beanName is optional. The annotation must be declared in the line ABOVE the declaration of the class.
Then, in order to call the bean from the other class you can do
InitialContext ic = new InitialContext();
ic.lookup("java:comp/env/ejb/GameBean");