Project oriented on minimize efforts when we work with legacy listeners (not only). The main idea is define interface
which annotated as Transmitter and extends legacy interface and you can define fallback and method which you want to
notify in Receiver class. Receiver class is your default POJO class with contains method which we want to notify and
fallback method
and methods for delegate result. And after this declaration on compile steps fa4nir will generate code which you can use
to listening your notifications.
gradle clean build
gradle :fa4nir-test:test
implementation 'io.github.fa4nir:fa4nir:1.0.4'
annotationProcessor 'io.github.fa4nir:fa4nir:1.0.4'
To define Transmitter, write interface and define beanName
to named generated class and define receiverName
to find
necessary receiver. Also you should override methods which need to use in receiver class and not necessary define as
default. Method which we want to use should have annotations @NotifyTo and @FallBackMethod
if necessary.
@Transmitter(beanName = "CustomListenerImpl", receiverName = "custom-listener-receiver")
public interface TransmitterTemplate extends CustomListener {
@Override
@NotifyTo(name = "receiverMethod")
@FallBackMethod(name = "fallBackForReceiverMethod")
void onSuccess(String parameter0,
Integer parameter1,
List<String> parameters2);
@Override
default void onFailure(Throwable t) {
}
@Override
default void onSuccess(String r) {
}
@Override
default void onSuccess1(String parameter0, Double parameters2) {
}
}
The next step is provide receiver. On this stem You should annotate your class as @Receiver
and define unique name for
it, define base method with name which we write in previous step @NotifyTo(name = "receiverMethod")
and define
parameters use annotation @FetchParam(num = 0)
where num is index in base method parameters also you can use name to
find parameters by name. and if you use annotation @FallBackMethod(name = "fallBackForReceiverMethod")
create method
fallback. You can delegate return statement to another methods to do
this @DelegateResultTo(method = "delegatorAcceptor")
where put method name which should received result and can
receive parameters of base method too. Result should be mapped as @FetchResult
.
@Receiver(name = "custom-listener-receiver")
public class ReceiverTemplate {
private static final Logger log = Logger.getLogger(CustomListenerClass2.class.getName());
@DelegateResultTo(method = "delegatorAcceptor")
public Person receiverMethod(@FetchParam(num = 0) String name, @FetchParam(name = "parameters2") List<String> payload) {
log.log(Level.INFO, "Enter: {0}, {1}", new Object[]{name, payload});
return new Person(1L, "Mit9i", "mit9i@gmail.com");
}
public void delegatorAcceptor(@FetchResult Person person,
@FetchParam(num = 0) String name,
@FetchParam(num = 1) Integer payload) {
log.log(Level.INFO, "Message {0}, {1}, {2}", new Object[]{person, name, payload});
}
public void fallBackForReceiverMethod(@ErrorSignal Exception e, @FetchParam(num = 1) Integer number) {
log.log(Level.WARNING, "Message: {0}, {1}", new Object[]{e.getMessage(), number});
}
}
Generated code:
package io.github.fa4nir.examples.impl;
import io.github.fa4nir.examples.receivers.CustomReceiverForCustomListenerCase2;
import io.github.fa4nir.examples.payloads.Person;
import java.lang.Exception;
import java.lang.Integer;
import java.lang.Override;
import java.lang.String;
import java.util.List;
public class CustomListenerImpl implements CustomListener {
private final ReceiverTemplate receiverTemplate;
public CustomListenerCase2(ReceiverTemplate receiverTemplate) {
this.receiverTemplate = receiverTemplate;
}
@Override
public void onSuccess(String parameter0, Integer parameter1, List<String> parameters2) {
try {
Person result = this.receiverTemplate.receiverMethod(parameter0, parameters2);
this.receiverTemplate.delegatorAcceptor(result, parameter0, parameter1);
} catch (Exception e) {
this.receiverTemplate.fallBackForReceiverMethod(e, parameter1);
}
}
// Start block_1
@Override
void onFailure(Throwable t) {
}
@Override
void onSuccess(String r) {
}
@Override
void onSuccess1(String parameter0, Double parameters2) {
}
// End block_1
}
But if you can see block_1
is useless code, so remove it. To do this
@Transmitter(beanName = "CustomListenerImpl", receiverName = "custom-listener-receiver", isSupper=false)
use this isSupper
and set false to it.
Generated code:
Tip: because default methods
package io.github.fa4nir.examples.impl;
import io.github.fa4nir.examples.receivers.CustomReceiverForCustomListenerCase2;
import io.github.fa4nir.examples.payloads.Person;
import java.lang.Exception;
import java.lang.Integer;
import java.lang.Override;
import java.lang.String;
import java.util.List;
public class CustomListenerImpl implements TransmitterTemplate {
private final ReceiverTemplate receiverTemplate;
public CustomListenerCase2(ReceiverTemplate receiverTemplate) {
this.receiverTemplate = receiverTemplate;
}
@Override
public void onSuccess(String parameter0, Integer parameter1, List<String> parameters2) {
try {
Person result = this.receiverTemplate.receiverMethod(parameter0, parameters2);
this.receiverTemplate.delegatorAcceptor(result, parameter0, parameter1);
} catch (Exception e) {
this.receiverTemplate.fallBackForReceiverMethod(e, parameter1);
}
}
}
The next is method fallback:
If you do not need parameters, define like this:
@Receiver(name = "custom-listener-receiver")
public class ReceiverTemplate {
public void fallBackForReceiverMethod(Exception e) {
}
//...
}
If you need parameters, define like this: where annotation @ErrorSignal
is required.
@Receiver(name = "custom-listener-receiver")
public class ReceiverTemplate {
public void fallBackForReceiverMethod(@ErrorSignal Exception e, @FetchParam(name = "parameters1") Integer number) {
}
//...
}
@DelegateResultTo
can be used for any delegated methods:
Example:
@Receiver(name = "custom-listener-receiver")
public class ReceiverTemplate {
private static final Logger log = Logger.getLogger(CustomListenerClass2.class.getName());
@DelegateResultTo(method = "delegatorAcceptor0")
@DelegateResultTo(method = "delegatorAcceptor1")
@DelegateResultTo(method = "delegatorAcceptor2")
//... any
public Person receiverMethod(@FetchParam(num = 0) String name, @FetchParam(name = "parameters2") List<String> payload) {
log.log(Level.INFO, "Enter: {0}, {1}", new Object[]{name, payload});
return new Person(1L, "Mit9i", "mit9i@gmail.com");
}
//...
}
Predicate (mark method as @PayloadPredicate
, and required is method should return boolean)
@Receiver(name = "ReceiverBase")
public class ReceiverWithNameReceivers {
private static final Logger log = Logger.getLogger(ParametersWithNameReceivers.class.getName());
@PayloadPredicate
public boolean isPayloadNotNull(@FetchParam(name = "personName") String payload) {
return Objects.nonNull(payload);
}
//...
}
Example:
public class TransmitterWithNameInParameters implements ParametersWithNameTransmitter {
@Override
public void onSuccess1(String personName, Double personEight) {
// should be like this
if (this.parametersWithNameReceivers.isPayloadNotNull(personName)) {
try {
Person result = this.parametersWithNameReceivers.listenerWithParametersName(personName);
this.parametersWithNameReceivers.receivePersonWithName(result, personName);
this.parametersWithNameReceivers.receivePersonWithNameAndWeight(result, personEight);
} catch (Exception e) {
this.parametersWithNameReceivers.fallbackListenerWithParametersName(e, personName);
}
}
}
}
@ReturnStatement
this annotation mark method which should return result to listener:
Example_1:
@Transmitter(beanName = "CustomListenerImpl", receiverName = "custom-listener-receiver")
public interface TransmitterTemplate extends CustomListener {
@Override
@NotifyTo(name = "receiverMethod")
@FallBackMethod(name = "fallBackForReceiverMethod")
Person onSuccess(String parameter0,
Integer parameter1,
List<String> parameters2);
@Override
default void onFailure(Throwable t) {
}
@Override
default void onSuccess(String r) {
}
@Override
default void onSuccess1(String parameter0, Double parameters2) {
}
}
@Receiver(name = "custom-listener-receiver")
public class ReceiverTemplate {
private static final Logger log = Logger.getLogger(CustomListenerClass2.class.getName());
@ReturnStatement
@DelegateResultTo(method = "delegatorAcceptor0")
@DelegateResultTo(method = "delegatorAcceptor1")
@DelegateResultTo(method = "delegatorAcceptor2")
//... any
public Person receiverMethod(@FetchParam(num = 0) String name, @FetchParam(name = "parameters2") List<String> payload) {
log.log(Level.INFO, "Enter: {0}, {1}", new Object[]{name, payload});
return new Person(1L, "Mit9i", "mit9i@gmail.com");
}
//...
}
Generated code:
public class TransmitterWithNameInParameters implements ParametersWithNameTransmitter {
@Override
public Person onSuccess1(String personName, List<String> payload) {
Person result;
if (this.parametersWithNameReceivers.isPayloadNotNull(personName)) {
try {
result = this.parametersWithNameReceivers.receiverMethod(personName);
this.parametersWithNameReceivers.receivePersonWithName(result, personName);
this.parametersWithNameReceivers.receivePersonWithNameAndWeight(result, payload);
} catch (Exception e) {
this.parametersWithNameReceivers.fallbackListenerWithParametersName(e, personName);
}
}
return result;
}
}
Example_2:
@Transmitter(beanName = "CustomListenerImpl", receiverName = "custom-listener-receiver")
public interface TransmitterTemplate extends CustomListener {
@Override
@NotifyTo(name = "receiverMethod")
@FallBackMethod(name = "fallBackForReceiverMethod")
Person onSuccess(String parameter0,
Integer parameter1,
List<String> parameters2);
@Override
default void onFailure(Throwable t) {
}
@Override
default void onSuccess(String r) {
}
@Override
default void onSuccess1(String parameter0, Double parameters2) {
}
}
@Receiver(name = "custom-listener-receiver")
public class ReceiverTemplate {
private static final Logger log = Logger.getLogger(CustomListenerClass2.class.getName());
@DelegateResultTo(method = "delegateMethod")
public int receiverMethod(@FetchParam(num = 0) String name, @FetchParam(name = "parameters2") List<String> payload) {
log.log(Level.INFO, "Enter: {0}, {1}", new Object[]{name, payload});
return 10;
}
public Person delegateMethod(@FetchResult int index) {
log.log(Level.INFO, "Enter: {0}, {1}", new Object[]{name, payload});
return new Person(index, "Mit9i", "mit9i@gmail.com");
}
//...
}
Generated code:
public class TransmitterWithNameInParameters implements ParametersWithNameTransmitter {
@Override
public Person onSuccess1(String personName, List<String> payload) {
Person result;
if (this.parametersWithNameReceivers.isPayloadNotNull(personName)) {
try {
int secondResult = this.receiverTemplate.receiverMethod(personName);
result = this.receiverTemplate.delegateMethod(secondResult);
} catch (Exception e) {
this.parametersWithNameReceivers.fallbackListenerWithParametersName(e, personName);
}
}
return result;
}
}
Spring Bean example:
@SpringBean
@Transmitter(beanName = "CustomListenerImpl", receiverName = "custom-listener-receiver")
public interface TransmitterTemplate extends CustomListener {
@Override
@NotifyTo(name = "receiverMethod")
@FallBackMethod(name = "fallBackForReceiverMethod")
Person onSuccess(String parameter0,
Integer parameter1,
List<String> parameters2);
@Override
default void onFailure(Throwable t) {
}
@Override
default void onSuccess(String r) {
}
@Override
default void onSuccess1(String parameter0, Double parameters2) {
}
}
@Receiver(name = "custom-listener-receiver")
public class ReceiverTemplate {
private static final Logger log = Logger.getLogger(CustomListenerClass2.class.getName());
@DelegateResultTo(method = "delegateMethod")
public int receiverMethod(@FetchParam(num = 0) String name, @FetchParam(name = "parameters2") List<String> payload) {
log.log(Level.INFO, "Enter: {0}, {1}", new Object[]{name, payload});
return 10;
}
public Person delegateMethod(@FetchResult int index) {
log.log(Level.INFO, "Enter: {0}, {1}", new Object[]{name, payload});
return new Person(index, "Mit9i", "mit9i@gmail.com");
}
//...
}
Generated code:
@Component
public class TransmitterWithNameInParameters implements ParametersWithNameTransmitter {
@Override
public Person onSuccess1(String personName, List<String> payload) {
Person result;
if (this.parametersWithNameReceivers.isPayloadNotNull(personName)) {
try {
int secondResult = this.receiverTemplate.receiverMethod(personName);
result = this.receiverTemplate.delegateMethod(secondResult);
} catch (Exception e) {
this.parametersWithNameReceivers.fallbackListenerWithParametersName(e, personName);
}
}
return result;
}
}