Implementing Data Acess API using dependency Injection - java

I am new to writing API's and did some research and realize to accomplish what I want I would need to do it using Dependency Injection. I am writing an android application that haves two data source. One is expose by web services and the other is SQLlite. The SQLlite is used as backup when no data connection is available (Only interested for the webservice portion of the API for the time being will refactor). I want to write a API that provides a layer of abstraction to this that calls the right data access class based on the model required. Therefore, I have a interface that describes methods that the api should implement, called IDataAccess (Only interested in getAll for the purpose of figuring out what to do).
public interface IDataAccess {
public <T> List <T> getAll ();
public <T> T getById (int id);
}//end IDataAccess
I am using Guice for dependency injection. The guice module is:
public class Data extends AbstractModule {
public void configure () {
bind (IDataAccess.class).to(UserData.class);
}
}
and a Implementation of IDataAccess is (Note I am using Jersey Client API):
public class UserData extends DataAccessManager implements IDataAccess {
#SuppressWarnings("unchecked")
public List <User> getAll () {
WebResource webResource = client.resource (WebResourceURL.URL_USER_ALL);
ClientResponse response = webResource.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
if (response.getStatus () == 200)
return response.getEntity(new GenericType <List <User>> () {}) ;
else
return null;
}//end getAllUsers method
}
I have a class that loads and instantiates any resource needed. It also returns a instance of a DataManager called DataAccessFactory.
public class DataAccessFactory {
private Client client;
private static DataAccessFactory instance;
private DataAccessFactory() {
client = Client.create();
}
public static DataAccessFactory getInstance() {
/*
* check if instance variable is instantiated.
* if it is not then instantiated it and returns
* created instance.
*/
if (instance == null) {
instance = new DataAccessFactory();
return instance;
} else
return instance;
}//end getInstance method
public DataAccessManager createDataAccessManager() {
return new DataAccessManager(client);
}//end createDataAccessManager method
}
Then I have the actual DataAccessManager class:
public class DataAccessManager {
protected Client client;
protected DataAccessManager (Client client)n{
this.client = client;
}//end constructor
public <T> List <Object> getAll(T t) {
Data module = new Data ();
Injector injector = Guice.createInjector(module);
IDataAccess data = (IDataAccess) injector.getInstance(t.getClass());
return (List<Object>) data;
}//end fetchAllUser method
}
To call the user model on this class I would do something like this:
#Test
public void fetchUser () {
DataAccessManager m = DataAccessFactory.getInstance().createDataAccessManager();
List<User> user = (List<User>) m.getAll(new Userdata ());
if (user == null)
assertEquals(1, 2);
else
assertEquals(1, 1);
}
Ideally what I want this to do now is, call the UserData to get all the User objects or the OrderData (When implementation is written) class to get all the order objects etc.
The problem is that this is giving a error:
Cannot cast from List to List
.How can I fix this problem or restructure this so that it makes sense?

1) You are creating an injector (Guice.createInjector) per request. Injector creation is expensive and should normally be done during application loading. You should see DI as a bootstrap mechanism and keep it simple.
2) You don't need the DataAccessFactory. First there is no need for a factory as the createDataAccessManager instantiation does not require any logic and secondly Guice could also take care of the factory pattern.
I would personally keep it simple and inject with Guice directly the UserData instance into each service that needs it, without using the rather complicated Abstraction approach showed here. Still, it does not solve the problem of dealing with network issues. My guess is that each data access class will have to deal with connectivity in a specific way, so the logic should be directly here.
For the list casting problem, see http://docs.oracle.com/javase/tutorial/java/generics/subtyping.html
If you will continue that way, I would recommend to read about erasure also.

It's a common problem you fall for. We'd expect that as String is-a Object, List<String> is-a List<Object> is true too. But it isn't. This is why this class cast won't work:
#Test
public void fetchUser () {
//...
List<User> user = (List<User>) m.getAll(new Userdata ());
//..
}
I suggest to rewrite the DataAccessManager.getAll() method to return the right kind of list.
For the record, I found a typo in DataAccessManager.getAll() method. I think when you wrote return (List<Object>) data; then you rather wanted to write return List<Object> data.getAll(); Otherwise you just cannot cast IDataAccess to List.
To escape from this casting hell I suggest to add a type to the IDataAccess interface and to its implementations:
public interface IDataAccess<T> {
public List <T> getAll ();
public T getById (int id);
}//end IDataAccess
public class UserData extends DataAccessManager<User> implements IDataAccess<User> {
// your implementation
}
I'd also clarify DataAccesManager itself:
public class DataAccessManager<T> {
//fields and constructors
public List<T> getAll(IDataAccess<T> access) { //this is how the test suggests you want to use this method
Data module = new Data ();
Injector injector = Guice.createInjector(module);
IDataAccess<T> data = (IDataAccess<T>) injector.getInstance(access.getClass()); //why is this line important? why don't you use the access parameter instead?
return data.getAll();
}
}

Related

Does it make sense to create a `Copyable` type interface instead of using `Cloneable`?

I have a bit of code that requires a copy of an object be sent in. This requirement is because a service (runtime library) that is called modifies the object sent. This object also needs to expose setters, in case the doThing method below needs to set any field in the ImportantObj class. This implementation is pending change, but does not have a reasonable expectation to be changed in the near future. My workaround is to provide a class that does as follows:
public class DangerousCallWrapper<T> implements DangerousCaller<T> {
public T doThing(T dataObject) {
T cloneOfDataObject = #Clone of dataObject
// This service modifies the cloneOfDataObject... dangerous!
Optional<T> result = service.doThing(cloneOfDataObject);
return result.orElseThrow(() -> new RuntimeException("No data object returned");
}
}
public interface DangerousCaller<T> {
/**
* Performs the functionality of the DangerousService
*/
public T doThing(T);
}
public DangerousService<T> {
public T doThing(T data) {
data.importantField = null;
data.thing = "Done!";
return data;
}
}
public static void main() {
DangerousService service = new DangerousService<ImportantObj>();
ImportantObj important = new ImportantObj().setImportantField("Password for my bank account").setThing("Undone");
service.doThing(important);
//would fail this check
assertNotNull(important.importantField);
DangerousCallWrapper wrapper = new DangerousCallWrapper<ImportantObj>();
ImportantObj important = new ImportantObj().setImportantField("Password for my bank account").setThing("Undone");
service.doThing(important);
//would not fail this check
assertNotNull(important.importantField);
}
So the first line of that method is where I am stuck. It is a generic type, so I can't explicitly call some cloning utility like Jackson, or similar.
So I thought I would just add T extends Cloneable to the method... but I opened the can of worms that Cloneable is beyond taboo (https://www.artima.com/intv/bloch13.html). I have also read that copy constructors are probably the best way to handle this... However, I am unsure of how to denote that using the generics.
So my thought was to provide an interface Copyable that does what you would expect Cloneable to do: expose a method, copy() that will create a new instance of the class.
Does this constitute a viable approach?
To solve your problem you need to polymorphically make a copy of dataObject like this:
T cloneOfDataObject = dataObject.clone();
and the issue is that Cloneable does not have a clone() method, so the above does not compile.
Given this premise, it does make sense to create your own Copyable interface that defines a clone() method so you can leverage already-implemented clone() methods (if they exist) on the classes of your data object. For maximum effectiveness this interface would need to be generic as well:
interface Copyable<T> {
public T clone();
}
and the type bound:
public class DangerousCallWrapper<T extends Copyable<T>>
implements DangerousCaller<T> {

how to inject interface to class in java?

i have my DTO class that is :
public class EmailResponse {
// Make public to avoid getters and setters
public Email email;
public RequestData reqData;
public EmailResponse() {
super();
}
}
and i want to implement to it this interface:
public interface IAssertionErrorDo {
public void onErrorDo();
}
but i want to do it during execution, i don't want to touch "EmailResponse" because it would not be ok to make it implements that interface due they don't belong to the same layer, i mean, EmailResponse would belong to service layer and IAssertionError would belong to test layer. I am using TestNG.
Do you know how i could do this? Regards
EDIT:
My implementation is this:
EmailResponse emailResponse = emailService.getUserEmail(userId);
And the reason i want to do this "injection" is because i have
public class LoggingAssert
extends Assertion {
private static final Logger LOGGER = LoggerFactory.getLogger(LoggingAssert.class);
private IAssertionErrorDo dataE;
#Override
public void onAssertFailure(IAssert a, AssertionError ex) {
LOGGER.info("[ERROR] " + a.getMessage());
if (this.dataE != null) {
this.dataE.onErrorDo();
}
}
public LoggingAssert setOnErrorDo(IAssertionErrorDo object) {
this.object = object;
return this;
}
}
loggingAssert.setOnErrorDo(emailResponse).assertNotNull(emailResponse.getEmail().getId(),
"Checking created email doesn't exists");
So i want to if assert fails execute method onErrorDo() from emailResponse
You could do
public class MyEmailResponse extends EmailResponse implements IAssertionErrorDo {
...
}
implementation calls in interfaces, you can call more than 1 interface if you want by adding commas to separate them..
to call interface methods you simply just use the method's name.
like this:
public class MyEmailResponse implements IAssertionErrorDo
{
public void onErrorDo() {//define it's behavior}
}
if you extend a class you use:
super.MyMethod()
to call the a method inside the extended class, but if you already have an extended class and want a method from another class you have to create an object for that class first then call it, thus:
MyClass mc = new MyClass();
if it is in a different package then
myPackage.MyClass mc = new myPackage.MyClass();
then you call your method from that class using the object you created, which is in this case mc.. so:
mc.MyMethod();
if you want it to return a variable then you will need to add a return statement in that method with the variable you want it to return.
interfaces are usually used for global an changing environments (dynamics), for example if you developed a program and it needs a driver to connect to databases then you will make an interface and send it to the database developers, and each one will fill the codes in that interface and send it back... this guarantees consistency.
when you implement an interface you have to define every method inside it (even if you leave it empty) and you cannot change the interface's methods names nor add... it is used in other areas as well, i don't think you need to use it in your case.

Original class name of a proxy (without manual string manipulation)

In Java, how do you get the original class object and/or class name of a Java EE (CDI) proxy?
When using getName() on a proxy instance, the name returned is something like
com.company.employeemgmt.EmployeeManager$Proxy$_$$_WeldSubclass
Is there some functionaliy in Java SE (7) or EE (6) that will return either the original, unproxied class instance or its name?
I need:
com.company.employeemgmt.EmployeeManager
Of course, I could simply use string manipulation, but I would like to know if such functionality is already Java-(EE)-inbuilt.
I already found java.reflect.Proxy, which I could use to detect proxies:
public static void doSomething( Class<? implements Serializable> managerClass )
{
if ( Proxy.isProxyClass( managerClass ) )
{
// unproxy how?
managerClass = managerClass.getUnproxiedClass();
}
// delegate
doSomething( managerClass.getName() );
}
public static void doSomething( String prefix )
{
// do real work
...
}
..., but how would you dereference the original class?
Update:
The trick would be to access MyUtil.doSomething( EmployeeManager.class ) (or MyUtil.doSomething( EmployeeManager.class.getName() )), but I would like to use/pass MyUtil.doSomething( this.getClass() ) (or MyUtil.doSomething( this.getClass().getName() )) from all clients as this code can be copied around without manual changes.
Since the proxy class inherits from the original class, I think that you can obtain the original class by getting the proxy superclass.
It depends. You can get the InvocationHandler for a proxy using Proxy.getInvocationHandler(manager). Alas, InvocationHandler is an interface with only one invoke method and with no feature that lets you get a target class; it all depends on the implementation.
As an example the CXF web servcie framework has a Client and uses a ClientProxy as an associated invocation handler, you can get the Client as such:
ClientProxy handler = (ClientProxy)Proxy.getInvocationHandler(proxiedObject);
Client client = handler.getClient();
To add insult to injury, it seems that the WeldInvocationHandler that you are probably using simply delegates the call to a org.jboss.wsf.spi.invocation.InvocationHandler that that it stores its delegate in a private field. So you need to do quite some magic with reflection to find out the actual class of the target object.
Since proxy implements interfaces it proxies, you can use Class<?>[] Class.getInterfaces()
to find out proxied class(es).
private Class<?> findProxiedClass(Object proxiedObject) {
Class<?> proxiedClass = proxiedObject.getClass();
if (proxiedObject instanceof Proxy) {
Class<?>[] ifaces = proxiedClass.getInterfaces();
if (ifaces.length == 1) {
proxiedClass = ifaces[0];
} else {
// We need some selection strategy here
// or return all of them
proxiedClass = ifaces[ifaces.length - 1];
}
}
return proxiedClass;
}
Test it with
#Test
public void testProxies() {
InvocationHandler handler = new InvocationHandler() {
#Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
};
RandomAccess proxiedIface = (RandomAccess) Proxy.newProxyInstance(
RandomAccess.class.getClassLoader(),
new Class[] { RandomAccess.class },
handler);
Assert.assertEquals(RandomAccess.class, findProxiedClass(proxiedIface));
Assert.assertEquals(Object.class, findProxiedClass(new Object()));
}

Understanding best use of Java Generics in this example case

Let's say I have a manufacturing scheduling system, which is made up of four parts:
There are factories that can manufacture a certain type of product and know if they are busy:
interface Factory<ProductType> {
void buildProduct(ProductType product);
boolean isBusy();
}
There is a set of different products, which (among other things) know in which factory they are built:
interface Product<ActualProductType extends Product<ActualProductType>> {
Factory<ActualProductType> getFactory();
}
Then there is an ordering system that can generate requests for products to be built:
interface OrderSystem {
Product<?> getNextProduct();
}
Finally, there's a dispatcher that grabs the orders and maintains a work-queue for each factory:
class Dispatcher {
Map<Factory<?>, Queue<Product<?>>> workQueues
= new HashMap<Factory<?>, Queue<Product<?>>>();
public void addNextOrder(OrderSystem orderSystem) {
Product<?> nextProduct = orderSystem.getNextProduct();
workQueues.get(nextProduct.getFactory()).add(nextProduct);
}
public void assignWork() {
for (Factory<?> factory: workQueues.keySet())
if (!factory.isBusy())
factory.buildProduct(workQueues.get(factory).poll());
}
}
Disclaimer: This code is merely an example and has several bugs (check if factory exists as a key in workQueues missing, ...) and is highly non-optimal (could iterate over entryset instead of keyset, ...)
Now the question:
The last line in the Dispatcher (factory.buildProduct(workqueues.get(factory).poll());) throws this compile-error:
The method buildProduct(capture#5-of ?) in the type Factory<capture#5-of ?> is not applicable for the arguments (Product<capture#7-of ?>)
I've been racking my brain over how to fix this in a type-safe way, but my Generics-skills have failed me here...
Changing it to the following, for example, doesn't help either:
public void assignWork() {
for (Factory<?> factory: workQueues.keySet())
if (!factory.isBusy()) {
Product<?> product = workQueues.get(factory).poll();
product.getFactory().buildProduct(product);
}
}
Even though in this case it should be clear that this is ok...
I guess I could add a "buildMe()" function to every Product that calls factory.buildProduct(this), but I have a hard time believing that this should be my most elegant solution.
Any ideas?
EDIT:
A quick example for an implementation of Product and Factory:
class Widget implements Product<Widget> {
public String color;
#Override
public Factory<Widget> getFactory() {
return WidgetFactory.INSTANCE;
}
}
class WidgetFactory implements Factory<Widget> {
static final INSTANCE = new WidgetFactory();
#Override
public void buildProduct(Widget product) {
// Build the widget of the given color (product.color)
}
#Override
public boolean isBusy() {
return false; // It's really quick to make this widget
}
}
Your code is weird.
Your problem is that you are passing A Product<?> to a method which expects a ProductType which is actually T.
Also I have no idea what Product is as you don't mention its definition in the OP.
You need to pass a Product<?> to work. I don't know where you will get it as I can not understand what you are trying to do with your code
Map<Factory<?>, Queue<Product<?>>> workQueues = new HashMap<Factory<?>, Queue<Product<?>>>();
// factory has the type "Factory of ?"
for (Factory<?> factory: workqueues.keySet())
// the queue is of type "Queue of Product of ?"
Queue<Product<?>> q = workqueues.get(factory);
// thus you put a "Product of ?" into a method that expects a "?"
// the compiler can't do anything with that.
factory.buildProduct(q.poll());
}
Got it! Thanks to meriton who answered this version of the question:
How to replace run-time instanceof check with compile-time generics validation
I need to baby-step the compiler through the product.getFactory().buildProduct(product)-part by doing this in a separate generic function. Here are the changes that I needed to make to the code to get it to work (what a mess):
Be more specific about the OrderSystem:
interface OrderSystem {
<ProductType extends Product<ProductType>> ProductType getNextProduct();
}
Define my own, more strongly typed queue to hold the products:
#SuppressWarnings("serial")
class MyQueue<T extends Product<T>> extends LinkedList<T> {};
And finally, changing the Dispatcher to this beast:
class Dispatcher {
Map<Factory<?>, MyQueue<?>> workQueues = new HashMap<Factory<?>, MyQueue<?>>();
#SuppressWarnings("unchecked")
public <ProductType extends Product<ProductType>> void addNextOrder(OrderSystem orderSystem) {
ProductType nextProduct = orderSystem.getNextProduct();
MyQueue<ProductType> myQueue = (MyQueue<ProductType>) workQueues.get(nextProduct.getFactory());
myQueue.add(nextProduct);
}
public void assignWork() {
for (Factory<?> factory: workQueues.keySet())
if (!factory.isBusy())
buildProduct(workQueues.get(factory).poll());
}
public <ProductType extends Product<ProductType>> void buildProduct(ProductType product) {
product.getFactory().buildProduct(product);
}
}
Notice all the generic functions, especially the last one. Also notice, that I can NOT inline this function back into my for loop as I did in the original question.
Also note, that the #SuppressWarnings("unchecked") annotation on the addNextOrder() function is needed for the typecast of the queue, not some Product object. Since I only call "add" on this queue, which, after compilation and type-erasure, stores all elements simply as objects, this should not result in any run-time casting exceptions, ever. (Please do correct me if this is wrong!)

Right way to prevent subclass instantiation without calling a desired initialisation method?

Can somebody help a novice programmer to understand if his solution is correct?
My question is similar to the the following two:
What's wrong with overridable method calls in constructors?
Factory pattern in C#: How to ensure an object instance can only be created by a factory class?
Problem: I want to have subclasses which will differ only in their initialisation method. However, I also want to prevent instantiating these classes without initialization. In other words, I want to ensure, that some "initialize()" method will always be called after instantiation of a subclass:
public abstract class Data {
protected Parameter dataSource;
Data(parameter1){
this.dataSource = parameter1;
loadData(); // should be called to initialise class fields and ensure correct work of other class methods
}
protected abstract loadData(){
... //uses dataSource
}
}
So I decided to perform initialization on a constructor. It worked (now I know that it's a very bad practice) until I created a subclass where the initialize method used some additional parameters:
public class DataFromSpecificSources extends Data {
private Parameter dataSource2;
public DataFromSpecificSources(parameter1, parameter2){
this.dataSource2 = parameter2; // I can't put it here because the constructor is not called yet
super(parameter1); // this, of course, will not work
}
#Override
private void loadData(){
... // uses both dataSource 1 and 2
// or just dataSource2
}
}
This, of course, is not going to work. And I started searching for a right pattern... After I read the answers on questions posted before, I decided to use the factory and limit visibility of the subclass constructor to the package:
My solution:
// factory ensures that loadData() method will be called
public class MyDataFactory(){
public Data createSubClass(parameter1,parameter2){
Data subClass;
if (parameter2 != null){
subClass = new DataFromSpecificSources(parameter1, parameter2);
subClass.loadData();
} else {
subClass = new AnotherSubClass(parameter1);
subClass.loadData()
}
return subClass;
}
}
public abstract class Data {
protected Parameter dataSource;
Data(parameter1){
this.dataSource = parameter1;
}
// I don't call it in constructor anymore - instead it's controlled within the factory
protected abstract loadData(){
... //uses dataSource
}
}
public class DataFromSpecificSources {
private Parameter dataSource2;
protected DataFromSpecificSources(){}
// now this constructor is only visible within package (only for the factory in the same package)
DataFromSpecificSources(parameter1, parameter2){
super(parameter1); // it does not initialise data anymore
this.dataSource2 = parameter2;
}
#Override
protected void loadData(){
... // uses dataSources 1 and 2
}
}
Now factory ensures that subclasses will be initialized (data will be loaded) and instantiation of subclasses is not allowed in other packages. Other classes have no access to constructor of subclasses and are forced to use factory to get an instance of a subclass.
I just wanted to ask if my solution is correct (logically) and Factory method with subclass constructor visibility limited to the package is right choice here?! Or there is any other more effective pattern solving the problem?!
Using a factory is definitely a step in the right direction. The issue I see is that what happens when you want to add a third class that takes a third parameter. Now your Factory is either going to have to have a second overloaded createSubClass method taking the third parameter, or all your code is going to have to be rewritten to provide the third parameter. Additionally you are forcing anyone using the Factory to specify null for the second parameter even if they only want the single parameter class.... when you get to the class that takes 15 parameters how are you going to remember which parameter is which
The solution to this is to use the Builder pattern instead.
public class MyDataBuilder(){
private parameter1 = null;
private parameter2 = null;
public MyDataBuilder withParameter1(parameter1) {
this.parameter1 = parameter1;
return this;
}
public MyDataBuilder withParameter2(parameter2) {
this.parameter2 = parameter2;
return this;
}
public Data createSubClass(){
Data subClass;
if (parameter2 != null){
subClass = new DataFromSpecificSources(parameter1, parameter2);
} else {
subClass = new AnotherSubClass(parameter1);
}
subClass.loadData();
return subClass;
}
}
Now the code creating the Data instances can work like so:
Data data = new MyDataBuilder().withParameter1(param1).withParameter2(param2).create();
or
Data data = new MyDataBuilder().withParameter1(param1).create();
And that code is future-proofed for when you add parameter3... and you can even have the builder with a non-null default for parameter3 if you so need that.
The next thing you notice is that you now have this nice Builder object that contains all the required parameters... so now you can add getters to the Builder and just pass the Builder as the constructor parameter, e.g.
public class DataFromSpecificSources {
...
DataFromSpecificSources(MyDataBuilder builder){
...
}
...
}
So that you now almost have a standard constructor signature
Now for some Java specific improvements. We can make the builder not need to know about the sub-classes at all!
Using a DI framework we can inject the classes that implement the Data interface / abstract class into the Builder and then just iterate through each class until we find a class that supports the configuration of the Builder instance.
The poor-man's DI framework is the /META-INF/services contract and the ServiceLoader class available since JRE 1.6 (though the core logic has been in Java since 1.2)
Your builder's create method will then look a little something like
public Data create() {
for (DataFactory factory: ServiceLoader.load(DataFactory.class)) {
if (factory.canCreate(this)) {
Data result = factory.newInstance(this);
result.loadData();
return result;
}
}
throw new IllegalStateException("not even the default instance supports this config");
}
Whether you want to go to that extreme is questionable... but since you might come across it at some point in time when looking at other people's code, it is probably a good time to point it out to you now.
Oh, the reason why we have to add a Factory class to be looked up by the ServiceLoader is because ServiceLoader expects to call the default constructor, and we have hidden the default constructor so we use a Factory class to do the work for us and allow us to keep the constructor hidden.
There is nothing preventing the Factory classes from being static inner classes in the Data classes (which gives them great visibility on the class they are creating), e.g.
public class UberData extends Data {
private UberData(MyDataBuilder config) {
...
}
public static class Factory extends DataFactory {
protected Data create(MyDataBuilder config) {
return new UberData(config);
}
protected boolean canCreate(MyDataBuilder config) {
return config.hasFlanges() and config.getWidgetCount() < 7;
}
}
}
As we can then list in META-INF/services/com.mypackage.DataFactory
com.mypackage.UberData.Factory
com.mypackage.DataFromSpecificSources.Factory
com.some.otherpackage.AnotherSubClass.Factory
The best bit about this type of solution is it allows adding additional implementations just by adding those implementations to the classpath at run-time... i.e. very loose coupling

Categories

Resources