Generic Interface in different classes - java

In my project, I have to use the database pretty often and I decided to create an interface and then implement it in different classes since they will all use the same methods.
public interface Project<E> {
void createTable();
void insert(E obj);
E select(int id);
void delete(int id);
void update(E obj, int id);
}
I try to implement it in one of my classes like below:
public class Person implements Project {
//createTable method
//select method
//delete method
public void insert(Person p) {
Connection connection = null;
PreparedStatement ppStm = null;
try {
connection = ConnectionConfiguration.getConnection();
ppStm = connection.prepareStatement("INSERT INTO person (first_name, last_name)"
+ "VALUES (?,?,?)");
ppStm.setString(1, p.getName());
ppStm.setString(2, p.getLname());
ppStm.executeUpdate();
} catch(Exception e) {
e.printStackTrace();
} finally {
if (ppStm != null){
try {
ppStm.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
//update method similar to insert();
}
The problem is that when I try to override the insert() and update() methods it shows me an error message "the method must override or implement a supertype method". I used generics since I thought it would work in my code seeing as I have different classes of different objects to implement it to but I am not understanding the right implementation I guess. I would like to know how I can change my interface or its implementation in my classes so it can work. Also when I remove the #Override it removes the error but still shows that I am not implementing all the methods.
Thank you in advance.

You can use DAO pattern
public interface DAO<T> {
void createTable();
void insert(T t);
T select(int id);
void delete(int id);
void update(T t, int id);
}
Implementation
class PersonDAO implements DAO<Person> {
#Override
public void createTable() {}
#Override
public void insert(Person person) {
/// Connection connection = null;
/// PreparedStatement ppStm = null;
// Detailed implementation
//// .............
}
#Override
public Person select(int id) {
return null;
}
#Override
public void delete(int id) {}
#Override
public void update(Person person, int id) {}
}

Related

throw own defined exception in visitor pattern java

We have to write an app using the visitor design pattern like ( https://www.baeldung.com/java-visitor-pattern ) , one example element looks like, implementing interface Stmt :
public class Call implements Stmt {
int hash_id;
private String id;
public Call(String id ) { this.id = id;}
public void accept(Visitor v) {
System.out.println("call.accept");
v.visit( this);
}
public String getId () { return id;}
....}
The vistor Interface looks like this code below , I may not change the interface code.
public interface Visitor {
...
...
void visit(Subroutine subroutine);
void visit(Call call);
}
Inside the Implementation of an Visitor (AbstractVisitor class) I have to throw a "UndefinedSubroutineException if the id (type string) of a call class is not yet existing in the hashtable SubBefehle.
The existing code with try catch statemenets never send as an exception to my testcase ....
public abstract class AbstractVisitor implements Visitor {
.....
private Hashtable<String, Integer> SubBefehle = new Hashtable< String, Integer>();
#Override
public void visit(Call call) {
/// implementation work :
try {
IsFunctionNameExisting(call.getId());
}
catch (UndefinedSubroutineException e){
// throw new UndefinedSubroutineException("");
}
}
public void IsFunctionNameExisting(String fctname) throws UndefinedSubroutineException {
boolean IsFound = false;
if (SubBefehle.containsKey(fctname)) {
System.out.println("Abstract visitor : function name found -> PASS ");
IsFound = true;
}
else {
System.out.println("Abstract visitor : function name not yet found -> EXCEPTION ");
throw new UndefinedSubroutineException(" function name not found in function name list !");
}
if the call IsFunctionNameExisting(call.getId()) is false if the name is not found inside the hash table. My optional solution is also not working .
/// optional solution
#Override
public void visit(Call call) throws UndefinedSubroutineException {
/// implementation work :
IsFunctionNameExisting(call.getId());
}
the corresponding testcase looks like this :
#Test
public void testUndefinedSubroutine() {
try {
PROG_TEST.accept(testVisitor);
fail("Exception expected");
} catch (UndefinedSubroutineException e) {
........
}
}
package turtle.logo;
the defintion of UndefinedSubroutineException goes like this :
public class UndefinedSubroutineException extends Throwable {
public UndefinedSubroutineException (String message) {
super(message);
}
}
PS: I can't change the test cases and the interface definition &
I hope someone can help us with this problem.
You can make UndefinedSubroutineException a RuntimeException. In that case since it is an unchecked exception, and you will not have to change your method signature.
Inside your test case you can now add a try catch block to handle the scenario.

How to test catch block in Java with Spock that has a simple log statement

I have a simple Java method that I want to unit test with Spock
private void executeDataLoad(String sql) {
Statement snowflakeStatement=null;
try {
snowflakeStatement = getSnowflakeStatement();
log.info("Importing data into Snowflake");
int rowsUpdated = snowflakeStatement.executeUpdate(sql);
log.info("Rows updated/inserted: " + rowsUpdated);
}
catch (SQLException sqlEx) {
log.error("Error importing data into Snowflake", sqlEx);
throw new RuntimeException(sqlEx);
}finally{
try {
if (snowflakeStatement != null)
snowflakeStatement.close();
} catch (SQLException sqlEx) {
log.error("Error closing the statement", sqlEx);
}
}
}
I want to test the catch block in finally. It is a simple catch block which just logs a statement. All the examples I have seen only test the catch blocks that have a throw keyword inside the catch block.
How do I test to make sure that the catch block is executed ?
The simple answer is: You don't test private methods directly.
Instead, good testing practice is to test public methods with the necessary parameters and injected objects (often mock objects) in order to cover all execution paths in both your public and private methods. If you cannot cover private method code by calling public methods, it is a sign that
either your class is not testable well and you should refactor
or (part of) your private method code is unreachable and should thus be removed
or maybe a combination of both.
Your code also suffers from the problem of instantiating its own dependencies, in this case the Statement object. If you could inject it as a method parameter instead of the method constructing it as a local variable, you could easily inject a mock, stub or spy and make that mock object behave as you wish in order to test different cases and execution paths in your method.
As a side note, I assume your logger is a private static final object. If you would make it non-final, you could replace it by a mock logger and even check if certain log methods are being called during the test. But maybe that is not so important for you, you should not over-specify and test too much. In my example I will just make it non-final in order to show you what is possible as you seem to be a beginner in test automation.
Back to testing private methods: As most mock frameworks (also Spock's) are based on subclassing or implementing the original classes or interfaces via dynamic proxies and private methods are not visible to their subclasses, you also cannot overwrite/stub the behaviour of a private method. This is yet another (technical) reason why trying to test private methods on mock objects is a bad idea.
Let us assume our class under test looks like this (please note that I made both methods package-protected so as to be able to mock/stub them):
package de.scrum_master.stackoverflow.q58072937;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.*;
public class SQLExecutor {
private static /*final*/ Logger log = LoggerFactory.getLogger(SQLExecutor.class);
/*private*/ void executeDataLoad(String sql) {
Statement snowflakeStatement = null;
try {
snowflakeStatement = getSnowflakeStatement();
log.info("Importing data into Snowflake");
int rowsUpdated = snowflakeStatement.executeUpdate(sql);
log.info("Rows updated/inserted: " + rowsUpdated);
} catch (SQLException sqlEx) {
log.error("Error importing data into Snowflake", sqlEx);
throw new RuntimeException(sqlEx);
} finally {
try {
if (snowflakeStatement != null)
snowflakeStatement.close();
} catch (SQLException sqlEx) {
log.error("Error closing the statement", sqlEx);
}
}
}
/*private*/ Statement getSnowflakeStatement() {
return new Statement() {
#Override public ResultSet executeQuery(String sql) throws SQLException { return null; }
#Override public int executeUpdate(String sql) throws SQLException { return 0; }
#Override public void close() throws SQLException {}
#Override public int getMaxFieldSize() throws SQLException { return 0; }
#Override public void setMaxFieldSize(int max) throws SQLException {}
#Override public int getMaxRows() throws SQLException { return 0; }
#Override public void setMaxRows(int max) throws SQLException {}
#Override public void setEscapeProcessing(boolean enable) throws SQLException {}
#Override public int getQueryTimeout() throws SQLException { return 0; }
#Override public void setQueryTimeout(int seconds) throws SQLException {}
#Override public void cancel() throws SQLException {}
#Override public SQLWarning getWarnings() throws SQLException { return null; }
#Override public void clearWarnings() throws SQLException {}
#Override public void setCursorName(String name) throws SQLException {}
#Override public boolean execute(String sql) throws SQLException { return false; }
#Override public ResultSet getResultSet() throws SQLException { return null; }
#Override public int getUpdateCount() throws SQLException { return 0; }
#Override public boolean getMoreResults() throws SQLException { return false; }
#Override public void setFetchDirection(int direction) throws SQLException {}
#Override public int getFetchDirection() throws SQLException { return 0; }
#Override public void setFetchSize(int rows) throws SQLException {}
#Override public int getFetchSize() throws SQLException { return 0; }
#Override public int getResultSetConcurrency() throws SQLException { return 0; }
#Override public int getResultSetType() throws SQLException { return 0; }
#Override public void addBatch(String sql) throws SQLException {}
#Override public void clearBatch() throws SQLException {}
#Override public int[] executeBatch() throws SQLException { return new int[0]; }
#Override public Connection getConnection() throws SQLException { return null; }
#Override public boolean getMoreResults(int current) throws SQLException { return false; }
#Override public ResultSet getGeneratedKeys() throws SQLException { return null; }
#Override public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { return 0; }
#Override public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { return 0; }
#Override public int executeUpdate(String sql, String[] columnNames) throws SQLException { return 0; }
#Override public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { return false; }
#Override public boolean execute(String sql, int[] columnIndexes) throws SQLException { return false; }
#Override public boolean execute(String sql, String[] columnNames) throws SQLException { return false; }
#Override public int getResultSetHoldability() throws SQLException { return 0; }
#Override public boolean isClosed() throws SQLException { return false; }
#Override public void setPoolable(boolean poolable) throws SQLException {}
#Override public boolean isPoolable() throws SQLException { return false; }
#Override public void closeOnCompletion() throws SQLException {}
#Override public boolean isCloseOnCompletion() throws SQLException { return false; }
#Override public <T> T unwrap(Class<T> iface) throws SQLException { return null; }
#Override public boolean isWrapperFor(Class<?> iface) throws SQLException { return false; }
};
}
}
Then you could write a Spock test like this:
package de.scrum_master.stackoverflow.q58072937
import org.slf4j.Logger
import spock.lang.Specification
import java.sql.SQLException
class SQLExecutorTest extends Specification {
def test() {
given:
def logger = Mock(Logger)
def originalLogger = SQLExecutor.log
SQLExecutor.log = logger
SQLExecutor sqlExecutor = Spy() {
getSnowflakeStatement() >> {
throw new SQLException("uh-oh")
}
}
when:
sqlExecutor.executeDataLoad("dummy")
then:
def exception = thrown RuntimeException
exception.cause instanceof SQLException
exception.cause.message == "uh-oh"
0 * logger.info(*_)
1 * logger.error(*_)
cleanup:
SQLExecutor.log = originalLogger
}
}
As I said above, the whole interaction testing on the logger is optional and not necessary in order to answer your question. I just did it in order to illustrate what is possible.
I also do not like my own solution because you need to
use a spy object for your class under test and
to know about the internal implementation of executeDataLoad(String), namely that it calls getSnowflakeStatement() in order to be able to stub out the latter method and make it throw the exception you want to be thrown in order to cover the exception handler's execution path.
Please also note that the statement exception.cause.message == "uh-oh" is not really necessary as it is just testing the mock. I just put it there in order to show you how the mocking thing works.
Now let us assume we refactor your class to make the Statement injectable:
/*private*/ void executeDataLoad(String sql, Statement snowflakeStatement) {
try {
if (snowflakeStatement == null)
snowflakeStatement = getSnowflakeStatement();
log.info("Importing data into Snowflake");
// (...)
Then you could make getSnowflakeStatement() private (provided you can cover that one via another public method) and modify your test like this (removing the logger interaction testing in order to concentrate on what I am changing):
package de.scrum_master.stackoverflow.q58072937
import spock.lang.Specification
import java.sql.SQLException
import java.sql.Statement
class SQLExecutorTest extends Specification {
def test() {
given:
def sqlExecutor = new SQLExecutor()
def statement = Mock(Statement) {
executeUpdate(_) >> {
throw new SQLException("uh-oh")
}
}
when:
sqlExecutor.executeDataLoad("dummy", statement)
then:
def exception = thrown RuntimeException
exception.cause instanceof SQLException
}
}
See the difference? You don't need to use a Spy on your class under test anymore and can just use a Mock or a Stub for the Statement you inject in order to modify its behaviour.
I could say and explain more, but this answer cannot replace a testing tutorial.
Remove null check in try block inside finally. Because of this null check, you can not get any exception. Just try to closing the statement without checking it.
private void executeDataLoad(String sql) {
Statement snowflakeStatement=null;
try {
snowflakeStatement = getSnowflakeStatement();
log.info("Importing data into Snowflake");
int rowsUpdated = snowflakeStatement.executeUpdate(sql);
log.info("Rows updated/inserted: " + rowsUpdated);
}
catch (SQLException sqlEx) {
log.error("Error importing data into Snowflake", sqlEx);
throw new RuntimeException(sqlEx);
}finally{
try {
snowflakeStatement.close();
} catch (SQLException sqlEx) {
log.error("Error closing the statement", sqlEx);
}
}
}

How to reduce code duplication when using non-compatible wrappers

[TL;DR]
The problem is, in AWrapper and AType I have to duplicate pretty much whole function, where there is always the syntax:
public [TYPE/void] METHOD([OPT: args]) throws TestFailedException {
[OPT: TYPE result = null;]
long startTime = System.currentTimeMillis();
while (true) {
try {
beforeOperation();
[OPT: result =] ((WrappedType) element).METHOD([OPT: args]);
handleSuccess();
break;
} catch (Exception e) {
handleSoftFailure(e);
if (System.currentTimeMillis() - startTime > TIMEOUT) {
handleFailure(e);
break;
} else {
try {
Thread.sleep(WAIT_FOR_NEXT_TRY);
} catch (InterruptedException ex) {
}
}
}
}
[OPT: return result;]
}
Lets say I have 2 classes I don't own:
public class IDontOwnThisType {
public void doA(String string) { System.out.println("doA"); }
public String doB(); {System.out.println("doB"); return "doB";}
public OtherTypeIDoNotOwn doC() {System.out.println("doC"); return new OtherTypeIDoNotOwn();}
}
public OtherTypeIDoNotOwn {
public void doD() { System.out.println("doD"); }
public String doE() { System.out.println("doE); }
public OtherTypeIDoNotOwn doF(String string) {System.out.println("doF"); return new OtherTypeIDoNotOwn();}
}
So, I have an interface:
public interface OperationManipulator {
void beforeOperation(); //called before operation
void handleSuccess(); //called after success
void handleSoftFailure(Exception e); //called after every failure in every try
void handleFailure(Exception e) throws TestFailedException; //called after reaching time limit
}
Then interface that extends above one, "mimicking" methods of external classes, but throwing custom exception:
public interface IWrapper<T extends IType> extends OperationManipulator {
public void doA(String string) throws TestFailedException;
public String doB() throws TestFailedException;
public T doC() throws TestFailedException;
}
Then we have IType, which also extends OperationManipulator:
public interface IType<T extends IType> extends OperationManipulator {
public void doD() throws TestFailedException;
public String doE() throws TestFailedException;
public T doF(String string) throws TestFailedException;
}
Then, we have abstract implementations of above interfaces:
public abstract class AType<T extends IType> implements IType{
Object element; // I do not own type of this object, cant modify it.
Class typeClass;
long TIMEOUT = 5000;
long WAIT_FOR_NEXT_TRY = 100;
public AType(Object element) {
this.element = element;
elementClass = this.getClass();
}
/* ... */
}
Then, we override functions from the interfaces, excluding OperationManipulator interface:
Function not returning anything version:
#Override
public void doD() throws TestFailedException {
long startTime = System.currentTimeMillis();
while (true) {
try {
beforeOperation();
((OtherTypeIDoNotOwn) element).doD();
handleSuccess();
break;
} catch (Exception e) {
handleSoftFailure(e);
if (System.currentTimeMillis() - startTime > TIMEOUT) {
handleFailure(e);
break;
} else {
try {
Thread.sleep(WAIT_FOR_NEXT_TRY);
} catch (InterruptedException ex) {
}
}
}
}
Function returning normal reference version:
#Override
public String doE() throws TestFailedException {
String result = null;
long startTime = System.currentTimeMillis();
while (true) {
try {
beforeOperation();
result = ((OtherTypeIDoNotOwn) element).doE();
handleSuccess();
break;
} catch (Exception e) {
handleSoftFailure(e);
if (System.currentTimeMillis() - startTime > TIMEOUT) {
handleFailure(e);
break;
} else {
try {
Thread.sleep(WAIT_FOR_NEXT_TRY);
} catch (InterruptedException ex) {
}
}
}
}
return result;
}
And function returning object of type parameter:
#Override
public T doF(String string) throws TestFailedException {
T result = null;
long startTime = System.currentTimeMillis();
while (true) {
try {
beforeOperation();
OtherTypeIDoNotOwn temp = ((OtherTypeIDoNotOwn) element).doF(string);
result = (T) elementClass.getDeclaredConstructor(Object.class).newInstance(temp);
handleSuccess();
break;
} catch (Exception e) {
handleSoftFailure(e);
if (System.currentTimeMillis() - startTime > TIMEOUT) {
handleFailure(e);
break;
} else {
try {
Thread.sleep(WAIT_FOR_NEXT_TRY);
} catch (InterruptedException ex) {
}
}
}
}
return result;
}
The same goes for AWrapper, but the differences are:
constructor have class argument of stored type
object is cast to IDoNotOwnThisType instead of OtherTypeIDoNotOwn. Functions of this object also may return OtherTypeIDoNotOwn.
IDoNotOwnThisType is type that AWrapper is wrapping.
OtherTypeIDoNotOwn is type that AType is wrapping.
Then, we have implementation of these abstract classes:
public class AssertingType extends AType<AssertingType> {
public AssertingType(Object element) {
super(element);
}
#Override
public void beforeOperation() {
//System.out.println("Asserting type before operation!");
}
#Override
public void handleSuccess() {
//TODO: add to log file and log to output
System.out.println("Asserting type success!");
}
#Override
public void handleFailure(Exception e) throws TestFailedException {
//TODO: add to log file, log to output and throw exception
System.out.println("Asserting type failure!");
e.printStackTrace();
throw new TestFailedException();
}
#Override
public void handleSoftFailure(Exception e) {
//TODO: add to log file, log to output
System.out.println("Asserting type soft failure!");
e.printStackTrace();
}
}
And:
public class AssertingWrapper extends AWrapper<AssertingType> {
public AssertingWrapper (Object driver) {
super(driver, AssertingType.class);
}
#Override
public void beforeOperation() {
//TODO
System.out.println("Asserting wrapper success!");
}
#Override
public void handleSuccess() {
//TODO: add to log file and log to output
System.out.println("Asserting wrapper success!");
}
#Override
public void handleFailure(Exception e) throws TestFailedException {
//TODO: add to log file, log to output and throw exception
System.out.println("Asserting wrapper failure!");
throw new TestFailedException();
}
#Override
public void handleSoftFailure(Exception e) {
//TODO: add to log file, log to output
System.out.println("Asserting wrapper soft failure!");
e.printStackTrace();
}
}
So, we can use it like that:
AssertingWrapper wrapper = new AssertingWrapper(new IDoNotOwnThisType());
AssertingType type = wrapper.doC();
AssertingType type2 = type.doF();
Output:
Asserting wrapper before operation!
doC
Asserting wrapper success!
Asserting type before operation!
doF
Asserting type success!
The full working code is here:
LIVE
The problem is, I have always to write while, try catch etc in AType and AWrapper, can I somehow reduce code duplication? In the example i provided just 3 functions per class, but in my real code I have 50+ methods. Can I somehow wrap these functions so thepart that is repeating is not duplicated?
Your problem appears to be quite complicated, and I cannot claim to have been able to successfully wrap my mind around it, but I will give it a try, because it appears to be a very interesting problem and because I happen to have some experience in dealing with situations that yours appears similar to.
Please excuse me if my answer turns out to be completely off the mark due to a misunderstanding on my part.
So, what it appears that you are looking for is a general purpose solution for injecting your own code before and after an invocation where the invocation may be to any method, accepting any number of parameters, and returning any kind of return value.
In java there exists a dynamic proxy facility, which you can find under java.lang.reflect.Proxy.
With it, you can do the following:
ClassLoader classLoader = myInterfaceClass.getClassLoader();
T temp = (T)Proxy.newProxyInstance( classLoader, new Class<?>[] { myInterfaceClass },
invocationHandler );
The invocationHandler is supplied by you, and it is of the following form:
private final InvocationHandler invocationHandler = new InvocationHandler()
{
#Override
public Object invoke( Object proxy, Method method, Object[] arguments )
throws Throwable
{
/* your pre-invocation code goes here */
/* ... */
/* invoke original object */
Object result = method.invoke( myObject, arguments );
/* your post-invocation code goes here */
/* ... */
/* return the result (will probably be null if method was void) */
return result;
}
};
So, I think you might be able to use that to solve your problem with the minimum amount of code.
Neither the creation of a dynamic proxy nor the call to method.invoke() perform terribly well, (you know, reflection is somewhat slow,) but if you are using it for testing, it should not matter.

Create an exception-safe wrapper of a class

I have a legacy class C1, implementing interface I, that may throw some exceptions.
I want to create a class C2, also implementing interface I, that is based on an instance of C1, but catches all exceptions and does something useful about them.
Currently my implementation looks like this:
class C2 implements I {
C1 base;
#Override void func1() {
try {
base.func1();
} catch (Exception e) {
doSomething(e);
}
}
#Override void func2() {
try {
base.func2();
} catch (Exception e) {
doSomething(e);
}
}
...
}
(Note: I could also make C2 extend C1. This does not matter for the current question).
The interface contains many functions, so I have to write the same try... catch block again and again.
Is there a way to reduce the amount of code duplication here?
You can make a Proxy, it could actually be generic
interface I1 {
void test();
}
class C1 implements I1 {
public void test() {
System.out.println("test");
throw new RuntimeException();
}
}
class ExceptionHandler implements InvocationHandler {
Object obj;
ExceptionHandler(Object obj) {
this.obj = obj;
}
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
return method.invoke(obj, args);
} catch (Exception e) {
// need a workaround for primitive return types
return null;
}
}
static <T> T proxyFor(Object obj, Class<T> i) {
return (T) Proxy.newProxyInstance(obj.getClass().getClassLoader(), new Class[] { i },
new ExceptionHandler(obj));
}
}
public class Test2 {
public static void main(String[] args) throws Exception {
I1 i1 = ExceptionHandler.proxyFor(new C1(), I1.class);
i1.test();
}
}

java generic cast question

I want to implement a sort of transfer object pattern. So, i have a method that fills object´s properties via BeanUtils.copyProperties(..,..) (apache common).
Here is the code:
public abstract class BaseTO<TObject> {
public Long id;
/***
* Obtains id of the object that´s transfered
* #return object´s id
*/
public Long getId() {
return id;
}
/****
* set transfered object´s id
* #param id object´s id
*/
public void setId(Long id) {
this.id = id;
}
/***
* Fill transfer object properties.
* #param entity entity to be transfered
* #return self reference
*/
public BaseTO<TObject> build(TObject entity){
try {
BeanUtils.copyProperties(this, entity);
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
customDataTransformation(entity);
return this;
}
protected void customDataTransformation(TObject entity) {
}
}
CustomerTO Class
public class CustomerTO extends BaseTO<Customer> {
private String name;
private String surname;
private String email;
private String sex;
private DocumentType documentType;
private String documentNumber;
--- getters and setters
#Override
protected void customDataTransformation(Customer entity) {
this.sex = Sex.MALE.equals(entity.getSex()) ? "M" : "F";
}
}
the problem
CustomerTO toEdit = (CustomerTO) (customerId!=null ? new CustomerTO().build(entityObject):new CustomerTO());
as you can see here have to cast to (CustomerTO). I want if it´s possible avoid that, to make the code simpler.
Is it posible that public BaseTO build(TObject entity) can return the object of the subclass??
I hope to be clear.
Thanks in advance.
Maybe try this:
class BaseTO<TObject, R extends BaseTO<TObject,R>> {
public R build(TObject entity) {
and then CustomerTO:
class CustomerTO extends BaseTO<Customer, CustomerTO> {
or less restrictively, only change the build signature:
public <X extends BaseTO<TObject>> X build(TObject entity) {
But IMHO better approach will be simply adding constructor to TO with TObject parameter.
public BaseTO(TObject entity) {
try {
BeanUtils.copyProperties(this, entity);
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
customDataTransformation(entity);
}
then in each extending class create simple constructor
public CustomerTO(Customer entity) {
super(entity);
}
and forget about the build method and use it simply
CustomerTO toEdit = (customerId!=null ? new CustomerTO(entityObject):new CustomerTO());
This compiles:
public class BaseTO<T> {
public BaseTO<T> build(T entity) {
return this;
}
public static class CustomerTO extends BaseTO<String> {
#Override public CustomerTO build(String string) {
return (CustomerTO) super.build(string);
}
}
but you will have to override build for all subclasses of BaseTO. You write explicitly the cast only once instead of every time you call build.
EDIT: see the point raised by #Paul in the comments above. You might be suffering from "give a man a hammer and everything looks like a nail to him."

Categories