package org.akaza.openclinica.controller; import org.akaza.openclinica.bean.core.Role; import org.akaza.openclinica.bean.extract.DatasetBean; import org.akaza.openclinica.bean.extract.ExtractPropertyBean; import org.akaza.openclinica.bean.login.StudyUserRoleBean; import org.akaza.openclinica.bean.login.UserAccountBean; import org.akaza.openclinica.dao.core.CoreResources; import org.akaza.openclinica.dao.extract.DatasetDAO; import org.akaza.openclinica.i18n.core.LocaleResolver; import org.akaza.openclinica.i18n.util.ResourceBundleProvider; import org.akaza.openclinica.service.extract.ExtractUtils; import org.akaza.openclinica.service.extract.XsltTriggerService; import org.akaza.openclinica.web.SQLInitServlet; import org.apache.commons.dbcp.BasicDataSource; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SimpleTrigger; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.ApplicationContext; import org.springframework.scheduling.quartz.JobDetailFactoryBean; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.context.ContextLoader; import org.springframework.web.context.WebApplicationContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.text.SimpleDateFormat; import java.util.Date; @Controller("extractController") @RequestMapping("/extract") public class ExtractController { @Autowired @Qualifier("sidebarInit") private SidebarInit sidebarInit; @Autowired @Qualifier("dataSource") private BasicDataSource dataSource; private DatasetDAO datasetDao; @Autowired private Scheduler scheduler; public static String TRIGGER_GROUP_NAME = "XsltTriggers"; protected final Logger logger = LoggerFactory.getLogger(getClass().getName()); public ExtractController() { } /** * process the page from whence you came, i.e. extract a dataset * @param id, the id of the extract properties bean, gained from Core Resources * @param datasetId, the id of the dataset, found through DatasetDAO * @param request, http request * @return model map, but more importantly, creates a quartz job which runs right away and generates all output there */ @RequestMapping(method = RequestMethod.GET) public ModelMap processSubmit(@RequestParam("id") String id, @RequestParam("datasetId") String datasetId, HttpServletRequest request, HttpServletResponse response) { if(!mayProceed(request)){ try{ response.sendRedirect(request.getContextPath() + "/MainMenu?message=authentication_failed"); }catch (Exception e){ e.printStackTrace(); } return null; } ModelMap map = new ModelMap(); ResourceBundleProvider.updateLocale(LocaleResolver.getLocale(request)); // String datasetId = (String)request.getAttribute("datasetId"); // String id = (String)request.getAttribute("id"); logger.debug("found both id " + id + " and dataset " + datasetId); ExtractUtils extractUtils = new ExtractUtils(); // get extract id // get dataset id // if id is a number and dataset id is a number ... datasetDao = new DatasetDAO(dataSource); UserAccountBean userBean = (UserAccountBean) request.getSession().getAttribute("userBean"); CoreResources cr = new CoreResources(); ExtractPropertyBean epBean = cr.findExtractPropertyBeanById(new Integer(id).intValue(),datasetId); DatasetBean dsBean = (DatasetBean)datasetDao.findByPK(new Integer(datasetId).intValue()); // set the job in motion String[] files = epBean.getFileName(); String exportFileName; int fileSize = files.length; int cnt = 0; SimpleTrigger simpleTrigger = null; //TODO: if files and export names size is not same... throw an error dsBean.setName(dsBean.getName().replaceAll(" ", "_")); String[] exportFiles= epBean.getExportFileName(); String pattern = "yyyy" + File.separator + "MM" + File.separator + "dd" + File.separator + "HHmmssSSS" + File.separator; SimpleDateFormat sdfDir = new SimpleDateFormat(pattern); int i =0; String[] temp = new String[exportFiles.length]; //JN: The following logic is for comma separated variables, to avoid the second file be treated as a old file and deleted. while(i<exportFiles.length) { temp[i] = resolveVars(exportFiles[i],dsBean,sdfDir, SQLInitServlet.getField("filePath"), extractUtils); i++; } epBean.setDoNotDelFiles(temp); epBean.setExportFileName(temp); XsltTriggerService xsltService = new XsltTriggerService(); // TODO get a user bean somehow? String generalFileDir = SQLInitServlet.getField("filePath"); generalFileDir = generalFileDir + "datasets" + File.separator + dsBean.getId() + File.separator + sdfDir.format(new java.util.Date()); exportFileName = epBean.getExportFileName()[cnt]; // need to set the dataset path here, tbh logger.debug("found odm xml file path " + generalFileDir); // next, can already run jobs, translations, and then add a message to be notified later //JN all the properties need to have the variables... String xsltPath = SQLInitServlet.getField("filePath") + "xslt" + File.separator +files[cnt]; String endFilePath = epBean.getFileLocation(); endFilePath = getEndFilePath(endFilePath,dsBean,sdfDir, SQLInitServlet.getField("filePath"), extractUtils); // exportFileName = resolveVars(exportFileName,dsBean,sdfDir); if(epBean.getPostProcExportName()!=null) { //String preProcExportPathName = getEndFilePath(epBean.getPostProcExportName(),dsBean,sdfDir); String preProcExportPathName = resolveVars(epBean.getPostProcExportName(),dsBean,sdfDir, SQLInitServlet.getField("filePath"), extractUtils); epBean.setPostProcExportName(preProcExportPathName); } if(epBean.getPostProcLocation()!=null) { String prePocLoc = getEndFilePath(epBean.getPostProcLocation(),dsBean,sdfDir, SQLInitServlet.getField("filePath"), extractUtils); epBean.setPostProcLocation(prePocLoc); } setAllProps(epBean,dsBean,sdfDir, extractUtils); // also need to add the status fields discussed w/ cc: // result code, user message, optional URL, archive message, log file message // asdf table: sort most recent at top logger.debug("found xslt file name " + xsltPath); // String xmlFilePath = generalFileDir + ODMXMLFileName; simpleTrigger = xsltService.generateXsltTrigger(scheduler, xsltPath, generalFileDir, // xml_file_path endFilePath + File.separator, exportFileName, dsBean.getId(), epBean, userBean, LocaleResolver.getLocale(request).getLanguage(),cnt, SQLInitServlet.getField("filePath") + "xslt",this.TRIGGER_GROUP_NAME); // System.out.println("just set locale: " + LocaleResolver.getLocale(request).getLanguage()); cnt++; ApplicationContext context = null; try { context = (ApplicationContext) scheduler.getContext().get("applicationContext"); } catch (SchedulerException e) { e.printStackTrace(); } //WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext(); JobDetailFactoryBean jobDetailFactoryBean = context.getBean(JobDetailFactoryBean.class, simpleTrigger, this.TRIGGER_GROUP_NAME); try { Date dateStart = scheduler.scheduleJob(jobDetailFactoryBean.getObject(), simpleTrigger); logger.debug("== found job date: " + dateStart.toString()); } catch (SchedulerException se) { se.printStackTrace(); } request.setAttribute("datasetId", datasetId); // set the job name here in the user's session, so that we can ping the scheduler to pull it out later if(jobDetailFactoryBean!=null) request.getSession().setAttribute("jobName", jobDetailFactoryBean.getObject().getKey().getName()); if(simpleTrigger!= null) request.getSession().setAttribute("groupName", this.TRIGGER_GROUP_NAME); request.getSession().setAttribute("datasetId", new Integer(dsBean.getId())); return map; } /** * @deprecated Use {@link #setAllProps(ExtractPropertyBean,DatasetBean,SimpleDateFormat,ExtractUtils)} instead */ @Deprecated private ExtractPropertyBean setAllProps(ExtractPropertyBean epBean,DatasetBean dsBean,SimpleDateFormat sdfDir) { return setAllProps(epBean, dsBean, sdfDir,new ExtractUtils()); } private ExtractPropertyBean setAllProps(ExtractPropertyBean epBean,DatasetBean dsBean,SimpleDateFormat sdfDir, ExtractUtils extractUtils) { return extractUtils.setAllProps(epBean, dsBean, sdfDir, SQLInitServlet.getField("filePath")); } //TODO: ${linkURL} needs to be added /** * * for dateTimePattern, the directory structure is created. "yyyy" + File.separator + "MM" + File.separator + "dd" + File.separator, * to resolve location * @param filePath TODO * @param extractUtils TODO */ private String getEndFilePath(String endFilePath,DatasetBean dsBean,SimpleDateFormat sdfDir, String filePath, ExtractUtils extractUtils){ return extractUtils.getEndFilePath(endFilePath, dsBean, sdfDir, filePath); } /** * Returns the datetime based on pattern :"yyyy-MM-dd-HHmmssSSS", typically for resolving file name * @param endFilePath * @param dsBean * @param sdfDir * @return * @deprecated Use {@link #resolveVars(String,DatasetBean,SimpleDateFormat,String, ExtractUtils)} instead */ @Deprecated private String resolveVars(String endFilePath,DatasetBean dsBean,SimpleDateFormat sdfDir){ return resolveVars(endFilePath, dsBean, sdfDir, SQLInitServlet.getField("filePath"),new ExtractUtils()); } /** * Returns the datetime based on pattern :"yyyy-MM-dd-HHmmssSSS", typically for resolving file name * @param endFilePath * @param dsBean * @param sdfDir * @param filePath TODO * @return * @deprecated Use {@link #resolveVars(String,DatasetBean,SimpleDateFormat,String,ExtractUtils)} instead */ @Deprecated private String resolveVars(String endFilePath,DatasetBean dsBean,SimpleDateFormat sdfDir, String filePath){ return resolveVars(endFilePath, dsBean, sdfDir, filePath, new ExtractUtils()); } /** * Returns the datetime based on pattern :"yyyy-MM-dd-HHmmssSSS", typically for resolving file name * @param endFilePath * @param dsBean * @param sdfDir * @param filePath TODO * @param extractUtils TODO * @return */ private String resolveVars(String endFilePath,DatasetBean dsBean,SimpleDateFormat sdfDir, String filePath, ExtractUtils extractUtils){ return extractUtils.resolveVars(endFilePath, dsBean, sdfDir, filePath); } private void setUpSidebar(HttpServletRequest request) { if (sidebarInit.getAlertsBoxSetup() == SidebarEnumConstants.OPENALERTS) { request.setAttribute("alertsBoxSetup", true); } if (sidebarInit.getInfoBoxSetup() == SidebarEnumConstants.OPENINFO) { request.setAttribute("infoBoxSetup", true); } if (sidebarInit.getInstructionsBoxSetup() == SidebarEnumConstants.OPENINSTRUCTIONS) { request.setAttribute("instructionsBoxSetup", true); } if (!(sidebarInit.getEnableIconsBoxSetup() == SidebarEnumConstants.DISABLEICONS)) { request.setAttribute("enableIconsBoxSetup", true); } } public SidebarInit getSidebarInit() { return sidebarInit; } public void setSidebarInit(SidebarInit sidebarInit) { this.sidebarInit = sidebarInit; } private String resolveExportFilePath(String epBeanFileName) { // String retMe = ""; //String epBeanFileName = epBean.getExportFileName(); // important that this goes first, tbh if (epBeanFileName.contains("$datetime")) { String dateTimeFilePattern = "yyyy-MM-dd-HHmmssSSS"; SimpleDateFormat sdfDir = new SimpleDateFormat(dateTimeFilePattern); epBeanFileName = epBeanFileName.replace("$datetime", sdfDir.format(new java.util.Date())); } else if (epBeanFileName.contains("$date")) { String dateFilePattern = "yyyy-MM-dd"; SimpleDateFormat sdfDir = new SimpleDateFormat(dateFilePattern); epBeanFileName = epBeanFileName.replace("$date", sdfDir.format(new java.util.Date())); // sdfDir.format(new java.util.Date()) // retMe = epBean.getFileLocation() + File.separator + epBean.getExportFileName() + "." + epBean.getPostProcessing().getFileType(); } else { // retMe = epBean.getFileLocation() + File.separator + epBean.getExportFileName() + "." + epBean.getPostProcessing().getFileType(); } return epBeanFileName;// + "." + epBean.getPostProcessing().getFileType();// not really the case - might be text to pdf // return retMe; } private boolean mayProceed(HttpServletRequest request) { StudyUserRoleBean currentRole = (StudyUserRoleBean)request.getSession().getAttribute("userRole"); Role r = currentRole.getRole(); if (r.equals(Role.STUDYDIRECTOR) || r.equals(Role.COORDINATOR) || r.equals(Role.MONITOR) || currentRole.getRole().equals(Role.INVESTIGATOR) ) { return true; } return false; } }