package is.idega.idegaweb.egov.bpm.xform; import is.idega.idegaweb.egov.application.business.ApplicationBusiness; import is.idega.idegaweb.egov.application.data.Application; import is.idega.idegaweb.egov.bpm.cases.presentation.beans.CasesBPMAssetsState; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.logging.Level; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; import com.idega.block.form.data.XFormSubmission; import com.idega.block.form.data.dao.XFormsDAO; import com.idega.block.form.presentation.FormViewer; import com.idega.bpm.data.XFormSubmissionData; import com.idega.chiba.web.xml.xforms.validation.XFormSubmissionValidator; import com.idega.core.business.DefaultSpringBean; import com.idega.core.persistence.Param; import com.idega.jbpm.data.dao.BPMDAO; import com.idega.jbpm.exe.BPMDocument; import com.idega.jbpm.exe.BPMFactory; import com.idega.jbpm.exe.TaskInstanceW; import com.idega.jbpm.presentation.BPMTaskViewer; import com.idega.user.data.User; import com.idega.util.CoreUtil; import com.idega.util.ListUtil; import com.idega.util.StringHandler; import com.idega.util.StringUtil; import com.idega.util.URIUtil; import com.idega.util.expression.ELUtil; @Scope(BeanDefinition.SCOPE_PROTOTYPE) @Service("bpmApplicationXFormHandler") public class XFormHandler extends DefaultSpringBean implements XFormSubmissionValidator { @Autowired private BPMDAO bpmDAO; @Autowired private BPMFactory bpmFactory; @Autowired private XFormsDAO xformsDAO; private XFormsDAO getXFormsDAO() { if (xformsDAO == null) { ELUtil.getInstance().autowire(this); } return xformsDAO; } private BPMFactory getBPMFactory() { if (bpmFactory == null) ELUtil.getInstance().autowire(this); return bpmFactory; } private BPMDAO getBPMDAO() { if (bpmDAO == null) ELUtil.getInstance().autowire(this); return bpmDAO; } private boolean isUserAbleToSubmitTask(User user, TaskInstanceW task) { if (user == null || task == null) return false; List<BPMDocument> tasksForUser = task.getProcessInstanceW().getTaskDocumentsForUser(user, getCurrentLocale(), Boolean.FALSE); if (ListUtil.isEmpty(tasksForUser)) { getLogger().warning("There are no tasks available for the user " + user); return false; } else { boolean foundAvailableTask = false; long tiId = task.getTaskInstanceId(); for (Iterator<BPMDocument> tasksIter = tasksForUser.iterator(); (!foundAvailableTask && tasksIter.hasNext());) { foundAvailableTask = tiId == tasksIter.next().getTaskInstanceId().longValue(); } if (foundAvailableTask) { return true; } else { getLogger().warning("Task with ID " + tiId + " is not available for submitting by the user " + user); return false; } } } @Override public boolean isPossibleToSubmitXForm(String uri) { if (StringUtil.isEmpty(uri)) return true; // Error - can not determine User user = null; try { user = getBPMFactory().getBpmUserFactory().getCurrentBPMUser().getUserToUse(); } catch (Exception e) { getLogger().log(Level.WARNING, "Error resolving BPM user", e); } URIUtil uriUtil = new URIUtil(uri); Map<String, String> params = uriUtil.getParameters(); if (params == null || params.isEmpty()) return true; // Error - can not determine try { Long procDefId = null; if (params.containsKey(BPMTaskViewer.PROCESS_DEFINITION_PROPERTY)) { procDefId = Long.valueOf(params.get(BPMTaskViewer.PROCESS_DEFINITION_PROPERTY)); } else if (params.containsKey(CasesBPMAssetsState.TASK_INSTANCE_ID_PARAMETER)) { Long tiId = Long.valueOf(params.get(CasesBPMAssetsState.TASK_INSTANCE_ID_PARAMETER)); TaskInstanceW task = getBPMFactory().getProcessManagerByTaskInstanceId(tiId).getTaskInstance(tiId); if (user == null) { procDefId = task.getProcessInstanceW().getProcessDefinitionW().getProcessDefinitionId(); } else return isUserAbleToSubmitTask(user, task); } else if (params.containsKey(FormViewer.submissionIdParam)) { String submissionId = params.get(FormViewer.submissionIdParam); if (!StringHandler.isNumeric(submissionId)) { XFormSubmission submission = getXFormsDAO().getSubmissionBySubmissionUUID(submissionId); if (submission != null) { if (submission.getProvider() != null) { procDefId = getXFormsDAO().getSingleResultByInlineQuery( "select sd.processDefinition.id from " + XFormSubmissionData.class.getName() + " sd where sd.id = :provider", Long.class, new Param("provider", submission.getProvider()) ); } else { submissionId = String.valueOf(submission.getSubmissionId()); } } } if (procDefId == null && StringHandler.isNumeric(submissionId)) { procDefId = getXFormsDAO().getSingleResultByInlineQuery( "select sd.processDefinition.id from " + XFormSubmissionData.class.getName() + " sd where sd.submission.submissionId = :submissionId", Long.class, new Param("submissionId", Long.valueOf(submissionId)) ); } } if (procDefId == null) { getLogger().warning("Unable to resolve process definition ID from the parameters: " + params); return true; // Error - can not determine } String appUrl = getBPMDAO().getProcessDefinitionNameByProcessDefinitionId(procDefId); if (StringUtil.isEmpty(appUrl)) { getLogger().warning("App URL can not be resolved from proc. def. ID: " + procDefId); return true; // Error - can not determine } ApplicationBusiness appBusiness = getServiceInstance(ApplicationBusiness.class); Collection<Application> apps = appBusiness.getApplicationHome().findAllByApplicationUrl(appUrl); if (ListUtil.isEmpty(apps)) { getLogger().warning("No applications were found by URL: " + appUrl); return getApplication().getSettings().getBoolean("submit_xform_if_logged_out", Boolean.TRUE); // Be default allowing to submit } for (Application app: apps) { if (app.getRequiresLogin() && user == null) { getLogger().warning("User must be logged in to submit the application: " + app.getNameByLocale(getCurrentLocale())); return false; } } } catch (Exception e) { String message = "Error resolving if xform at '" + uri + "' needs to be invalidated"; CoreUtil.sendExceptionNotification(message, e); getLogger().log(Level.WARNING, message, e); } return true; } }