Need to call multiple EJBs based on the input string - java

I have a pojo class where in I have to call multiple ejbs based on the input string. For example , if the input is a x, I have to call XServiceBean, and if it is Y, I have to call YServiceBean.
I am planning to parameterise the input string x and the respective service bean in the database or xml. I do not want to put multiple if conditions or switch cases to call the service bean based on the input string.
Is there any simple pattern that i can use to achieve this. would be helpful if you can give some example
thank you

Main class where you can run as java for testing purpose
package stack;
public class ServiceInit
{
public static void main(String[] args)
{
new ServiceInit();
}
public ServiceInit()
{
ServiceBeanInterface xbean = ServiceFactory.getInstance().getServiceBean("X");
xbean.callService();
ServiceBeanInterface ybean = ServiceFactory.getInstance().getServiceBean("Y");
ybean.callService();
}
}
Service Factory which returns the bean that you want to call
package stack;
public class ServiceFactory
{
/*
* you can do it with factory and class reflection if the input is always the prefix for the service bean.
*/
private static ServiceFactory instance;
// the package name where your service beans are
private final String serviceBeanPackage = "stack.";
private ServiceFactory()
{
}
public static ServiceFactory getInstance()
{
if (instance == null)
{
instance = new ServiceFactory();
}
return instance;
}
#SuppressWarnings("unchecked")
public ServiceBeanInterface getServiceBean(String prefix)
{
ServiceBeanInterface serviceBean = null;
try
{
Class<ServiceBeanInterface> bean = (Class<ServiceBeanInterface>) Class
.forName(serviceBeanPackage + prefix + "ServiceBean");
serviceBean = bean.newInstance();
}
catch (ClassNotFoundException | InstantiationException | IllegalAccessException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return serviceBean;
}
}
The interface which is implemented by your service classes
package stack;
public interface ServiceBeanInterface
{
void callService();
}
XServiceBean class
package stack;
public class XServiceBean implements ServiceBeanInterface
{
#Override
public void callService()
{
System.out.println("I am X");
}
}
YServiceBean class
package stack;
public class YServiceBean implements ServiceBeanInterface
{
#Override
public void callService()
{
System.out.println("I am Y");
}
}

Related

Handle duplicate code in concrete implementations of an interface in Spring boot application

I am working on a spring boot application, where I have an interface I as follows:
public interface I {
String getType();
void f1();
}
There are two classes implementing interface I as follows:
#Component
class A implements I {
private final MyRepo1 myRepo1;
private final Helper helper;
public A(MyRepo1 myRepo1, Helper helper) {
this.myRepo1 = myRepo1;
this.helper = helper;
}
#Override
public String getType() {
return "type1";
}
#Override
public void f1(String type) {
int response = helper.f1(type);
if(response != -1) {
return;
}
//Add type1 specific handling here
}
}
One more class B implementing interface I as follows:
#Component
class B implements I {
private final MyRepo2 myRepo2;
private final Helper helper;
public B(MyRepo2 myRepo2, Helper helper) {
this.myRepo2 = myRepo2;
this.helper = helper;
}
#Override
public String getType() {
return "type2";
}
#Override
public void f1(String type) {
int response = helper.f1(type);
if(response != -1) {
return;
}
//Add type2 specific handling here
}
}
Helper is as follows:
#Component
class Helper {
public int f1(String type) {
...
}
}
I have a factory class as follows, that is used to fetch an object of the appropriate type:
#Component
public class ServiceFactory {
private final Map<String, I>
typeToClassMap = new HashMap<>();
public ServiceFactory(List<I> components) {
for(I component : components) {
typeToClassMap.put(component.getType(), component);
}
}
}
This ServiceFactory is basically used to get objects according to the type.
Now, the problem is, here for sake of simplicity I have just shown two classes implementing the interface. But actually, I have a lot more classes than this, implementing the interface I.
Some of the classes may have the same implementation of f1(), resulting in duplicate code.
I cannot make f1() as the default method in interface I as this requires the dependent bean.
I cannot understand what is the best way to handle this.
Could anyone please help here?

Create object in function based on Class argument

I want to define a function that creates different type objects that share the same base class. I'd like to pass in the object type and have the function creating the object and then modifying its attributes. The problem is that the main class from which all these objects are created, does not have the object's attributes so the code fails to compile.
Example:
public void new_generic_report(Class report_class, String report_name) {
Report new_report = this.reportManager.createReport(report_class);
new_report.set_name(report_name);
}
Calling new_generic_report(GreenReport.class, "green_report"); fails because new_report is of the class Report instead of GreenReport so it does not have the .set_name method.
I know I could implement the .set_name method (and other common methods) in the main Report class but I am writing code to interface with an API that I cannot modify.
If you are sure that createReport returns an instance of the correct class you can just do a cast:
((SpecialClass)new_report).set_name(report_name);
An alternative is to use reflection:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test {
static class Base {};
static class Child extends Base {
public void setName(final String name) {
System.out.println("setName("+name+")");
}
}
public static void main(String[] args) {
new Test().new_generic_report(Child.class, "Testname");
}
public void new_generic_report(final Class clazz, final String name) {
Base base = createBase(clazz);
try {
Method m = clazz.getMethod("setName", String.class);
m.invoke(base, name);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
private Base createBase(Class report_class) {
return new Child();
}
}
Of course this only works, if the returned instance implements the method.
Create a parent class for your report for instance :
public abstract class NamedReport extends Report
{
public abstract void setName(String name);
}
class GreenReport extends NamedReport {
#Override
public void setName(String name) {
}
}
Then simply cast your class in your method :
public void new_generic_report(Class report_class, String report_name) {
Report new_report = this.reportManager.createReport(report_class);
if (new_report instanceof NamedReport)
{
((NamedReport)new_report).set_name(report_name);
}
}

CDI injection in recursive structure

Suppose I have two real implementations A and B of some interface. And there is also a Delegate-implemenation of that interface that delegates to either A or B dependending on some logic.
I want to have the Delegate injected into my client class so I marked A and B as #Alternatives to make that unambiguous. However, now the injection into the Delegate does not work since A and B are alternatives.
Any suggestions on how to solve this?
import org.jglue.cdiunit.AdditionalClasses;
import org.jglue.cdiunit.CdiRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
import javax.enterprise.inject.Alternative;
import javax.inject.Inject;
#RunWith(CdiRunner.class)
#AdditionalClasses({ CdiTest.A.class, CdiTest.B.class, CdiTest.Delegate.class })
public class CdiTest {
public interface Service {
void run();
}
#Alternative
public static class A implements CdiTest.Service {
#Override
public void run() {
System.out.println("Hi from A");
}
}
#Alternative
public static class B implements CdiTest.Service {
#Override
public void run() {
System.out.println("Hi from B");
}
}
public static class Delegate implements CdiTest.Service {
int counter = 0;
#Inject A a;
#Inject B b;
#Override
public void run() {
System.out.println("Hi from Delegate");
if ((counter++) % 2 == 0) a.run();
else b.run();
}
}
#Inject
private Service service;
#Test
public void test() {
service.run();
}
}
I think tha you need qualifiers instead of alternatives.
Have you tried using two qualifiers ServiceA and ServiceB? You could inject in the delegate both implementations and in real test the delegate.
EDIT
I don't think you should replace the delegate with a producer (from your example I understood that the delegate has some functional role in your application and is not only a
test/production switch).
I think that you could create another class with a producer method like this:
public class ServiceProducer {
private static final String SERVICE_A = "service-a";
private static final String SERVICE_B = "service-a";
private static final String SERVICE_DELEGATE = "service-delegate";
#Produces
#Chosen
public CdiTest.Service getService(#SystemProperty("service.choose.key") String chosenKey,
#ServiceA Instance<Service> a,
#ServiceB Instance<Service> b,
#ServiceDelegate Instance<Service> delegate) {
switch(chosenKey) {
case SERVICE_A:
return a.get();
case SERVICE_B:
return b.get();
case SERVICE_DELEGATE:
return delegate.get();
default:
throw new IllegalStateException("No Service implementation for type " + chosenKey);
}
}
}
The #SystemProperty is a useful solution to inject system properties found at http://juraj.blahunka.eu/2014/05/17/inject-jboss-system-properties/
So you example code could be changed in:
public class CdiTest {
public interface Service {
void run();
}
#ServiceA
public static class A implements CdiTest.Service {
#Override
public void run() {
System.out.println("Hi from A");
}
}
#ServiceB
public static class B implements CdiTest.Service {
#Override
public void run() {
System.out.println("Hi from B");
}
}
#ServiceDelegate
public static class Delegate implements CdiTest.Service {
int counter = 0;
#Inject #ServiceA Service a;
#Inject #ServiceB Service b;
#Override
public void run() {
System.out.println("Hi from Delegate");
if ((counter++) % 2 == 0) a.run();
else b.run();
}
}
#Inject
#Chosen
private Service service;
#Test
public void test() {
service.run();
}
}
This way you inject implementations A and B inside the delegate (without using the producer) and the produced one in your test class (choosing the correct implementation with a system property named "service.choose.key").

How to call instance of variety of classes in java

I create a class to handle some specific job that use variety of classes on my project.
But after finish the job class must call-back specific method on the called classes.
I use interface to handle this call-back method.
How can I store the called class?
I can get the instance from constructor but I'm looking for generic way.
Your question is not clear but it may be possible that you have missed the fact that classes can implement more than one interface.
public interface DoesAJob {
public void doIt();
}
public interface Finishes {
public void finish();
}
class AThing implements DoesAJob, Finishes {
#Override
public void doIt() {
}
#Override
public void finish() {
}
}
private void doTheJob(DoesAJob thing) {
thing.doIt();
}
private void finishUp(Finishes thing) {
thing.finish();
}
public void test() {
AThing thing = new AThing();
doTheJob(thing);
finishUp(thing);
}
You can use just Java Interface, or use Java Reflection.
First the Interface
package test;
public interface MyClassInterface {
public String getName();
}
next, the Interface Implementation
package test;
public class MyClassImplementation implements MyClassInterface {
String name;
public MyClassImplementation() {
name= "Whatever";
}
public String getName() {
return name;
}
}
finally invoke the class. just Interface example:
package test;
public class MainTest {
public static void main(String[] args){
MyClassInterface myClassImplementation = new MyClassImplementation();
System.out.println(myClassImplementation.getName());
}
}
Using Reflection example:
package test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MainTest {
public static void main(String[] args)
throws InstantiationException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException, NoSuchMethodException, SecurityException {
//using reflection
Object otherClassImplementation=null;
try {
Class<?> cls = Class.forName("test.MyClassImplementation");
otherClassImplementation = cls.newInstance();
Method method = cls.getMethod("getName");
System.out.println(method.invoke(otherClassImplementation));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}

How to 'wrap' two classes with identical methods?

I have to handle two classes with identical methods but they don't implement the same interface, nor do they extend the same superclass. I'm not able / not allowed to change this classes and I don't construct instances of this classes I only get objects of this.
What is the best way to avoid lots of code duplication?
One of the class:
package faa;
public class SomethingA {
private String valueOne = null;
private String valueTwo = null;
public String getValueOne() { return valueOne; }
public void setValueOne(String valueOne) { this.valueOne = valueOne; }
public String getValueTwo() { return valueTwo; }
public void setValueTwo(String valueTwo) { this.valueTwo = valueTwo; }
}
And the other...
package foo;
public class SomethingB {
private String valueOne;
private String valueTwo;
public String getValueOne() { return valueOne; }
public void setValueOne(String valueOne) { this.valueOne = valueOne; }
public String getValueTwo() { return valueTwo; }
public void setValueTwo(String valueTwo) { this.valueTwo = valueTwo; }
}
(In reality these classes are larger)
My only idea is now to create a wrapper class in this was:
public class SomethingWrapper {
private SomethingA someA;
private SomethingB someB;
public SomethingWrapper(SomethingA someA) {
//null check..
this.someA = someA;
}
public SomethingWrapper(SomethingB someB) {
//null check..
this.someB = someB;
}
public String getValueOne() {
if (this.someA != null) {
return this.someA.getValueOne();
} else {
return this.someB.getValueOne();
}
}
public void setValueOne(String valueOne) {
if (this.someA != null) {
this.someA.setValueOne(valueOne);
} else {
this.someB.setValueOne(valueOne);
}
}
public String getValueTwo() {
if (this.someA != null) {
return this.someA.getValueTwo();
} else {
return this.someB.getValueTwo();
}
}
public void setValueTwo(String valueTwo) {
if (this.someA != null) {
this.someA.setValueTwo(valueTwo);
} else {
this.someB.setValueTwo(valueTwo);
}
}
}
But I'm not realy satisfied with this solution. Is there any better / more elegant way to solve this problem?
A better solution would be to create an interface to represent the unified interface to both classes, then to write two classes implementing the interface, one that wraps an A, and another that wraps a B:
public interface SomethingWrapper {
public String getValueOne();
public void setValueOne(String valueOne);
public String getValueTwo();
public void setValueTwo(String valueTwo);
};
public class SomethingAWrapper implements SomethingWrapper {
private SomethingA someA;
public SomethingWrapper(SomethingA someA) {
this.someA = someA;
}
public String getValueOne() {
return this.someA.getValueOne();
}
public void setValueOne(String valueOne) {
this.someA.setValueOne(valueOne);
}
public String getValueTwo() {
return this.someA.getValueTwo();
}
public void setValueTwo(String valueTwo) {
this.someA.setValueTwo(valueTwo);
}
};
and then another class just like it for SomethingBWrapper.
There, a duck-typed solution. This will accept any object with valueOne, valueTwo properties and is trivially extensible to further props.
public class Wrapper
{
private final Object wrapped;
private final Map<String, Method> methods = new HashMap<String, Method>();
public Wrapper(Object w) {
wrapped = w;
try {
final Class<?> c = w.getClass();
for (String propName : new String[] { "ValueOne", "ValueTwo" }) {
final String getter = "get" + propName, setter = "set" + propName;
methods.put(getter, c.getMethod(getter));
methods.put(setter, c.getMethod(setter, String.class));
}
} catch (Exception e) { throw new RuntimeException(e); }
}
public String getValueOne() {
try { return (String)methods.get("getValueOne").invoke(wrapped); }
catch (Exception e) { throw new RuntimeException(e); }
}
public void setValueOne(String v) {
try { methods.get("setValueOne").invoke(wrapped, v); }
catch (Exception e) { throw new RuntimeException(e); }
}
public String getValueTwo() {
try { return (String)methods.get("getValueTwo").invoke(wrapped); }
catch (Exception e) { throw new RuntimeException(e); }
}
public void setValueTwo(String v) {
try { methods.get("setValueTwo").invoke(wrapped, v); }
catch (Exception e) { throw new RuntimeException(e); }
}
}
You can use a dynamic proxy to create a "bridge" between an interface you define and the classes that conform but do not implement your interface.
It all starts with an interface:
interface Something {
public String getValueOne();
public void setValueOne(String valueOne);
public String getValueTwo();
public void setValueTwo(String valueTwo);
}
Now you need an InvocationHandler, that will just forward calls to the method that matches the interface method called:
class ForwardInvocationHandler implements InvocationHandler {
private final Object wrapped;
public ForwardInvocationHandler(Object wrapped) {
this.wrapped = wrapped;
}
#Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Method match = wrapped.getClass().getMethod(method.getName(), method.getParameterTypes());
return match.invoke(wrapped, args);
}
}
Then you can create your proxy (put it in a factory for easier usage):
SomethingA a = new SomethingA();
a.setValueOne("Um");
Something s = (Something)Proxy.newProxyInstance(
Something.class.getClassLoader(),
new Class[] { Something.class },
new ForwardInvocationHandler(a));
System.out.println(s.getValueOne()); // prints: Um
Another option is simpler but requires you to subclass each class and implement the created interface, simply like this:
class SomethingAImpl extends SomethingA implements Something {}
class SomethingBImpl extends SomethingB implements Something {}
(Note: you also need to create any non-default constructors)
Now use the subclasses instead of the superclasses, and refer to them through the interface:
Something o = new SomethingAImpl(); // o can also refer to a SomethingBImpl
o.setValueOne("Uno");
System.out.println(o.getValueOne()); // prints: Uno
i think your original wrapper class is the most viable option...however it can be done using reflection, your real problem is that the application is a mess...and reflection is might not be the method you are looking for
i've another proposal, which might be help: create a wrapper class which has specific functions for every type of classes...it mostly copypaste, but it forces you to use the typed thing as a parameter
class X{
public int asd() {return 0;}
}
class Y{
public int asd() {return 1;}
}
class H{
public int asd(X a){
return a.asd();
}
public int asd(Y a){
return a.asd();
}
}
usage:
System.out.println("asd"+h.asd(x));
System.out.println("asd"+h.asd(y));
i would like to note that an interface can be implemented by the ancestor too, if you are creating these classes - but just can't modify it's source, then you can still overload them from outside:
public interface II{
public int asd();
}
class XI extends X implements II{
}
class YI extends Y implements II{
}
usage:
II a=new XI();
System.out.println("asd"+a.asd());
You probably can exploit a facade along with the reflection - In my opinion it streamlines the way you access the legacy and is scalable too !
class facade{
public static getSomething(Object AorB){
Class c = AorB.getClass();
Method m = c.getMethod("getValueOne");
m.invoke(AorB);
}
...
}
I wrote a class to encapsulate the logging framework API's. Unfortunately, it's too long to put in this box.
The program is part of the project at http://www.github.com/bradleyross/tutorials with the documentation at http://bradleyross.github.io/tutorials. The code for the class bradleyross.library.helpers.ExceptionHelper in the module tutorials-common is at https://github.com/BradleyRoss/tutorials/blob/master/tutorials-common/src/main/java/bradleyross/library/helpers/ExceptionHelper.java.
The idea is that I can have the additional code that I want to make the exception statements more useful and I won't have to repeat them for each logging framework. The wrapper isn't where you eliminate code duplication. The elimination of code duplication is in not having to write multiple versions of the code that calls the wrapper and the underlying classes. See https://bradleyaross.wordpress.com/2016/05/05/java-logging-frameworks/
The class bradleyross.helpers.GenericPrinter is another wrapper that enables you to write code that works with both the PrintStream, PrintWriter, and StringWriter classes and interfaces.

Categories

Resources