package com.itedge.infrastructure.web.taskhandler.impl;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.context.MessageSource;
import org.springframework.format.support.FormattingConversionServiceFactoryBean;
import org.springframework.web.bind.ServletRequestDataBinder;
import com.itedge.infrastructure.constants.InfrastructureConstants;
import com.itedge.infrastructure.domain.IProcessEntity;
import com.itedge.infrastructure.service.process.IProcessService;
import com.itedge.infrastructure.service.task.ITaskService;
import com.itedge.infrastructure.service.taskdata.ITaskDataEntityService;
import com.itedge.infrastructure.taskdata.ITaskDataEntity;
import com.itedge.infrastructure.util.ContextUtil;
import com.itedge.infrastructure.web.dto.TaskAvailabilityResponse;
import com.itedge.infrastructure.web.taskhandler.ITaskDataHandler;
import com.itedge.infrastructure.web.taskhandler.TaskHandlerException;
/**
* Abstract class containing some common functionality for task handlers.
*
* @author jhe
*
* @param <T extends ITaskData>
* @param <O extends IProcessEntity>
*/
public abstract class AbstractTaskDataHandler<T extends ITaskDataEntity, O extends IProcessEntity>
implements ITaskDataHandler<T, O> {
/** Conversion service bean. */
protected FormattingConversionServiceFactoryBean conversionService;
/** Message source instance. */
protected MessageSource messageSource;
/** Process service instance. */
protected IProcessService<O> processService;
/** Task data service instance. */
protected ITaskDataEntityService<T> taskDataService;
/** Task service instance. */
protected ITaskService<T,O> taskService;
/**
* Default constructor, sets all needed bean and service instances.
*
* @param conversionService
* @param processService
* @param taskDataService
* @param taskService
* @param messageSource
*/
protected AbstractTaskDataHandler(FormattingConversionServiceFactoryBean conversionService,
IProcessService<O> processService, ITaskDataEntityService<T> taskDataService,
ITaskService<T,O> taskService, MessageSource messageSource) {
this.conversionService = conversionService;
this.messageSource = messageSource;
this.processService = processService;
this.taskDataService = taskDataService;
this.taskService = taskService;
}
/**
* Implementing subclasses should return Class instance of related task data.
*
* @return class instance
*/
abstract protected Class<T> getTaskDataClass();
@Override
public Map<String,Object> loadTaskData(String taskId, O linkedObject, Boolean forHistory)
throws TaskHandlerException {
T taskData = taskDataService.findEntityByProcessTaskId(taskId);
if (taskData == null) {
try {
taskData = getTaskDataClass().newInstance();
} catch (Exception e) {
throw new TaskHandlerException(e.getMessage(),e.getCause());
}
}
taskData.setTaskId(taskId);
Map<String,Object> data = new HashMap<String,Object>();
data.put("taskData", taskData);
return data;
}
@Override
public void saveTaskData(T taskData) {
taskDataService.merge(taskData);
}
@Override
public void saveTaskDataAndPushProcess(T taskData, O linkedObject, String taskId) {
taskService.completeTask(taskId, linkedObject, taskData, ContextUtil.getLoggedUsername());
}
@Override
public TaskAvailabilityResponse requestTaskAvailabilityAndLockTask(String taskId, String lockedBy, Locale locale) {
TaskAvailabilityResponse response = new TaskAvailabilityResponse();
// check if task is available
if (processService.getTaskById(taskId) != null) {
// lock associated
response.setAvailable(taskDataService.lock(taskId, lockedBy));
} else {
response.setAvailable(false);
response.setMessage(messageSource.getMessage(InfrastructureConstants.TASK_LOCKED_OR_COMPLETED,
null, InfrastructureConstants.UNDEFINED_MESSAGE, locale));
}
return response;
}
@Override
public TaskAvailabilityResponse requestTaskAvailability(String taskId, Locale locale) {
TaskAvailabilityResponse response = new TaskAvailabilityResponse();
// check if task is available
if (processService.getTaskById(taskId) != null) {
response.setAvailable(true);
} else {
response.setAvailable(false);
response.setMessage(messageSource.getMessage(InfrastructureConstants.TASK_LOCKED_OR_COMPLETED,
null, InfrastructureConstants.UNDEFINED_MESSAGE, locale));
}
return response;
}
@Override
public T bindTaskData(HttpServletRequest request, O linkedObject)
throws TaskHandlerException {
T taskData;
try {
taskData = getTaskDataClass().newInstance();
} catch (Exception e) {
throw new TaskHandlerException(e.getMessage(),e.getCause());
}
ServletRequestDataBinder binder = new ServletRequestDataBinder(taskData);
binder.setConversionService(conversionService.getObject());
binder.bind(request);
try {
binder.closeNoCatch();
} catch(Exception e) {
throw new TaskHandlerException(e.getMessage(),e.getCause());
}
return taskData;
}
}