How to pass an Object with annotation? - java

I'm trying to use annotated class as parameters like below:
#Target(ElementType.TYPE)
#Retention(RetentionPolicy.RUNTIME)
public #interface ContextHolder {
}
#ContextHolder
class Foo extends Context {
}
// In some other place
protected Context getContext(ActionHandler handler) {
if (handler.getClass().isAssignableFrom(Context.class)) {
return (Context) handler;
}
for (Method m : handler.getClass().getDeclaredMethods()) {
if (m.getReturnType().isAssignableFrom(Context.class)) {
try {
return (Context) m.invoke(handler);
} catch (IllegalAccessException e) {
ALog.w("", e);
} catch (IllegalArgumentException e) {
ALog.w("", e);
} catch (InvocationTargetException e) {
ALog.w("", e);
}
break;
}
}
ALog.e("Can't find Context in passed ActionHandler");
return null;
}
Foo foo = ...;
getContext(foo?)
The problem is I don't know how to call getContext(). Simply passing foo results compile error.
Any hint will be appreciated. Thanks!

Related

Spring: Generic Resource Controller

I want to create a generic controller that would like something like this:
#RequestMapping("/api/v1/resource/{resource}")
public class StandardController {
private StandardResourceService standardResourceService;
public StandardController(StandardResourceService standardResourceService) {
this.standardResourceService = standardResourceService;
}
#GetMapping("/{id}")
public Object getResource(
#PathVariable(value="resource") String resource,
#PathVariable(value="id") Long id,
HttpServletRequest request){
return standardResourceService.getEntity(id, resource);
}
#PostMapping
#Transactional
Object newResource(#PathVariable(value="resource") String resource, #RequestBody Object newObject) {
standardResourceService.postResource(resource, newObject);
return newObject;
}
}
The idea is that I don't want to have a lot of endpoints/services/controllers for each entity I'll define in the project. I want to create a standard one for each entity and if I need some custom behaviour for some entities, I'll just extend the base service/controller.
The service I've made looks like this:
#Service
public class StandardResourceService {
#Autowired
private EntityManager entityManager;
#Autowired
private ModelMapper modelMapper;
public <T, ID> T findById(Class<T> type, ID id) {
return entityManager.find(type, id);
}
#Transactional
public void saveObject(Object object) {
entityManager.persist(object);
}
public Object getEntity(long resourceId, String resource) throws EntityNotFoundException {
Object resourceOpt;
Object dto;
try{
Class<?> cls = Class.forName("com.base.package.models." + resource);
resourceOpt = findById(cls, resourceId);
}catch (ClassNotFoundException ex){
throw new EntityNotFoundException("Resource " + resource + " could not be found with id: " + resourceId);
}
if(resourceOpt == null) {
throw new EntityNotFoundException("Resource " + resource + " could not be found with id: " + resourceId);
}
try {
Class<?> dtoClass = Class.forName("com.base.package.dto." + resource + "DTO");
dto = modelMapper.map(resourceOpt, dtoClass);
} catch (ClassNotFoundException ex) {
return resourceOpt;
}
return dto;
}
public Object postResource(String resource, Object newObject) throws RuntimeException {
try{
Class<?> clazz = Class.forName("com.base.package.models." + resource);
//saveObject(instance);
}catch (ClassNotFoundException ex){
throw new EntityNotFoundException("");
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
return newObject;
}
}
The GET is working pretty good. I return a DTO if any, otherwise I return the entity itself.
By the way when using the POST I don't know how to instantiate the correct class with the body I'm sending in the POST.
Is there a way to do this?
Am I approaching this problem correctly?

How to regroup catch finally into one method in java 8?

New to java 8, I would like to optimise my code bellow:
public Response create() {
try{
...
} catch (Exception e) {
codeA;
} finally {
codeB;
}
}
public Response update() {
try{
...
} catch (Exception e) {
codeA;
} finally {
codeB;
}
}
I have a lot of methods using this same way to catch exceptions and do the same finally, is that possible to replace the bellow common code by a method in java 8? So that I could optimise all my methods who use this common code.
} catch (Exception e) {
codeA;
} finally {
codeB;
}
Depends what you do in the .... You could do something like this:
private Response method(Supplier<Response> supplier) {
try{
return supplier.get();
} catch (Exception e) {
codeA;
} finally {
codeB;
}
}
and invoke like:
public Response create() { return method(() -> { ... for create }); }
public Response update() { return method(() -> { ... for update }); }
You could wrap your payload and put it to the separate method. One thing; what do you expect to return on exception catch. This time this is null, but probably you could provide default value.
public static <T> T execute(Supplier<T> payload) {
try {
return payload.get();
} catch(Exception e) {
// code A
return null;
} finally {
// code B
}
}
Client code could look like this:
public Response create() {
return execute(() -> new CreateResponse());
}
public Response update() {
return execute(() -> new UpdateResponse());
}
This could be a generic solution.
//here describe supplier which can throw exceptions
#FunctionalInterface
public interface ThrowingSupplier<T> {
T get() throws Exception;
}
// The wrapper
private <T> T callMethod(ThrowingSupplier<T> supplier) {
try {
return supplier.get();
} catch (Exception e) {
//code A
}finally {
// code B
}
}

Refactoring duplication with two different return types in java

Say I have these lines of code in all of my controllers:
public View ControllerClass() {
// ...
// some code in controller
SomeClass someClass;
try {
someClass = Util.getParam(
context.getEncryptedParam(), soemthignElse.getSomething());
} catch (SomeException ex) {
log.error(ex);
return viewBuilderFactory.view1.view();
} catch (AnotherException ex) {
return viewBuilderFactory.view2.view();
} catch (etc ...) {}
// use someClass
// ...
return viewBuilderFactory.view3.view();
}
In this case I'd have two different return types (void and view) if I want to move the duplication to its own method. What'd be a good approach here?
Your code is best restructured as follows:
public View ControllerClass() {
ViewBuilderFactoryView viewBuilderFactoryView;
try {
SomeClass someClass = Util.getParam(
context.getEncryptedParam(), soemthignElse.getSomething());
// use someClass
// ...
viewBuilderFactoryView = viewBuilderFactory.view3;
} catch (SomeException ex) {
log.error(ex);
viewBuilderFactoryView = viewBuilderFactory.view1;
} catch (AnotherException ex) {
viewBuilderFactoryView = viewBuilderFactory.view2;
} catch (etc ...) {}
return viewBuilderFactoryView.view();
}
In other words, if you successfully obtain a SomeClass, go ahead and use it, and afterwards return some View. If you do not successfully obtain a SomeClass, then just return some View.

Common Argument Pass in Method

I have a method called makePersistent in my DAO class.
Currntly we have this method in all dao classes and what i need to do is convert this method to common format. So is there any way to do it?
Method in UserDao Class
public void makePersistent(User model) throws InfrastructureException {
try {
getSession().saveOrUpdate(model);
getSession().flush();
getSession().clear();
} catch (org.hibernate.StaleObjectStateException ex) {
throw new InfrastructureException(Labels.getString("com.tran.msg.objectDeletedOrUpdated"));
} catch (HibernateException ex) {
throw new InfrastructureException(ex);
}
}
Method in HolidayDao Class
public void makePersistent(Holiday model) throws InfrastructureException {
try {
getSession().saveOrUpdate(model);
getSession().flush();
getSession().clear();
} catch (org.hibernate.StaleObjectStateException ex) {
throw new InfrastructureException(Labels.getString("com.tran.msg.objectDeletedOrUpdated"));
} catch (HibernateException ex) {
throw new InfrastructureException(ex);
}
}
Please help me to get rid of this redundant coding.
Thank you.
Just use Object the hibernate will persist it.
public void makePersistent(Object model) throws InfrastructureException {
try {
getSession().saveOrUpdate(model);
getSession().flush();
getSession().clear();
} catch (org.hibernate.StaleObjectStateException ex) {
throw new InfrastructureException(Labels.getString("com.tran.msg.objectDeletedOrUpdaed"));
} catch (HibernateException ex) {
throw new InfrastructureException(ex);
}
}
Create a superclass for your DAOs with a type parameter and make your DAO classes extend that superclass with the appropriate type argument. For example:
public class BaseDao<T> {
public void makePersistent(T model) throws InfrastructureException {
try {
getSession().saveOrUpdate(model);
getSession().flush();
getSession().clear();
} catch (org.hibernate.StaleObjectStateException ex) {
throw new InfrastructureException(Labels.getString("com.tran.msg.objectDeletedOrUpdated"));
} catch (HibernateException ex) {
throw new InfrastructureException(ex);
}
}
}
public class UserDao extends BaseDao<User> {
// ...
}
public class HolidayDao extends BaseDao<Holiday> {
// ...
}
UserDao and HolidayDao inherit the makePersistent method from BaseDao, so you don't have to implement it again in every DAO class.

how to use generic jsonFile handler using guice?

I have 2 repositories classes:
public class ResponseRepository implements IRoutingResponseRepository {
private final String baselineFileName;
#Inject
#Singleton
public ResponseRepository(#Named("baseline_file") String baselineFileName) {
this.baselineFileName = baselineFileName;
}
#Override
public E2EResult getBaseLine() {
E2EResult e2EResult = null;
ObjectMapper mapper = new ObjectMapper();
try
{
e2EResult = mapper.readValue(new File(baselineFileName), E2EResult.class);
} catch (JsonGenerationException e)
{
e.printStackTrace();
} catch (JsonMappingException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
return e2EResult;
}
}
and
public class StatsRepository implements IRoutingResponseRepository {
private final String baselineFileName;
#Inject
#Singleton
public StatsRepository(#Named("stats_file") String baselineFileName) {
this.baselineFileName = baselineFileName;
}
#Override
public StatsObj getStats() {
StatsObj statsObj = null;
ObjectMapper mapper = new ObjectMapper();
try
{
statsObj = mapper.readValue(new File(baselineFileName), StatsObj.class);
} catch (JsonGenerationException e)
{
e.printStackTrace();
} catch (JsonMappingException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
return statsObj;
}
}
how can I refactor the common code to be generic one?
and also I want guice to use fileName = E2EResult.csv when <E2EResult> and fileName = StatsObj.csv when <StatsObj>
I have tried:
but I wrote the generics incorrectly. It shows an error.
And also i'm not sure how to let guice inject different fileName
public interface IFileHandler<T> {
T getContent();
}
and
public class JsonFileHandler implements IFileHandler<T> {
String fileName;
#Inject
public JsonFileHandler(String file) {
this.fileName = file;
//Constants.RESULTS_BASELINE_FILE
}
public <T> T getContent() {
T t = null;
ObjectMapper mapper = new ObjectMapper();
try {
t = mapper.readValue(new File(fileName), T.class);
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return t;
}
}
For the type variable part, it would be, with this interface:
public interface IFileHandler<T> {
T getContent();
}
this implementing class declaration and method signature:
class JsonFileHandler<T> implements IFileHandler<T> {
public T getContent() {
T t = null;
// ...
return t;
}
}

Categories

Resources