/*
* OpenClinica is distributed under the
* GNU Lesser General Public License (GNU LGPL).
* For details see: http://www.openclinica.org/license
* copyright 2003-2005 Akaza Research
*/
package org.akaza.openclinica.control.core;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.StringTokenizer;
import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.SingleThreadModel;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.sql.DataSource;
import org.akaza.openclinica.bean.admin.CRFBean;
import org.akaza.openclinica.bean.core.DiscrepancyNoteType;
import org.akaza.openclinica.bean.core.Role;
import org.akaza.openclinica.bean.core.Status;
import org.akaza.openclinica.bean.extract.ArchivedDatasetFileBean;
import org.akaza.openclinica.bean.login.StudyUserRoleBean;
import org.akaza.openclinica.bean.login.UserAccountBean;
import org.akaza.openclinica.bean.managestudy.DiscrepancyNoteBean;
import org.akaza.openclinica.bean.managestudy.EventDefinitionCRFBean;
import org.akaza.openclinica.bean.managestudy.StudyBean;
import org.akaza.openclinica.bean.managestudy.StudyEventBean;
import org.akaza.openclinica.bean.managestudy.StudyEventDefinitionBean;
import org.akaza.openclinica.bean.managestudy.StudyGroupClassBean;
import org.akaza.openclinica.bean.managestudy.StudySubjectBean;
import org.akaza.openclinica.bean.submit.EventCRFBean;
import org.akaza.openclinica.bean.submit.ItemBean;
import org.akaza.openclinica.bean.submit.ItemDataBean;
import org.akaza.openclinica.control.SpringServletAccess;
import org.akaza.openclinica.core.CRFLocker;
import org.akaza.openclinica.core.EmailEngine;
import org.akaza.openclinica.core.SessionManager;
import org.akaza.openclinica.core.form.StringUtil;
import org.akaza.openclinica.dao.admin.CRFDAO;
import org.akaza.openclinica.dao.core.AuditableEntityDAO;
import org.akaza.openclinica.dao.core.CoreResources;
import org.akaza.openclinica.dao.extract.ArchivedDatasetFileDAO;
import org.akaza.openclinica.dao.hibernate.EventDefinitionCrfTagDao;
import org.akaza.openclinica.dao.hibernate.UserAccountDao;
import org.akaza.openclinica.dao.managestudy.StudyDAO;
import org.akaza.openclinica.dao.managestudy.StudyEventDAO;
import org.akaza.openclinica.dao.managestudy.StudyEventDefinitionDAO;
import org.akaza.openclinica.dao.managestudy.StudyGroupClassDAO;
import org.akaza.openclinica.dao.managestudy.StudyGroupDAO;
import org.akaza.openclinica.dao.managestudy.StudySubjectDAO;
import org.akaza.openclinica.dao.service.StudyConfigService;
import org.akaza.openclinica.dao.service.StudyParameterValueDAO;
import org.akaza.openclinica.dao.submit.EventCRFDAO;
import org.akaza.openclinica.dao.submit.ItemDAO;
import org.akaza.openclinica.dao.submit.ItemDataDAO;
import org.akaza.openclinica.domain.datamap.EventDefinitionCrf;
import org.akaza.openclinica.domain.datamap.EventDefinitionCrfTag;
import org.akaza.openclinica.domain.user.UserAccount;
import org.akaza.openclinica.exception.OpenClinicaException;
import org.akaza.openclinica.i18n.core.LocaleResolver;
import org.akaza.openclinica.i18n.util.I18nFormatUtil;
import org.akaza.openclinica.i18n.util.ResourceBundleProvider;
import org.akaza.openclinica.service.pmanage.Authorization;
import org.akaza.openclinica.service.pmanage.ParticipantPortalRegistrar;
import org.akaza.openclinica.view.BreadcrumbTrail;
import org.akaza.openclinica.view.Page;
import org.akaza.openclinica.view.StudyInfoPanel;
import org.akaza.openclinica.view.StudyInfoPanelLine;
import org.akaza.openclinica.web.InconsistentStateException;
import org.akaza.openclinica.web.InsufficientPermissionException;
import org.akaza.openclinica.web.SQLInitServlet;
import org.akaza.openclinica.web.bean.EntityBeanTable;
import org.quartz.JobKey;
import org.apache.commons.lang.StringEscapeUtils;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerKey;
import org.quartz.impl.StdScheduler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.owasp.esapi.ESAPI;
/**
* This class enhances the Controller in several ways.
*
* <ol>
* <li>The method mayProceed, for which the class is named, is declared abstract and is called before processRequest. This
* method indicates whether the user may proceed with the action he wishes to perform (as indicated by various attributes or
* parameters in request or session). Note, howeveer, that the method has a void return, and throws
* InsufficientPermissionException. The intention is that if the user may not proceed with his desired action, the method
* should throw an exception. InsufficientPermissionException will accept a Page object which indicates where the user should
* be redirected in order to be informed that he has insufficient permission, and the process method enforces this redirection
* by catching an InsufficientPermissionException object.
*
* <li>Four new members, session, request, response, and the UserAccountBean object ub have been declared protected, and are
* set in the process method. This allows developers to avoid passing these objects between methods, and moreover it
* accurately encodes the fact that these objects represent the state of the servlet.
*
* <br/>
* In particular, please note that it is no longer necessary to generate a bean for the session manager, the current user or
* the current study.
*
* <li>The method processRequest has been declared abstract. This change is unlikely to affect most code, since by custom
* processRequest is declared in each subclass anyway.
*
* <li>The standard try-catch block within most processRequest methods has been included in the process method, which calls
* the processRequest method. Therefore, subclasses may throw an Exception in the processRequest method without having to
* handle it.
*
* <li>The addPageMessage method has been declared to streamline the process of setting page-level messages. The accompanying
* showPageMessages.jsp file in jsp/include/ automatically displays all of the page messages; the developer need only include
* this file in the jsp.
*
* <li>The addEntityList method makes it easy to add a Collection of EntityBeans to the request. Note that this method should
* only be used for Collections from which one EntityBean must be selected by the user. If the Collection is empty, this
* method will throw an InconsistentStateException, taking the user to an error page and settting a page message indicating
* that the user may not proceed because no entities are present. Note that the error page and the error message must be
* specified.
* </ol>
*
* @author ssachs
*/
public abstract class SecureController extends HttpServlet implements SingleThreadModel {
protected ServletContext context;
protected SessionManager sm;
// protected final Logger logger =
// LoggerFactory.getLogger(getClass().getName());
protected final Logger logger = LoggerFactory.getLogger(getClass().getName());
protected String logDir;
protected String logLevel;
protected HttpSession session;
protected HttpServletRequest request;
protected HttpServletResponse response;
protected UserAccountBean ub;
protected StudyBean currentStudy;
protected StudyUserRoleBean currentRole;
protected HashMap errors = new HashMap();
protected UserAccountDao userDaoDomain;
private static String SCHEDULER = "schedulerFactoryBean";
private StdScheduler scheduler;
/**
* local_df is set to the client locale in each request.
*/
protected SimpleDateFormat local_df = new SimpleDateFormat("MM/dd/yyyy");
public static ResourceBundle resadmin, resaudit, resexception, resformat, respage, resterm, restext, resword, resworkflow;
protected StudyInfoPanel panel = new StudyInfoPanel();
public static final String PAGE_MESSAGE = "pageMessages";// for showing
// page
// wide message
public static final String INPUT_MESSAGES = "formMessages"; // for showing
// input-specific
// messages
public static final String PRESET_VALUES = "presetValues"; // for setting
// preset values
public static final String ADMIN_SERVLET_CODE = "admin";
public static final String BEAN_TABLE = "table";
public static final String STUDY_INFO_PANEL = "panel"; // for setting the
// side panel
public static final String BREADCRUMB_TRAIL = "breadcrumbs";
public static final String POP_UP_URL = "popUpURL";
// public static String DATASET_HOME_DIR = "OpenClinica";
// Use this variable as the key for the support url
public static final String SUPPORT_URL = "supportURL";
public static final String MODULE = "module";// to determine which module
private CRFLocker crfLocker;
// user is in
// for setting the breadcrumb trail
// protected HashMap errors = new HashMap();//error messages on the page
protected void addPageMessage(String message) {
ArrayList pageMessages = (ArrayList) request.getAttribute(PAGE_MESSAGE);
if (pageMessages == null) {
pageMessages = new ArrayList();
}
pageMessages.add(message);
logger.debug(message);
request.setAttribute(PAGE_MESSAGE, pageMessages);
}
protected void resetPanel() {
panel.reset();
}
protected void setToPanel(String title, String info) {
if (panel.isOrderedData()) {
ArrayList data = panel.getUserOrderedData();
data.add(new StudyInfoPanelLine(title, info));
panel.setUserOrderedData(data);
} else {
panel.setData(title, info);
}
request.setAttribute(STUDY_INFO_PANEL, panel);
}
protected void setInputMessages(HashMap messages) {
request.setAttribute(INPUT_MESSAGES, messages);
}
protected void setPresetValues(HashMap presetValues) {
request.setAttribute(PRESET_VALUES, presetValues);
}
protected void setTable(EntityBeanTable table) {
request.setAttribute(BEAN_TABLE, table);
}
@Override
public void init() throws ServletException {
context = getServletContext();
crfLocker = SpringServletAccess.getApplicationContext(context).getBean(CRFLocker.class);
}
/**
* Process request
*
* @throws Exception
*/
protected abstract void processRequest() throws Exception;
protected abstract void mayProceed() throws InsufficientPermissionException;
public static final String USER_BEAN_NAME = "userBean";
public void passwdTimeOut() {
Date lastChangeDate = ub.getPasswdTimestamp();
if (!ub.isLdapUser() && lastChangeDate == null) {
//@pgawade 18-Sep-2012: fix for issue #14506 (https://issuetracker.openclinica.com/view.php?id=14506#c58197)
//addPageMessage(respage.getString("welcome") + " " + ub.getFirstName() + " " + ub.getLastName() + ". " + respage.getString("password_set"));
// + "<a href=\"UpdateProfile\">" + respage.getString("user_profile") + " </a>");
int pwdChangeRequired = new Integer(SQLInitServlet.getField("change_passwd_required")).intValue();
if (pwdChangeRequired == 1) {
addPageMessage(respage.getString("welcome") + " " + ub.getFirstName() + " " + ub.getLastName() + ". " + respage.getString("password_set"));
request.setAttribute("mustChangePass", "yes");
forwardPage(Page.RESET_PASSWORD);
}
}
}
private void pingJobServer(HttpServletRequest request) {
String jobName = (String) request.getSession().getAttribute("jobName");
String groupName = (String) request.getSession().getAttribute("groupName");
Integer datasetId = (Integer) request.getSession().getAttribute("datasetId");
try {
if (jobName != null && groupName != null) {
Trigger.TriggerState triggerState = getScheduler(request).getTriggerState(new TriggerKey(jobName, groupName));
org.quartz.JobDetail details = getScheduler(request).getJobDetail(new JobKey(jobName, groupName));
List contexts = getScheduler(request).getCurrentlyExecutingJobs();
// will we get the above, even if its completed running?
// ProcessingResultType message = null;
// for (int i = 0; i < contexts.size(); i++) {
// org.quartz.JobExecutionContext context = (org.quartz.JobExecutionContext) contexts.get(i);
// if (context.getJobDetail().getName().equals(jobName) &&
// context.getJobDetail().getGroup().equals(groupName)) {
// message = (ProcessingResultType) context.getResult();
// System.out.println("found message " + message.getDescription());
// }
// }
// ProcessingResultType message = (ProcessingResultType) details.getResult();
org.quartz.JobDataMap dataMap = details.getJobDataMap();
String failMessage = dataMap.getString("failMessage");
if (triggerState == Trigger.TriggerState.NONE || triggerState== Trigger.TriggerState.COMPLETE) {
// add the message here that your export is done
// TODO make absolute paths in the message, for example a link from /pages/* would break
// TODO i18n
if (failMessage != null) {
// The extract data job failed with the message:
// ERROR: relation "demographics" already exists
// More information may be available in the log files.
addPageMessage("The extract data job failed with the message: <br/><br/>" + failMessage
+ "<br/><br/>More information may be available in the log files.");
request.getSession().removeAttribute("jobName");
request.getSession().removeAttribute("groupName");
request.getSession().removeAttribute("datasetId");
} else {
String successMsg = dataMap.getString("SUCCESS_MESSAGE");
String success = dataMap.getString("successMsg");
if (success != null ) {
if (successMsg.contains("$linkURL")) {
successMsg = decodeLINKURL(successMsg, datasetId);
}
if(successMsg!=null && !successMsg.isEmpty())
{
addPageMessage(successMsg);
}
else {
addPageMessage("Your Extract is now completed. Please go to review them at <a href='ExportDataset?datasetId="
+ datasetId + "'> Here </a>." );
}
request.getSession().removeAttribute("jobName");
request.getSession().removeAttribute("groupName");
request.getSession().removeAttribute("datasetId");
}
}
} else {
}
}
} catch (SchedulerException se) {
se.printStackTrace();
}
}
private String decodeLINKURL(String successMsg, Integer datasetId) {
ArchivedDatasetFileDAO asdfDAO = new ArchivedDatasetFileDAO(sm.getDataSource());
ArrayList<ArchivedDatasetFileBean> fileBeans = asdfDAO.findByDatasetId(datasetId);
successMsg =
successMsg.replace("$linkURL", "<a href=\"" + CoreResources.getField("sysURL.base") + "AccessFile?fileId=" + fileBeans.get(0).getId()
+ "\">here </a>");
return successMsg;
}
private StdScheduler getScheduler(HttpServletRequest request) {
scheduler =
this.scheduler != null ? scheduler : (StdScheduler) SpringServletAccess.getApplicationContext(request.getSession().getServletContext()).getBean(
SCHEDULER);
return scheduler;
}
private void process(HttpServletRequest request, HttpServletResponse response) throws OpenClinicaException, UnsupportedEncodingException {
request.setCharacterEncoding("UTF-8");
session = request.getSession();
// BWP >> 1/8/2008
try {
// YW 10-03-2007 <<
session.setMaxInactiveInterval(Integer.parseInt(SQLInitServlet.getField("max_inactive_interval")));
// YW >>
} catch (NumberFormatException nfe) {
// BWP>>3600 is the datainfo.properties maxInactiveInterval on
// 1/8/2008
session.setMaxInactiveInterval(3600);
}
// If the session already has a value with key SUPPORT_URL don't reset
if (session.getAttribute(SUPPORT_URL) == null) {
session.setAttribute(SUPPORT_URL, SQLInitServlet.getSupportURL());
}
ub = (UserAccountBean) session.getAttribute(USER_BEAN_NAME);
currentStudy = (StudyBean) session.getAttribute("study");
currentRole = (StudyUserRoleBean) session.getAttribute("userRole");
// Set current language preferences
Locale locale = LocaleResolver.getLocale(request);
ResourceBundleProvider.updateLocale(locale);
resadmin = ResourceBundleProvider.getAdminBundle(locale);
resaudit = ResourceBundleProvider.getAuditEventsBundle(locale);
resexception = ResourceBundleProvider.getExceptionsBundle(locale);
resformat = ResourceBundleProvider.getFormatBundle(locale);
restext = ResourceBundleProvider.getTextsBundle(locale);
resterm = ResourceBundleProvider.getTermsBundle(locale);
resword = ResourceBundleProvider.getWordsBundle(locale);
respage = ResourceBundleProvider.getPageMessagesBundle(locale);
resworkflow = ResourceBundleProvider.getWorkflowBundle(locale);
local_df = I18nFormatUtil.getDateFormat(locale);
try {
String userName = request.getRemoteUser();
// BWP 1/8/08<< the sm variable may already be set with a mock
// object,
// from the perspective of
// JUnit servlets tests
/*
* if(sm==null && (!StringUtil.isBlank(userName))) {//check if user logged in, then create a new sessionmanger to
* get ub //create a new sm in order to get a new ub object sm = new SessionManager(ub, userName); }
*/
// BWP 01/08 >>
// sm = new SessionManager(ub, userName);
sm = new SessionManager(ub, userName, SpringServletAccess.getApplicationContext(context));
ub = sm.getUserBean();
session.setAttribute("userBean", ub);
StudyDAO sdao = new StudyDAO(sm.getDataSource());
if (currentStudy == null || currentStudy.getId() <= 0) {
if (ub.getId() > 0 && ub.getActiveStudyId() > 0) {
StudyParameterValueDAO spvdao = new StudyParameterValueDAO(sm.getDataSource());
currentStudy = (StudyBean) sdao.findByPK(ub.getActiveStudyId());
ArrayList studyParameters = spvdao.findParamConfigByStudy(currentStudy);
currentStudy.setStudyParameters(studyParameters);
StudyConfigService scs = new StudyConfigService(sm.getDataSource());
if (currentStudy.getParentStudyId() <= 0) {// top study
scs.setParametersForStudy(currentStudy);
} else {
// YW <<
currentStudy.setParentStudyName(((StudyBean) sdao.findByPK(currentStudy.getParentStudyId())).getName());
// YW >>
scs.setParametersForSite(currentStudy);
}
// set up the panel here, tbh
panel.reset();
/*
* panel.setData("Study", currentStudy.getName()); panel.setData("Summary", currentStudy.getSummary());
* panel.setData("Start Date", sdf.format(currentStudy.getDatePlannedStart())); panel.setData("End Date",
* sdf.format(currentStudy.getDatePlannedEnd())); panel.setData("Principal Investigator",
* currentStudy.getPrincipalInvestigator());
*/
session.setAttribute(STUDY_INFO_PANEL, panel);
} else {
currentStudy = new StudyBean();
}
session.setAttribute("study", currentStudy);
} else if (currentStudy.getId() > 0) {
// YW 06-20-2007<< set site's parentstudy name when site is
// restored
if (currentStudy.getParentStudyId() > 0) {
currentStudy.setParentStudyName(((StudyBean) sdao.findByPK(currentStudy.getParentStudyId())).getName());
}
// YW >>
}
if (currentStudy.getParentStudyId() > 0) {
/*
* The Role decription will be set depending on whether the user logged in at study lever or site level.
* issue-2422
*/
List roles = Role.toArrayList();
for (Iterator it = roles.iterator(); it.hasNext();) {
Role role = (Role) it.next();
switch (role.getId()) {
case 2:
role.setDescription("site_Study_Coordinator");
break;
case 3:
role.setDescription("site_Study_Director");
break;
case 4:
role.setDescription("site_investigator");
break;
case 5:
role.setDescription("site_Data_Entry_Person");
break;
case 6:
role.setDescription("site_monitor");
break;
case 7:
role.setDescription("site_Data_Entry_Person2");
break;
default:
// logger.info("No role matched when setting role description");
}
}
} else {
/*
* If the current study is a site, we will change the role description. issue-2422
*/
List roles = Role.toArrayList();
for (Iterator it = roles.iterator(); it.hasNext();) {
Role role = (Role) it.next();
switch (role.getId()) {
case 2:
role.setDescription("Study_Coordinator");
break;
case 3:
role.setDescription("Study_Director");
break;
case 4:
role.setDescription("Investigator");
break;
case 5:
role.setDescription("Data_Entry_Person");
break;
case 6:
role.setDescription("Monitor");
break;
default:
// logger.info("No role matched when setting role description");
}
}
}
if (currentRole == null || currentRole.getId() <= 0) {
// if (ub.getId() > 0 && currentStudy.getId() > 0) {
// if current study has been "removed", current role will be
// kept as "invalid" -- YW 06-21-2007
if (ub.getId() > 0 && currentStudy.getId() > 0 && !currentStudy.getStatus().getName().equals("removed")) {
currentRole = ub.getRoleByStudy(currentStudy.getId());
if (currentStudy.getParentStudyId() > 0) {
// Checking if currentStudy has been removed or not will
// ge good enough -- YW 10-17-2007
StudyUserRoleBean roleInParent = ub.getRoleByStudy(currentStudy.getParentStudyId());
// inherited role from parent study, pick the higher
// role
currentRole.setRole(Role.max(currentRole.getRole(), roleInParent.getRole()));
}
// logger.info("currentRole:" + currentRole.getRoleName());
} else {
currentRole = new StudyUserRoleBean();
}
session.setAttribute("userRole", currentRole);
}
// YW << For the case that current role is not "invalid" but current
// active study has been removed.
else if (currentRole.getId() > 0 && (currentStudy.getStatus().equals(Status.DELETED) || currentStudy.getStatus().equals(Status.AUTO_DELETED))) {
currentRole.setRole(Role.INVALID);
currentRole.setStatus(Status.DELETED);
session.setAttribute("userRole", currentRole);
}
// YW 06-19-2007 >>
request.setAttribute("isAdminServlet", getAdminServlet());
this.request = request;
this.response = response;
// java.util.Enumeration en_session = session.getAttributeNames();
// java.util.Enumeration en_request = request.getAttributeNames();
//
// // logging added to find problems with adding subjects, tbh
// 102007
// String ss_names = "session names: ";
// while (en_session.hasMoreElements()) {
// ss_names += " - " + en_session.nextElement();
// }
// logger.info(ss_names);
//
// // also added tbh, 102007
// String rq_names = "request names: ";
// while (en_request.hasMoreElements()) {
// rq_names += " - " + en_request.nextElement();
// }
// logger.info(rq_names);
if (!request.getRequestURI().endsWith("ResetPassword")) {
passwdTimeOut();
}
mayProceed();
pingJobServer(request);
processRequest();
} catch (InconsistentStateException ise) {
ise.printStackTrace();
logger.warn("InconsistentStateException: org.akaza.openclinica.control.SecureController: " + ise.getMessage());
addPageMessage(ise.getOpenClinicaMessage());
forwardPage(ise.getGoTo());
} catch (InsufficientPermissionException ipe) {
ipe.printStackTrace();
logger.warn("InsufficientPermissionException: org.akaza.openclinica.control.SecureController: " + ipe.getMessage());
// addPageMessage(ipe.getOpenClinicaMessage());
forwardPage(ipe.getGoTo());
} catch (OutOfMemoryError ome) {
ome.printStackTrace();
long heapSize = Runtime.getRuntime().totalMemory();
session.setAttribute("ome", "yes");
} catch (Exception e) {
e.printStackTrace();
logger.error(SecureController.getStackTrace(e));
forwardPage(Page.ERROR);
}
}
public static String getStackTrace(Throwable t) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw, true);
t.printStackTrace(pw);
pw.flush();
sw.flush();
return sw.toString();
}
/**
* Handles the HTTP <code>GET</code> method.
*
* @param request
* @param response
* @throws ServletException
* @throws java.io.IOException
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException {
try {
logger.debug("Request");
process(request, response);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Handles the HTTP <code>POST</code> method.
*
* @param request servlet request
* @param response servlet response
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException {
try {
logger.debug("Post");
process(request, response);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* <P>
* Forwards to a jsp page. Additions to the forwardPage() method involve checking the session for the bread crumb trail
* and setting it, if necessary. Setting it here allows the developer to only have to update the
* <code>BreadcrumbTrail</code> class.
*
* @param jspPage The page to go to.
* @param checkTrail The command to check for, and set a trail in the session.
*/
protected void forwardPage(Page jspPage, boolean checkTrail) {
Page page1 = Page.valueOf(jspPage.name());
String temp;
// YW 10-03-2007 <<
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", -1);
response.setHeader("Cache-Control", "no-store");
// YW >>
if (request.getAttribute(POP_UP_URL) == null) {
request.setAttribute(POP_UP_URL, "");
}
try {
// Added 01/19/2005 for breadcrumbs, tbh
if (checkTrail) {
BreadcrumbTrail bt = new BreadcrumbTrail();
if (session != null) {// added bu jxu, fixed bug for log out
/* ArrayList trail = (ArrayList) session.getAttribute("trail");
if (trail == null) {
trail = bt.generateTrail(jspPage, request);
} else {
bt.setTrail(trail);
trail = bt.generateTrail(jspPage, request);
}
session.setAttribute("trail", trail);*/
panel = (StudyInfoPanel) session.getAttribute(STUDY_INFO_PANEL);
if (panel == null) {
panel = new StudyInfoPanel();
panel.setData(jspPage, session, request);
} else {
panel.setData(jspPage, session, request);
}
session.setAttribute(STUDY_INFO_PANEL, panel);
}
// we are also using checkTrail to update the panel, tbh
// 01/31/2005
}
temp = page1.getFileName();
// above added 01/19/2005, tbh
context.getRequestDispatcher(temp).forward(request, response);
} catch (Exception se) {
/* if ("View Notes".equals(jspPage.getTitle())) {
String viewNotesURL = jspPage.getFileName();
if (viewNotesURL != null && viewNotesURL.contains("listNotes_p_=")) {
String[] ps = viewNotesURL.split("listNotes_p_=");
String t = ps[1].split("&")[0];
int p = t.length() > 0 ? Integer.valueOf(t).intValue() : -1;
if (p > 1) {
viewNotesURL = viewNotesURL.replace("listNotes_p_=" + p, "listNotes_p_=" + (p - 1));
//forwardPage(Page.setNewPage(viewNotesURL, "View Notes"));
try {
getServletContext().getRequestDispatcher(viewNotesURL).forward(request, response);
} catch (ServletException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else if (p <= 0) {
forwardPage(Page.VIEW_DISCREPANCY_NOTES_IN_STUDY);
}
}
}
*/ logger.error(se.getMessage(),se);
}
finally {
page1 = null;
jspPage = null;
temp= null;
}
}
protected void forwardPage(Page jspPage) {
this.forwardPage(jspPage, true);
}
/**
* This method supports functionality of the type
* "if a list of entities is empty, then jump to some page and display an error message." This prevents users from seeing
* empty drop-down lists and being given error messages when they can't choose an entity from the drop-down list. Use,
* e.g.:
* <code>addEntityList("groups", allGroups, "There are no groups to display, so you cannot add a subject to this Study.",
* Page.SUBMIT_DATA)</code>
*
* @param beanName The name of the entity list as it should be stored in the request object.
* @param list The Collection of entities.
* @param messageIfEmpty The message to display if the collection is empty.
* @param destinationIfEmpty The Page to go to if the collection is empty.
* @throws InconsistentStateException
*/
protected void addEntityList(String beanName, Collection list, String messageIfEmpty, Page destinationIfEmpty) throws InconsistentStateException {
if (list.isEmpty()) {
throw new InconsistentStateException(destinationIfEmpty, messageIfEmpty);
}
request.setAttribute(beanName, list);
}
/**
* @return A blank String if this servlet is not an Administer System servlet. SecureController.ADMIN_SERVLET_CODE
* otherwise.
*/
protected String getAdminServlet() {
return "";
}
protected void setPopUpURL(String url) {
if (url != null && request != null) {
request.setAttribute(POP_UP_URL, url);
request.setAttribute("hasPopUp", 1);
logger.info("just set pop up url: " + url);
}
}
/**
* <p>Check if an entity with passed entity id is included in studies of current user.</p>
*
* <p>Note: This method called AuditableEntityDAO.findByPKAndStudy which required
* "The subclass must define findByPKAndStudyName before calling this
* method. Otherwise an inactive AuditableEntityBean will be returned."</p>
* @author ywang 10-18-2007
* @param entityId int
* @param userName String
* @param adao AuditableEntityDAO
* @param ds javax.sql.DataSource
*/
protected boolean entityIncluded(int entityId, String userName, AuditableEntityDAO adao, DataSource ds) {
StudyDAO sdao = new StudyDAO(ds);
ArrayList<StudyBean> studies = (ArrayList<StudyBean>) sdao.findAllByUserNotRemoved(userName);
for (int i = 0; i < studies.size(); ++i) {
if (adao.findByPKAndStudy(entityId, studies.get(i)).getId() > 0) {
return true;
}
// Here follow the current logic - study subjects at sites level are
// visible to parent studies.
if (studies.get(i).getParentStudyId() <= 0) {
ArrayList<StudyBean> sites = (ArrayList<StudyBean>) sdao.findAllByParent(studies.get(i).getId());
if (sites.size() > 0) {
for (int j = 0; j < sites.size(); ++j) {
if (adao.findByPKAndStudy(entityId, sites.get(j)).getId() > 0) {
return true;
}
}
}
}
}
return false;
}
public String getRequestURLMinusServletPath() {
String requestURLMinusServletPath = request.getRequestURL().toString().replaceAll(request.getServletPath(), "");
return requestURLMinusServletPath;
}
public String getHostPath() {
String requestURLMinusServletPath = getRequestURLMinusServletPath();
return requestURLMinusServletPath.substring(0, requestURLMinusServletPath.lastIndexOf("/"));
}
public String getContextPath() {
String contextPath = request.getContextPath().replaceAll("/", "");
return contextPath;
}
/*
* To check if the current study is LOCKED
*/
public void checkStudyLocked(Page page, String message) {
if (currentStudy.getStatus().equals(Status.LOCKED)) {
addPageMessage(message);
forwardPage(page);
}
}
public void checkStudyLocked(String url, String message) {
try {
if (currentStudy.getStatus().equals(Status.LOCKED)) {
addPageMessage(message);
response.sendRedirect(url);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
/*
* To check if the current study is FROZEN
*/
public void checkStudyFrozen(Page page, String message) {
if (currentStudy.getStatus().equals(Status.FROZEN)) {
addPageMessage(message);
forwardPage(page);
}
}
public void checkStudyFrozen(String url, String message) {
try {
if (currentStudy.getStatus().equals(Status.FROZEN)) {
addPageMessage(message);
response.sendRedirect(url);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
public ArrayList getEventDefinitionsByCurrentStudy() {
StudyDAO studyDAO = new StudyDAO(sm.getDataSource());
StudyEventDefinitionDAO studyEventDefinitionDAO = new StudyEventDefinitionDAO(sm.getDataSource());
int parentStudyId = currentStudy.getParentStudyId();
ArrayList allDefs = new ArrayList();
if (parentStudyId > 0) {
StudyBean parentStudy = (StudyBean) studyDAO.findByPK(parentStudyId);
allDefs = studyEventDefinitionDAO.findAllActiveByStudy(parentStudy);
} else {
parentStudyId = currentStudy.getId();
allDefs = studyEventDefinitionDAO.findAllActiveByStudy(currentStudy);
}
return allDefs;
}
public ArrayList getStudyGroupClassesByCurrentStudy() {
StudyDAO studyDAO = new StudyDAO(sm.getDataSource());
StudyGroupClassDAO studyGroupClassDAO = new StudyGroupClassDAO(sm.getDataSource());
StudyGroupDAO studyGroupDAO = new StudyGroupDAO(sm.getDataSource());
int parentStudyId = currentStudy.getParentStudyId();
ArrayList studyGroupClasses = new ArrayList();
if (parentStudyId > 0) {
StudyBean parentStudy = (StudyBean) studyDAO.findByPK(parentStudyId);
studyGroupClasses = studyGroupClassDAO.findAllActiveByStudy(parentStudy);
} else {
parentStudyId = currentStudy.getId();
studyGroupClasses = studyGroupClassDAO.findAllActiveByStudy(currentStudy);
}
for (int i = 0; i < studyGroupClasses.size(); i++) {
StudyGroupClassBean sgc = (StudyGroupClassBean) studyGroupClasses.get(i);
ArrayList groups = studyGroupDAO.findAllByGroupClass(sgc);
sgc.setStudyGroups(groups);
}
return studyGroupClasses;
}
protected UserDetails getUserDetails() {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof UserDetails) {
return (UserDetails) principal;
} else {
return null;
}
}
public Boolean sendEmail(String to, String subject, String body, Boolean htmlEmail, Boolean sendMessage) throws Exception {
return sendEmail(to, EmailEngine.getAdminEmail(), subject, body, htmlEmail, respage.getString("your_message_sent_succesfully"),
respage.getString("mail_cannot_be_sent_to_admin"), sendMessage);
}
public Boolean sendEmail(String to, String subject, String body, Boolean htmlEmail) throws Exception {
return sendEmail(to, EmailEngine.getAdminEmail(), subject, body, htmlEmail, respage.getString("your_message_sent_succesfully"),
respage.getString("mail_cannot_be_sent_to_admin"), true);
}
public Boolean sendEmail(String to, String from, String subject, String body, Boolean htmlEmail) throws Exception {
return sendEmail(to, from, subject, body, htmlEmail, respage.getString("your_message_sent_succesfully"),
respage.getString("mail_cannot_be_sent_to_admin"), true);
}
public Boolean sendEmail(String to, String from, String subject, String body, Boolean htmlEmail, String successMessage, String failMessage,
Boolean sendMessage) throws Exception {
Boolean messageSent = true;
try {
JavaMailSenderImpl mailSender = (JavaMailSenderImpl) SpringServletAccess.getApplicationContext(context).getBean("mailSender");
//@pgawade 09-Feb-2012 #issue 13201 - setting the "mail.smtp.localhost" property to localhost when java API is not able to
//retrieve the host name
Properties javaMailProperties = mailSender.getJavaMailProperties();
if(null != javaMailProperties){
if (javaMailProperties.get("mail.smtp.localhost") == null || ((String)javaMailProperties.get("mail.smtp.localhost")).equalsIgnoreCase("") ){
javaMailProperties.put("mail.smtp.localhost", "localhost");
}
}
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, htmlEmail);
helper.setFrom(from);
helper.setTo(processMultipleImailAddresses(to.trim()));
helper.setSubject(subject);
helper.setText(body, true);
mailSender.send(mimeMessage);
if (successMessage != null && sendMessage) {
addPageMessage(successMessage);
}
logger.debug("Email sent successfully on {}", new Date());
} catch (MailException me) {
me.printStackTrace();
if (failMessage != null && sendMessage) {
addPageMessage(failMessage);
}
logger.debug("Email could not be sent on {} due to: {}", new Date(), me.toString());
messageSent = false;
}
return messageSent;
}
private InternetAddress[] processMultipleImailAddresses(String to) throws MessagingException {
ArrayList<String> recipientsArray = new ArrayList<String>();
StringTokenizer st = new StringTokenizer(to, ",");
while (st.hasMoreTokens()) {
recipientsArray.add(st.nextToken());
}
int sizeTo = recipientsArray.size();
InternetAddress[] addressTo = new InternetAddress[sizeTo];
for (int i = 0; i < sizeTo; i++) {
addressTo[i] = new InternetAddress(recipientsArray.get(i).toString());
}
return addressTo;
}
public void dowloadFile(File f, String contentType) throws Exception {
response.setHeader("Content-disposition", "attachment; filename=\"" + f.getName() + "\";");
response.setContentType("text/xml");
response.setHeader("Pragma", "public");
ServletOutputStream op = response.getOutputStream();
DataInputStream in = null;
try {
response.setContentType("text/xml");
response.setHeader("Pragma", "public");
response.setContentLength((int) f.length());
byte[] bbuf = new byte[(int) f.length()];
in = new DataInputStream(new FileInputStream(f));
int length;
while (in != null && (length = in.read(bbuf)) != -1) {
op.write(bbuf, 0, length);
}
in.close();
op.flush();
op.close();
} catch (Exception ee) {
ee.printStackTrace();
} finally {
if (in != null) {
in.close();
}
if (op != null) {
op.close();
}
}
}
public String getPageServletFileName() {
String fileName = request.getServletPath();
String temp = request.getPathInfo();
if (temp != null) {
fileName += temp;
}
temp = request.getQueryString();
if (temp != null && temp.length() > 0) {
fileName += "?" + temp;
}
return fileName;
}
public String getPageURL() {
String url = request.getRequestURL().toString();
String query = request.getQueryString();
if (url != null && url.length() > 0 && query != null) {
url += "?" + query;
}
return url;
}
public DiscrepancyNoteBean getNoteInfo(DiscrepancyNoteBean note) {
StudySubjectDAO ssdao = new StudySubjectDAO(sm.getDataSource());
if ("itemData".equalsIgnoreCase(note.getEntityType())) {
int itemDataId = note.getEntityId();
ItemDataDAO iddao = new ItemDataDAO(sm.getDataSource());
ItemDataBean itemData = (ItemDataBean) iddao.findByPK(itemDataId);
ItemDAO idao = new ItemDAO(sm.getDataSource());
if (StringUtil.isBlank(note.getEntityName())) {
ItemBean item = (ItemBean) idao.findByPK(itemData.getItemId());
note.setEntityName(item.getName());
request.setAttribute("item", item);
}
EventCRFDAO ecdao = new EventCRFDAO(sm.getDataSource());
StudyEventDAO svdao = new StudyEventDAO(sm.getDataSource());
EventCRFBean ec = (EventCRFBean) ecdao.findByPK(itemData.getEventCRFId());
StudyEventBean event = (StudyEventBean) svdao.findByPK(ec.getStudyEventId());
StudyEventDefinitionDAO seddao = new StudyEventDefinitionDAO(sm.getDataSource());
StudyEventDefinitionBean sed = (StudyEventDefinitionBean) seddao.findByPK(event.getStudyEventDefinitionId());
note.setEventName(sed.getName());
note.setEventStart(event.getDateStarted());
CRFDAO cdao = new CRFDAO(sm.getDataSource());
CRFBean crf = cdao.findByVersionId(ec.getCRFVersionId());
note.setCrfName(crf.getName());
note.setEventCRFId(ec.getId());
if (StringUtil.isBlank(note.getSubjectName())) {
StudySubjectBean ss = (StudySubjectBean) ssdao.findByPK(ec.getStudySubjectId());
note.setSubjectName(ss.getName());
}
if (note.getDiscrepancyNoteTypeId() == 0) {
note.setDiscrepancyNoteTypeId(DiscrepancyNoteType.FAILEDVAL.getId());// default
// value
}
} else if ("eventCrf".equalsIgnoreCase(note.getEntityType())) {
int eventCRFId = note.getEntityId();
EventCRFDAO ecdao = new EventCRFDAO(sm.getDataSource());
StudyEventDAO svdao = new StudyEventDAO(sm.getDataSource());
EventCRFBean ec = (EventCRFBean) ecdao.findByPK(eventCRFId);
StudyEventBean event = (StudyEventBean) svdao.findByPK(ec.getStudyEventId());
StudyEventDefinitionDAO seddao = new StudyEventDefinitionDAO(sm.getDataSource());
StudyEventDefinitionBean sed = (StudyEventDefinitionBean) seddao.findByPK(event.getStudyEventDefinitionId());
note.setEventName(sed.getName());
note.setEventStart(event.getDateStarted());
CRFDAO cdao = new CRFDAO(sm.getDataSource());
CRFBean crf = cdao.findByVersionId(ec.getCRFVersionId());
note.setCrfName(crf.getName());
StudySubjectBean ss = (StudySubjectBean) ssdao.findByPK(ec.getStudySubjectId());
note.setSubjectName(ss.getName());
note.setEventCRFId(ec.getId());
} else if ("studyEvent".equalsIgnoreCase(note.getEntityType())) {
int eventId = note.getEntityId();
StudyEventDAO svdao = new StudyEventDAO(sm.getDataSource());
StudyEventBean event = (StudyEventBean) svdao.findByPK(eventId);
StudyEventDefinitionDAO seddao = new StudyEventDefinitionDAO(sm.getDataSource());
StudyEventDefinitionBean sed = (StudyEventDefinitionBean) seddao.findByPK(event.getStudyEventDefinitionId());
note.setEventName(sed.getName());
note.setEventStart(event.getDateStarted());
StudySubjectBean ss = (StudySubjectBean) ssdao.findByPK(event.getStudySubjectId());
note.setSubjectName(ss.getName());
} else if ("studySub".equalsIgnoreCase(note.getEntityType())) {
int studySubjectId = note.getEntityId();
StudySubjectBean ss = (StudySubjectBean) ssdao.findByPK(studySubjectId);
note.setSubjectName(ss.getName());
} else if ("Subject".equalsIgnoreCase(note.getEntityType())) {
int subjectId = note.getEntityId();
StudySubjectBean ss = ssdao.findBySubjectIdAndStudy(subjectId, currentStudy);
note.setSubjectName(ss.getName());
}
return note;
}
public void checkRoleByUserAndStudy(UserAccountBean ub, int studyId, int siteId){
StudyUserRoleBean studyUserRole = ub.getRoleByStudy(studyId);
StudyUserRoleBean siteUserRole = new StudyUserRoleBean();
if (siteId != 0) {
siteUserRole = ub.getRoleByStudy(siteId);
}
if(studyUserRole.getRole().equals(Role.INVALID) && siteUserRole.getRole().equals(Role.INVALID)){
addPageMessage(respage.getString("no_have_correct_privilege_current_study")
+ " " + respage.getString("change_active_study_or_contact"));
forwardPage(Page.MENU_SERVLET);
return;
}
}
protected void baseUrl() throws MalformedURLException{
String portalURL = CoreResources.getField("portalURL");
URL pManageUrl = new URL(portalURL);
ParticipantPortalRegistrar registrar = new ParticipantPortalRegistrar();
Authorization pManageAuthorization = registrar.getAuthorization(currentStudy.getOid());
String url="";
if (pManageAuthorization!=null)
url = pManageUrl.getProtocol() + "://" + pManageAuthorization.getStudy().getHost() + "." + pManageUrl.getHost()
+ ((pManageUrl.getPort() > 0) ? ":" + String.valueOf(pManageUrl.getPort()) : "");
System.out.println("the url : "+ url);
request.setAttribute("participantUrl",url+"/");
}
protected String encodeForHtml(String input) {
return ESAPI.encoder().encodeForHTML(input);
}
protected String decodeForHtml(String input) {
return StringEscapeUtils.unescapeHtml(input);
}
/**
* A inner class designed to allow the implementation of a JUnit test case for abstract SecureController. The inner class
* allows the test case to call the outer class' private process() method.
*
* @author Bruce W. Perry 01/2008
* @see org.akaza.openclinica.servlettests.SecureControllerServletTest
* @see org.akaza.openclinica.servlettests.SecureControllerWrapper
*/
public class SecureControllerTestDelegate {
public SecureControllerTestDelegate() {
super();
}
public void process(HttpServletRequest request, HttpServletResponse response) throws OpenClinicaException, UnsupportedEncodingException {
SecureController.this.process(request, response);
}
}
public CRFLocker getCrfLocker() {
return crfLocker;
}
}