package net.techreadiness.ui.action.task.batch;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import javax.inject.Inject;
import net.techreadiness.navigation.taskflow.filebatch.FileBatchTaskFlowData;
import net.techreadiness.navigation.taskflow.filebatch.FileBatchTaskFlowDefinition;
import net.techreadiness.persistence.dao.FileDAO.FileTypeCode;
import net.techreadiness.service.BatchJobSchedulerService;
import net.techreadiness.service.DataModificationStatus;
import net.techreadiness.service.DataModificationStatus.ModificationState;
import net.techreadiness.service.FileService;
import net.techreadiness.service.exception.ServiceException;
import net.techreadiness.ui.tags.datagrid.DataGridState;
import net.techreadiness.ui.task.BaseTaskFlowAction;
import net.techreadiness.ui.task.Task;
import net.techreadiness.ui.task.TaskFlowState;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Result;
import com.google.common.collect.Lists;
import com.google.common.io.Files;
import com.opensymphony.xwork2.Preparable;
import com.opensymphony.xwork2.util.CreateIfNull;
public class FileBatchTaskFlowAction extends BaseTaskFlowAction<FileBatchTaskFlowData, FileBatchTaskFlowDefinition>
implements Preparable {
public enum BatchMode {
Append, Replace;
@Override
public String toString() {
return name().toLowerCase();
}
}
private static final long serialVersionUID = 1L;
private static final String FILE_REQUIRED = "Incomplete information, a file must be selected.";
private static final String AN_ERROR_OCCURRED_FOR_THIS_REQUEST = "An error occurred for this request";
protected File upload;
protected String uploadFileName;
protected String uploadContentType;
@Inject
private FileService fileService;
@Inject
private BatchJobSchedulerService bsService;
@Inject
private DataModificationStatus dataModificationStatus;
@Inject
private FileBatchTaskFlowDefinition tfd;
// Matches what is defined on the file action for the datagrid
// @ConversationScoped(value="fileDataGrid")
private static String FILE_DATA_GRID = "fileDataGrid";
@CreateIfNull
private net.techreadiness.service.object.File serviceFile;
public List<FileTypeCode> getTypes() {
return Collections.emptyList();
}
@Action(value = "fileBatchTaskFlowBegin", results = { @Result(name = "success", type = "redirectAction", params = {
"actionName", "${taskFlowData.taskFlowState.currentTask.action}", "namespace",
"${taskFlowData.taskFlowState.currentTask.namespace}" }) })
public String beginTaskFlow() {
startNewTaskFlow();
DataGridState<net.techreadiness.service.object.File> fileGrid = conversation
.get(DataGridState.class, FILE_DATA_GRID);
List<net.techreadiness.service.object.File> list = fileGrid.getSelectedItems();
getTaskFlowData().setFiles(new ArrayList<>(list));
return SUCCESS;
}
protected String scheduleImport() {
try {
if (upload == null) {
addFieldError("upload", FILE_REQUIRED);
dataModificationStatus.setModificationState(ModificationState.FAILURE);
return "invalid";
}
moveFileToUploadFolder();
serviceFile.setDisplayFilename(uploadFileName);
serviceFile.setFilename(upload.getName());
serviceFile.setPath(upload.getParentFile().getPath());
serviceFile.setRequestDate(new Date());
serviceFile.setStatus("pending");
serviceFile = fileService.addOrUpdate(getServiceContext(), serviceFile);
bsService.schedule(getServiceContext(), serviceFile.getFileId());
dataModificationStatus.setModificationState(ModificationState.SUCCESS);
return SUCCESS;
} catch (Exception e) {
addActionError(AN_ERROR_OCCURRED_FOR_THIS_REQUEST);
dataModificationStatus.setModificationState(ModificationState.FAILURE);
return "invalid";
}
}
protected String scheduleExport() {
try {
serviceFile.setPath(fileService.getUploadDir(getServiceContext()));
String internalFileName = getInternalFileName();
serviceFile.setFilename(internalFileName);
serviceFile.setDisplayFilename(internalFileName);
serviceFile.setStatus("pending");
serviceFile.setRequestDate(new Date());
serviceFile = fileService.addOrUpdate(getServiceContext(), serviceFile);
bsService.schedule(getServiceContext(), serviceFile.getFileId());
dataModificationStatus.setModificationState(ModificationState.SUCCESS);
return SUCCESS;
} catch (Exception e) {
addActionError(AN_ERROR_OCCURRED_FOR_THIS_REQUEST);
dataModificationStatus.setModificationState(ModificationState.FAILURE);
return "invalid";
}
}
public List<BatchMode> getModes() {
return Collections.emptyList();
}
@Override
public void prepare() throws Exception {
serviceFile = new net.techreadiness.service.object.File();
}
private void moveFileToUploadFolder() throws IOException {
String internalFileName = getInternalFileName();
File moved = new File(fileService.getUploadDir(getServiceContext()), internalFileName);
try {
Files.move(upload, moved);
} catch (Exception e) {
throw new FileNotFoundException("Failed to rename/move uploaded file: " + moved.getName());
}
upload = moved;
}
private String getInternalFileName() {
StringBuilder sb = new StringBuilder();
sb.append(serviceFile.getFileTypeCode());
sb.append("-");
sb.append(getServiceContext().getOrgId());
sb.append("-");
sb.append(System.currentTimeMillis());
sb.append(".csv");
return sb.toString();
}
@Action(value = "altFileTaskFlowBegin", results = { @Result(name = "success", type = "redirectAction", params = {
"actionName", "${taskFlowData.taskFlowState.currentTask.action}", "namespace",
"${taskFlowData.taskFlowState.currentTask.namespace}" }) })
public String altBeginTaskFlow() throws ServiceException {
getTaskFlowData().setStandardInvocation(false);
return SUCCESS;
}
public void setUpload(File upload) {
this.upload = upload;
}
public void setUploadFileName(String uploadFileName) {
this.uploadFileName = uploadFileName;
}
public void setUploadContentType(String uploadContentType) {
this.uploadContentType = uploadContentType;
}
public net.techreadiness.service.object.File getServiceFile() {
return serviceFile;
}
public void setServiceFile(net.techreadiness.service.object.File serviceFile) {
this.serviceFile = serviceFile;
}
protected void initialize(String task) {
// if invoked thru external task link, bootstrap state if necessary
if (taskFlowStateNeedsReset(task)) {
TaskFlowState state = new TaskFlowState();
state.setTasks(Lists.newArrayList(tfd.getTask(task)));
getTaskFlowData().setTaskFlowState(state);
}
}
private boolean taskFlowStateNeedsReset(String task) {
if (getTaskFlowData().getTaskFlowState() == null) {
return true;
}
for (Task stateTask : getTaskFlowData().getTaskFlowState().getTasks()) {
if (stateTask.getTaskName().equals(task)) {
return false;
}
}
return true;
}
}