package is.idega.idegaweb.egov.bpm.cases.presentation.beans; import is.idega.idegaweb.egov.application.business.ApplicationBusiness; import is.idega.idegaweb.egov.application.business.ApplicationType; import is.idega.idegaweb.egov.application.data.Application; import is.idega.idegaweb.egov.bpm.IWBundleStarter; import is.idega.idegaweb.egov.bpm.cases.CasesBPMProcessView; import is.idega.idegaweb.egov.bpm.cases.actionhandlers.CaseHandlerAssignmentHandler; import is.idega.idegaweb.egov.bpm.cases.exe.CasesBPMProcessDefinitionW; import is.idega.idegaweb.egov.bpm.cases.presentation.UIProcessVariables; import is.idega.idegaweb.egov.bpm.cases.search.CasesListSearchCriteriaBean; import is.idega.idegaweb.egov.bpm.cases.search.CasesListSearchFilter; import is.idega.idegaweb.egov.bpm.cases.search.impl.DefaultCasesListSearchFilter; import is.idega.idegaweb.egov.bpm.media.CasesSearchResultsExporter; import is.idega.idegaweb.egov.cases.bean.CasesExportParams; import is.idega.idegaweb.egov.cases.business.CasesBusiness; import is.idega.idegaweb.egov.cases.presentation.ClosedCases; import is.idega.idegaweb.egov.cases.presentation.MyCases; import is.idega.idegaweb.egov.cases.presentation.OpenCases; import is.idega.idegaweb.egov.cases.presentation.PublicCases; import is.idega.idegaweb.egov.cases.util.CasesConstants; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javax.ejb.FinderException; import javax.faces.component.UIComponent; import javax.servlet.ServletContext; import org.jdom.Document; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import com.idega.block.process.business.CaseBusiness; import com.idega.block.process.business.CaseManagersProvider; import com.idega.block.process.business.CasesRetrievalManager; import com.idega.block.process.business.ProcessConstants; import com.idega.block.process.business.file.CaseAttachment; import com.idega.block.process.business.pdf.CaseConverterToPDF; import com.idega.block.process.business.pdf.CasePDF; import com.idega.block.process.data.Case; import com.idega.block.process.data.CaseStatus; import com.idega.block.process.event.CaseModifiedEvent; import com.idega.block.process.presentation.CaseBlock; import com.idega.block.process.presentation.UICasesList; import com.idega.block.process.presentation.UserCases; import com.idega.block.process.presentation.beans.CaseListPropertiesBean; import com.idega.block.process.presentation.beans.CasePresentation; import com.idega.block.process.presentation.beans.CasePresentationComparator; import com.idega.block.process.presentation.beans.CasesSearchCriteriaBean; import com.idega.block.process.presentation.beans.CasesSearchResults; import com.idega.block.process.presentation.beans.CasesSearchResultsHolder; import com.idega.block.process.presentation.beans.GeneralCasesListBuilder; import com.idega.block.web2.business.JQuery; import com.idega.block.web2.business.Web2Business; import com.idega.bpm.bean.CasesBPMAssetProperties; import com.idega.builder.bean.AdvancedProperty; import com.idega.builder.business.AdvancedPropertyComparator; import com.idega.builder.business.BuilderLogic; import com.idega.builder.business.BuilderLogicWrapper; import com.idega.business.IBOLookup; import com.idega.business.IBOLookupException; import com.idega.core.accesscontrol.bean.UserHasLoggedInEvent; import com.idega.core.builder.data.ICPage; import com.idega.core.business.DefaultSpringBean; import com.idega.core.component.bean.RenderedComponent; import com.idega.core.component.business.ICObjectBusiness; import com.idega.core.component.data.ICObjectInstance; import com.idega.core.component.data.ICObjectInstanceHome; import com.idega.data.IDOLookup; import com.idega.data.IDOLookupException; import com.idega.idegaweb.IWApplicationContext; import com.idega.idegaweb.IWMainApplication; import com.idega.idegaweb.IWMainSlideStartedEvent; import com.idega.idegaweb.IWResourceBundle; import com.idega.idegaweb.egov.bpm.data.CaseProcInstBind; import com.idega.idegaweb.egov.bpm.data.dao.CasesBPMDAO; import com.idega.idegaweb.egov.bpm.presentation.CasesExporter; import com.idega.io.DownloadWriter; import com.idega.io.MediaWritable; import com.idega.jbpm.bean.BPMProcessVariable; import com.idega.jbpm.bean.VariableInstanceType; import com.idega.jbpm.exe.ProcessDefinitionW; import com.idega.jbpm.utils.JBPMConstants; import com.idega.jbpm.variables.MultipleSelectionVariablesResolver; import com.idega.presentation.IWContext; import com.idega.presentation.ListNavigator; import com.idega.presentation.paging.PagedDataCollection; import com.idega.presentation.ui.handlers.IWDatePickerHandler; import com.idega.user.business.GroupBusiness; import com.idega.user.business.UserBusiness; import com.idega.user.data.Group; import com.idega.user.data.User; import com.idega.util.ArrayUtil; import com.idega.util.CoreConstants; import com.idega.util.CoreUtil; import com.idega.util.FileUtil; import com.idega.util.IWTimestamp; import com.idega.util.ListUtil; import com.idega.util.StringUtil; import com.idega.util.URIUtil; import com.idega.util.expression.ELUtil; import com.idega.webface.WFUtil; @Scope(BeanDefinition.SCOPE_SINGLETON) @Service("casesEngineDWR") public class CasesEngineImp extends DefaultSpringBean implements BPMCasesEngine, ApplicationListener { @Autowired private CasesBPMProcessView casesBPMProcessView; @Autowired private BuilderLogicWrapper builderLogic; @Autowired private GeneralCasesListBuilder casesListBuilder; private CasesRetrievalManager casesRetrievalManager; @Autowired private CaseManagersProvider caseManagersProvider; @Autowired private Web2Business web2; @Autowired private JQuery jQuery; @Autowired private CasesBPMDAO casesBPMDAO; @Autowired private CaseConverterToPDF caseConverter; public static final String FILE_DOWNLOAD_LINK_STYLE_CLASS = "casesBPMAttachmentDownloader", PDF_GENERATOR_AND_DOWNLOAD_LINK_STYLE_CLASS = "casesBPMPDFGeneratorAndDownloader", DOWNLOAD_TASK_IN_PDF_LINK_STYLE_CLASS = "casesBPMDownloadTaskInPDF", CASE_LOGS_PDF_DOWNLOAD_LINK_STYLE_CLASS = "caselogspdfdownload"; private static final Logger LOGGER = Logger.getLogger(CasesEngineImp.class.getName()); protected CasesRetrievalManager getCasesRetrievalManager() { if (this.casesRetrievalManager == null) { this.casesRetrievalManager = getCaseManagersProvider().getCaseManager(); } return this.casesRetrievalManager; } @Override public Long getProcessInstanceId(String caseId) { if (caseId == null) { LOGGER.warning("Case ID is not provided!"); return null; } Long processInstanceId = getCasesBPMProcessView().getProcessInstanceId(caseId); return processInstanceId; } @Override public Document getCaseManagerView(CasesBPMAssetProperties properties) { if (properties == null) { return null; } IWContext iwc = CoreUtil.getIWContext(); if (iwc == null) { return null; } String caseIdStr = properties.getCaseId(); if (caseIdStr == null || CoreConstants.EMPTY.equals(caseIdStr) || iwc == null) { LOGGER.log(Level.WARNING, "Either not provided:\n caseId="+caseIdStr+", iwc="+iwc); return null; } try { CasesBPMAssetsState stateBean = WFUtil.getBeanInstance(CasesBPMAssetsState.beanIdentifier); if (stateBean != null) { stateBean.setUsePDFDownloadColumn(properties.isUsePDFDownloadColumn()); stateBean.setAllowPDFSigning(properties.isAllowPDFSigning()); stateBean.setHideEmptySection(properties.isHideEmptySection()); stateBean.setCommentsPersistenceManagerIdentifier(properties.getCommentsPersistenceManagerIdentifier()); stateBean.setShowAttachmentStatistics(properties.isShowAttachmentStatistics()); stateBean.setShowOnlyCreatorInContacts(properties.isShowOnlyCreatorInContacts()); stateBean.setAutoShowComments(properties.isAutoShowComments()); stateBean.setShowLogExportButton(properties.isShowLogExportButton()); stateBean.setShowComments(properties.isShowComments()); stateBean.setShowContacts(properties.isShowContacts()); stateBean.setSpecialBackPage(properties.getSpecialBackPage()); stateBean.setNameFromExternalEntity(properties.isNameFromExternalEntity()); stateBean.setShowUserProfilePicture(properties.isShowUserProfilePicture()); stateBean.setAddExportContacts(properties.isAddExportContacts()); stateBean.setShowUserCompany(properties.isShowUserCompany()); stateBean.setShowLastLoginDate(properties.isShowLastLoginDate()); } Integer caseId = new Integer(caseIdStr); UIComponent caseAssets = getCasesBPMProcessView().getCaseManagerView(iwc, null, caseId, properties.getProcessorType()); Document rendered = getBuilderLogic().getBuilderService(iwc).getRenderedComponent(iwc, caseAssets, true); return rendered; } catch (Exception e) { LOGGER.log(Level.SEVERE, "Exception while resolving rendered component for case assets view", e); } return null; } @Override public boolean setCaseSubject(String caseId, String subject) { if (caseId == null || subject == null) { return false; } CaseBusiness caseBusiness = null; try { caseBusiness = IBOLookup.getServiceInstance(IWMainApplication.getDefaultIWApplicationContext(), CaseBusiness.class); } catch (IBOLookupException e) { LOGGER.log(Level.SEVERE, "Error getting CaseBusiness", e); } if (caseBusiness == null) { return false; } Case theCase = null; try { theCase = caseBusiness.getCase(caseId); } catch (Exception e) { LOGGER.log(Level.SEVERE, "Unable to get case by ID: " + caseId, e); } if (theCase == null) { return false; } theCase.setSubject(subject); theCase.store(); return true; } @Override public Document getRenderedCasesByQuery(CasesSearchCriteriaBean criterias) { if (criterias instanceof CasesListSearchCriteriaBean) return getCasesListByUserQuery((CasesListSearchCriteriaBean) criterias); getLogger().warning("Criterias " + criterias + " are not instance of " + CasesListSearchCriteriaBean.class + " (actual implementation: " + criterias.getClass().getName() + "), returning null"); return null; } @Override public Document getCasesListByUserQuery(CasesListSearchCriteriaBean criterias) { if (criterias == null) { LOGGER.log(Level.SEVERE, "Can not execute search - search criterias unknown"); return null; } if (criterias.isClearResults()) // Clearing search result before new search clearSearchResults(criterias.getId()); List<Long> piIds = criterias.getProcInstIds(); LOGGER.log(Level.INFO, new StringBuilder("Search query: caseNumber: ").append(criterias.getCaseNumber()).append(", description: ") .append(criterias.getDescription()).append(", name: ").append(criterias.getName()).append(", personalId: ") .append(criterias.getPersonalId()).append(", processId: ").append(criterias.getProcessId()).append(", statusId: ") .append(criterias.getStatusId()).append(", dateRange: ").append(criterias.getDateRange()).append(", casesListType: ") .append(criterias.getCaseListType()).append(", contact: ").append(criterias.getContact()).append(", variables provided: ") .append(ListUtil.isEmpty(criterias.getProcessVariables()) ? "none" : criterias.getProcessVariables()) .append(", process instance IDs: ").append(ListUtil.isEmpty(piIds) ? "none" : piIds.size() >= 1000 ? new ArrayList<Long>(piIds).subList(0, 999) + " ..." : piIds) .toString()); IWContext iwc = CoreUtil.getIWContext(); if (iwc == null) { LOGGER.warning(IWContext.class + " is unavailable!"); return null; } addSearchQueryToSession(iwc, criterias); if (criterias.isNothingFound()) return null; PagedDataCollection<CasePresentation> cases = getCasesByQuery(iwc, criterias); if (criterias.isClearResults()) { if (cases == null) { Collection<CasePresentation> externalData = getExternalSearchResults(getSearchResultsHolder(), criterias.getId()); if (externalData != null) setSearchResults(iwc, externalData, criterias); } else setSearchResults(iwc, cases.getCollection(), criterias); } CaseListPropertiesBean properties = new CaseListPropertiesBean(); properties.setType(ProcessConstants.CASE_LIST_TYPE_SEARCH_RESULTS); properties.setUsePDFDownloadColumn(criterias.isUsePDFDownloadColumn()); properties.setAllowPDFSigning(criterias.isAllowPDFSigning()); properties.setShowStatistics(criterias.isShowStatistics()); properties.setHideEmptySection(criterias.isHideEmptySection()); properties.setPageSize(criterias.getPageSize()); properties.setPage(criterias.getPage()); properties.setInstanceId(criterias.getInstanceId()); properties.setShowCaseNumberColumn(criterias.isShowCaseNumberColumn()); properties.setShowCreationTimeInDateColumn(criterias.isShowCreationTimeInDateColumn()); properties.setCaseCodes(criterias.getCaseCodesInList()); properties.setStatusesToShow(criterias.getStatusesToShowInList()); properties.setStatusesToHide(criterias.getStatusesToHideInList()); properties.setOnlySubscribedCases(criterias.isOnlySubscribedCases()); properties.setComponentId(criterias.getComponentId()); properties.setCriteriasId(criterias.getCriteriasId()); properties.setFoundResults(criterias.getFoundResults()); properties.setCasesListCustomizer(criterias.getCasesListCustomizer()); properties.setCustomColumns(criterias.getCustomColumns()); properties.setShowLoadingMessage(criterias.isShowLoadingMessage()); properties.setSubscribersGroupId(criterias.getSubscribersGroupId()); properties.setShowUserProfilePicture(criterias.isShowUserProfilePicture()); properties.setShowAttachmentStatistics(criterias.isShowAttachmentStatistics()); properties.setShowUserCompany(criterias.isShowUserCompany()); properties.setAddExportContacts(criterias.isAddExportContacts()); UIComponent component = null; if (CasesRetrievalManager.CASE_LIST_TYPE_USER.equals(criterias.getCaseListType())) { properties.setAddCredentialsToExernalUrls(false); component = getCasesListBuilder().getUserCasesList(iwc, cases, null, properties); } else { properties.setShowCheckBoxes(false); component = getCasesListBuilder().getCasesList(iwc, cases, properties); } if (component == null) { LOGGER.warning("Unable to get UIComponent for cases list!"); return null; } return getBuilderLogic().getBuilderService(iwc).getRenderedComponent(iwc, component, true); } private IWResourceBundle getResourceBundle(IWContext iwc) { return iwc.getIWMainApplication().getBundle(IWBundleStarter.IW_BUNDLE_IDENTIFIER).getResourceBundle(iwc); } protected String getSelectedGroup(Long id) { if (id == null) { return null; } try { Group group = IDOLookup.findByPrimaryKey( Group.class, id.intValue()); if (group != null) { return group.getName(); } } catch (IDOLookupException e) { getLogger().log( Level.WARNING, "Failed to get data access object, casue of: ", e); } catch (FinderException e) { getLogger().log( Level.WARNING, "Failed to find group by id: " + id, e); } return null; } private void addSearchQueryToSession(IWContext iwc, CasesListSearchCriteriaBean criterias) { List<AdvancedProperty> searchFields = new ArrayList<AdvancedProperty>(); Locale locale = iwc.getCurrentLocale(); IWResourceBundle iwrb = getResourceBundle(iwc); if (!StringUtil.isEmpty(criterias.getCaseNumber())) { searchFields.add(new AdvancedProperty("case_nr", criterias.getCaseNumber())); } if (!StringUtil.isEmpty(criterias.getDescription())) { searchFields.add(new AdvancedProperty("description", criterias.getDescription())); } if (!StringUtil.isEmpty(criterias.getName())) { searchFields.add(new AdvancedProperty("name", criterias.getName())); } if (!StringUtil.isEmpty(criterias.getPersonalId())) { searchFields.add(new AdvancedProperty("personal_id", criterias.getPersonalId())); } if (!StringUtil.isEmpty(criterias.getContact())) { searchFields.add(new AdvancedProperty("contact", criterias.getContact())); } if (criterias.getSubscribersGroupId() != null) { searchFields.add(new AdvancedProperty("handler_category_id", getSelectedGroup(criterias.getSubscribersGroupId()))); } if (!StringUtil.isEmpty(criterias.getProcessId())) { String processName = null; try { ProcessDefinitionW bpmCasesManager = ELUtil.getInstance().getBean(CasesBPMProcessDefinitionW.SPRING_BEAN_IDENTIFIER); bpmCasesManager.setProcessDefinitionId(Long.valueOf(criterias.getProcessId())); processName = bpmCasesManager.getProcessName(locale); } catch(Exception e) { LOGGER.log(Level.WARNING, "Error getting process name by: " + criterias.getProcessId()); } searchFields.add(new AdvancedProperty("cases_search_select_process", StringUtil.isEmpty(processName) ? "general_cases" : processName)); } if (!StringUtil.isEmpty(criterias.getStatusId())) { String status = null; try { status = getCasesBusiness(iwc).getLocalizedCaseStatusDescription(null, getCasesBusiness(iwc).getCaseStatus(criterias.getStatusId()), locale); } catch (Exception e) { LOGGER.log(Level.WARNING, "Error getting status name by: " + criterias.getStatusId(), e); } searchFields.add(new AdvancedProperty("status", StringUtil.isEmpty(status) ? iwrb.getLocalizedString("unknown_status", "Unknown") : status)); } if (!StringUtil.isEmpty(criterias.getDateRange())) { searchFields.add(new AdvancedProperty("date_range", criterias.getDateRange())); } if (!ListUtil.isEmpty(criterias.getProcessVariables())) { for (BPMProcessVariable variable: criterias.getProcessVariables()) { String value = variable.getValue(); String name = variable.getName(); if (CaseHandlerAssignmentHandler.handlerUserIdVarName.equals(name) || CaseHandlerAssignmentHandler.performerUserIdVarName.equals(name) || name.startsWith(VariableInstanceType.OBJ_LIST.getPrefix()) || name.startsWith(VariableInstanceType.LIST.getPrefix()) || !StringUtil.isEmpty(isResolverExist(MultipleSelectionVariablesResolver.BEAN_NAME_PREFIX + variable.getName())) ) { MultipleSelectionVariablesResolver resolver = null; try { resolver = ELUtil.getInstance().getBean(MultipleSelectionVariablesResolver.BEAN_NAME_PREFIX + variable.getName()); } catch (Throwable e) {} if (resolver != null) value = resolver.getPresentation(variable); } searchFields.add(new AdvancedProperty(iwrb.getLocalizedString(JBPMConstants.VARIABLE_LOCALIZATION_PREFIX.concat(variable.getName()), variable.getName()), value)); } } iwc.setSessionAttribute(GeneralCasesListBuilder.USER_CASES_SEARCH_QUERY_BEAN_ATTRIBUTE, searchFields); } private List<CasesListSearchFilter> getFilters(ServletContext servletContext, CasesSearchCriteriaBean criterias) { List<CasesListSearchFilter> filtersList = new ArrayList<CasesListSearchFilter>(); try { WebApplicationContext webAppContext = WebApplicationContextUtils.getWebApplicationContext(servletContext); Map<?, ?> filters = webAppContext.getBeansOfType(CasesListSearchFilter.class); if (filters == null || filters.isEmpty()) { return filtersList; } for (Object filterObject: filters.values()) { CasesListSearchFilter filter = (CasesListSearchFilter) filterObject; filter.setCriterias(criterias); filtersList.add(filter); } } catch (Exception e) { e.printStackTrace(); } return filtersList; } @Override public PagedDataCollection<CasePresentation> getCasesByQuery(CasesSearchCriteriaBean criterias) { if (criterias instanceof CasesListSearchCriteriaBean) return getCasesByQuery(CoreUtil.getIWContext(), (CasesListSearchCriteriaBean) criterias); getLogger().warning("Unable to get cases by query " + criterias + " because it is not instance of " + CasesListSearchCriteriaBean.class.getName() + ". Actual implementation: " + criterias.getClass().getName()); return null; } private boolean isPagingTurnedOn() { return IWMainApplication.getDefaultIWMainApplication().getSettings().getBoolean(UICasesList.DYNAMIC_CASES_NAVIGATOR, Boolean.TRUE); } protected List<Long> convertTo(Collection<String> collection) { if (ListUtil.isEmpty(collection)) { return Collections.emptyList(); } List<Long> subscribedGroupsIds = new ArrayList<Long>(); for (String id : collection) { subscribedGroupsIds.add(Long.valueOf(id)); } return subscribedGroupsIds; } private PagedDataCollection<CasePresentation> getCasesByQuery( IWContext iwc, CasesListSearchCriteriaBean criterias ) { User currentUser = null; if (!iwc.isLoggedOn() || (currentUser = iwc.getCurrentUser()) == null) { LOGGER.info("Not logged in, skipping searching"); return null; } long start = System.currentTimeMillis(); String casesProcessorType = criterias.getCaseListType() == null ? CasesRetrievalManager.CASE_LIST_TYPE_OPEN : criterias.getCaseListType(); List<Integer> casesIds = null; try { if (criterias.isShowAllCases()) { CasesBusiness casesBusiness = getCasesBusiness(iwc); Collection<CaseStatus> statuses = casesBusiness.getCaseStatuses(); StringBuffer allStatuses = null; if (!ListUtil.isEmpty(statuses)) { allStatuses = new StringBuffer(); for (Iterator<CaseStatus> statusesIter = statuses.iterator(); statusesIter.hasNext();) { allStatuses.append(statusesIter.next().getStatus()); if (statusesIter.hasNext()) allStatuses.append(CoreConstants.COMMA); } } criterias.setStatusesToShow(allStatuses == null ? null : allStatuses.toString()); criterias.setStatusesToHide(null); } casesIds = getCaseManagersProvider().getCaseManager().getCasePrimaryKeys( currentUser, casesProcessorType, criterias.getCaseCodesInList(), criterias.getStatusesToHideInList(), criterias.getStatusesToShowInList(), criterias.isOnlySubscribedCases(), criterias.isShowAllCases(), criterias.getProcInstIds(), criterias.getSubscribersGroupId() != null ? Arrays.asList(criterias.getSubscribersGroupId()) : null); } catch (Exception e) { LOGGER.log(Level.WARNING, "Some error occured getting cases by criterias: " + criterias, e); } if (ListUtil.isEmpty(casesIds)) return null; long end = System.currentTimeMillis(); LOGGER.info("Cases IDs were resolved in " + (end - start) + " ms"); if (criterias.getStatusId() != null) criterias.setStatuses(new String[] {criterias.getStatusId()}); if (ListUtil.isEmpty(criterias.getProcInstIds())) { // Filtering out the initial set of cases IDs by filters List<CasesListSearchFilter> filters = getFilters(iwc.getServletContext(), criterias); if (ListUtil.isEmpty(filters)) return null; for (CasesListSearchFilter filter: filters) casesIds = filter.doFilter(casesIds); } else { // Selecting cases IDs by provided process instance IDs List<Integer> ids = casesBPMDAO.getCasesIdsByProcInstIds(criterias.getProcInstIds()); if (ListUtil.isEmpty(ids)) return null; // Making sure user will see cases that are available to her/him only casesIds = DefaultCasesListSearchFilter.getNarrowedResults(casesIds, ids); } start = System.currentTimeMillis(); LOGGER.info("Searh was executed in " + (start - end) + " ms"); if (ListUtil.isEmpty(casesIds)) return null; boolean usePaging = isPagingTurnedOn(); boolean noSortingOptions = ListUtil.isEmpty(criterias.getSortingOptions()); if (usePaging && !criterias.isNoOrdering()) { Comparator<Integer> c = new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return -o1.compareTo(o2); } }; getLogger().info("Sorting cases by IDs descending"); Collections.sort(casesIds, c); } int totalCount = casesIds.size(); criterias.setFoundResults(totalCount); if (criterias.getPageSize() <= 0) criterias.setPageSize(20); if (criterias.getPage() <= 0) criterias.setPage(1); criterias.setAllDataLoaded(!(totalCount > criterias.getPageSize())); int count = criterias.getPageSize(); int startIndex = (criterias.getPage() - 1) * count; Locale locale = iwc.getCurrentLocale(); PagedDataCollection<CasePresentation> cases = null; if (!ListUtil.isEmpty(casesIds)) { if (usePaging && noSortingOptions) { // No need to load all the cases, just for one page casesIds = getSubList(casesIds, startIndex, count, totalCount); } // Loading cases by IDs cases = getCasesRetrievalManager().getCasesByIds(casesIds, locale); } if (cases == null || ListUtil.isEmpty(cases.getCollection())) return null; List<CasePresentation> result = new ArrayList<CasePresentation>(cases.getCollection()); if (!criterias.isNoOrdering()) { CasePresentationComparator comparator = getCasePresentationComparator(criterias, locale); getLogger().info("Sorting cases by comparator: " + comparator + " and sorting options: " + criterias.getSortingOptions()); Collections.sort(result, comparator); } if (usePaging && !noSortingOptions) result = getSubList(result, startIndex, count, totalCount); cases = new PagedDataCollection<CasePresentation>(result); LOGGER.info("Sorting and paging was executed in " + (System.currentTimeMillis() - start) + " ms"); return cases; } private <T> List<T> getSubList(List<T> list, int startIndex, int count, int totalCount) { if (startIndex + count < totalCount) { return list.subList(startIndex, (startIndex + count)); } else { return list.subList(startIndex, totalCount); } } private CasePresentationComparator getCasePresentationComparator(CasesListSearchCriteriaBean criterias, Locale locale) { return (criterias == null || ListUtil.isEmpty(criterias.getSortingOptions())) ? new CasePresentationComparator() : new BPMCasePresentationComparator(locale, criterias); } private BuilderLogicWrapper getBuilderLogic() { return builderLogic; } private GeneralCasesListBuilder getCasesListBuilder() { return casesListBuilder; } private CasesBusiness getCasesBusiness(IWApplicationContext iwac) { try { return IBOLookup.getServiceInstance(iwac, CasesBusiness.class); } catch (IBOLookupException ile) { LOGGER.log(Level.SEVERE, "Error getting CasesBusiness", ile); } return null; } private CasesBPMProcessView getCasesBPMProcessView() { return casesBPMProcessView; } @Override public RenderedComponent getVariablesWindow(String processDefinitionId) { RenderedComponent fake = new RenderedComponent(); fake.setErrorMessage("There are no variables for selected process!"); IWContext iwc = CoreUtil.getIWContext(); if (iwc == null) { return fake; } List<String> resources = new ArrayList<String>(); resources.add(web2.getBundleUriToHumanizedMessagesStyleSheet()); resources.add(jQuery.getBundleURIToJQueryLib()); resources.add(web2.getBundleUriToHumanizedMessagesScript()); fake.setResources(resources); IWResourceBundle iwrb = getResourceBundle(iwc); fake.setErrorMessage(iwrb.getLocalizedString("cases_search.there_are_no_variables_for_selected_process", fake.getErrorMessage())); if (!iwc.isLoggedOn()) { LOGGER.warning("User must be logged!"); return fake; } if (StringUtil.isEmpty(processDefinitionId)) { return fake; } Long pdId = null; try { pdId = Long.valueOf(processDefinitionId); } catch(NumberFormatException e) { LOGGER.severe("Unable to convert to Long: " + processDefinitionId); } if (pdId == null) { return fake; } BPMProcessVariablesBean variablesBean = null; try { variablesBean = ELUtil.getInstance().getBean(BPMProcessVariablesBean.SPRING_BEAN_IDENTIFIER); } catch(Exception e) { LOGGER.log(Level.SEVERE, "Error getting bean: " + BPMProcessVariablesBean.class.getName(), e); } if (variablesBean == null) { return fake; } variablesBean.setProcessDefinitionId(pdId); return getBuilderLogic().getBuilderService(iwc).getRenderedComponentByClassName(UIProcessVariables.class.getName(), null); } private CasesSearchResultsHolder getSearchResultsHolder() throws NullPointerException { CasesSearchResultsHolder resultsHolder = null; try { resultsHolder = ELUtil.getInstance().getBean(CasesSearchResultsHolder.SPRING_BEAN_IDENTIFIER); } catch(Exception e) { LOGGER.log(Level.WARNING, "Error getting bean for search results holder: " + CasesSearchResultsHolder.class.getName(), e); } if (resultsHolder == null) { throw new NullPointerException(); } return resultsHolder; } private boolean setSearchResults(IWContext iwc, Collection<CasePresentation> cases, CasesListSearchCriteriaBean criterias) { iwc.setSessionAttribute(GeneralCasesListBuilder.USER_CASES_SEARCH_SETTINGS_ATTRIBUTE, criterias); CasesSearchResultsHolder resultsHolder = null; try { resultsHolder = getSearchResultsHolder(); } catch(NullPointerException e) { return false; } String id = criterias.getId(); resultsHolder.setSearchResults(id, new CasesSearchResults(id, cases, criterias)); return true; } private String getType(BuilderLogic builder, String pageKey, String instanceId) { String type = getProperty(builder, pageKey, instanceId, ":method:1:implied:void:setType:java.lang.String:"); return StringUtil.isEmpty(type) ? CasesRetrievalManager.CASE_LIST_TYPE_OPEN : type; } private List<String> getCodes(BuilderLogic builder, String pageKey, String instanceId) { String codes = getProperty(builder, pageKey, instanceId, ":method:1:implied:void:setCaseCodes:java.lang.String:"); return StringUtil.isEmpty(codes) ? null : new ArrayList<String>(Arrays.asList(codes.split(CoreConstants.COMMA))); } private List<String> getStatusesToHide(BuilderLogic builder, String pageKey, String instanceId) { String hide = getProperty(builder, pageKey, instanceId, ":method:1:implied:void:setCaseStatusesToHide:java.lang.String:"); return StringUtil.isEmpty(hide) ? null : new ArrayList<String>(Arrays.asList(hide.split(CoreConstants.COMMA))); } private List<String> getStatusesToShow(BuilderLogic builder, String pageKey, String instanceId) { String show = getProperty(builder, pageKey, instanceId, ":method:1:implied:void:setCaseStatusesToShow:java.lang.String:"); return StringUtil.isEmpty(show) ? null : new ArrayList<String>(Arrays.asList(show.split(CoreConstants.COMMA))); } private boolean isShowSubscribedOnly(BuilderLogic builder, String pageKey, String instanceId) { String subscribedOnly = getProperty(builder, pageKey, instanceId, ":method:1:implied:void:setOnlySubscribedCases:boolean:"); return StringUtil.isEmpty(subscribedOnly) ? false : "T".equals(subscribedOnly) || Boolean.TRUE.toString().equals(subscribedOnly); } private String getProperty(BuilderLogic builder, String pageKey, String instanceId, String property) { return builder.getProperty(pageKey, instanceId, property); } @Override public AdvancedProperty getExportedCases(String instanceId, String uri, Boolean exportContacts, Boolean showCompany) { if (StringUtil.isEmpty(instanceId)) return null; IWContext iwc = CoreUtil.getIWContext(); if (iwc == null || !iwc.isLoggedOn()) return null; BuilderLogic builder = BuilderLogic.getInstance(); String pageKey = builder.getPageKeyByURI(uri, iwc.getDomain()); User user = iwc.getCurrentUser(); String type = getType(builder, pageKey, instanceId); List<String> caseCodes = getCodes(builder, pageKey, instanceId); List<String> statusesToHide = getStatusesToHide(builder, pageKey, instanceId); List<String> statusesToShow = getStatusesToShow(builder, pageKey, instanceId); boolean onlySubscribedCases = isShowSubscribedOnly(builder, pageKey, instanceId); PagedDataCollection<CasePresentation> cases = getCaseManagersProvider().getCaseManager().getCases(user, type, iwc.getCurrentLocale(), caseCodes, statusesToHide, statusesToShow, Integer.MAX_VALUE, -1, onlySubscribedCases, true); AdvancedProperty result = new AdvancedProperty(Boolean.FALSE.toString()); String errorMessage = getResourceBundle(iwc).getLocalizedString("unable_to_export_all_cases", "Sorry, unable to export cases to Excel"); if (cases == null || ListUtil.isEmpty(cases.getCollection())) { result.setValue(errorMessage); return result; } CasesSearchResultsHolder resultsHolder = null; try { resultsHolder = getSearchResultsHolder(); } catch (NullPointerException e) { result.setValue(errorMessage); return result; } List<CasePresentation> casesToExport = new ArrayList<CasePresentation>(cases.getCollection()); if (!resultsHolder.setCasesToExport(instanceId, casesToExport)) { result.setValue(errorMessage); return result; } result.setId(Boolean.TRUE.toString()); URIUtil uriUtil = new URIUtil(iwc.getIWMainApplication().getMediaServletURI()); uriUtil.setParameter(MediaWritable.PRM_WRITABLE_CLASS, IWMainApplication.getEncryptedClassName(CasesSearchResultsExporter.class)); uriUtil.setParameter(CasesSearchResultsExporter.ALL_CASES_DATA, instanceId); uriUtil.setParameter(CasesSearchResultsExporter.EXPORT_CONTACTS, (exportContacts != null) && (exportContacts.equals(Boolean.TRUE)) ? "y" : "n"); uriUtil.setParameter(CasesSearchResultsExporter.SHOW_USER_COMPANY, (showCompany != null) && (showCompany.equals(Boolean.TRUE)) ? "y" : "n"); result.setValue(uriUtil.getUri()); return result; } @Override public AdvancedProperty getExportedSearchResults(String id) { return getExportedSearchResults(id, false, false); } public AdvancedProperty getExportedSearchResults(String pageURI,boolean exportContacts, boolean showCompany) { IWContext iwc = CoreUtil.getIWContext(); if (iwc == null) { return null; } AdvancedProperty result = new AdvancedProperty(Boolean.FALSE.toString()); CasesSearchResultsHolder resultsHolder = null; try { resultsHolder = getSearchResultsHolder(); } catch(NullPointerException e) { result.setValue(getResourceBundle(iwc).getLocalizedString("unable_to_export_search_results", "Sorry, unable to export search results to Excel")); return result; } CasesSearchCriteriaBean criterias = resultsHolder.getSearchCriteria(pageURI); if (criterias != null) { criterias.setPage(-1); criterias.setPageSize(Integer.MAX_VALUE); } if (!resultsHolder.isSearchResultStored(pageURI) || !resultsHolder.isAllDataLoaded(pageURI)) { Collection<CasePresentation> cases = getReLoadedCases(resultsHolder, criterias, pageURI); if (ListUtil.isEmpty(cases)) { result.setValue(getResourceBundle(iwc).getLocalizedString("no_search_results_to_export", "There are no search results to export!")); return result; } else if (criterias != null) { criterias.setPageSize(cases.size()); criterias.setAllDataLoaded(Boolean.TRUE); } } getExternalSearchResults(resultsHolder, pageURI); if (!resultsHolder.doExport(pageURI,exportContacts,showCompany)) { result.setValue(getResourceBundle(iwc).getLocalizedString("unable_to_export_search_results", "Sorry, unable to export search results to Excel")); return result; } result.setId(Boolean.TRUE.toString()); URIUtil uriUtil = new URIUtil(iwc.getIWMainApplication().getMediaServletURI()); uriUtil.setParameter(MediaWritable.PRM_WRITABLE_CLASS, IWMainApplication.getEncryptedClassName(CasesSearchResultsExporter.class)); uriUtil.setParameter(CasesSearchResultsExporter.ID_PARAMETER, pageURI); result.setValue(uriUtil.getUri()); return result; } private CaseManagersProvider getCaseManagersProvider() { return caseManagersProvider; } @Override public boolean clearSearchResults(String id) { IWContext iwc = CoreUtil.getIWContext(); iwc.removeSessionAttribute(GeneralCasesListBuilder.USER_CASES_SEARCH_QUERY_BEAN_ATTRIBUTE); iwc.removeSessionAttribute(GeneralCasesListBuilder.USER_CASES_SEARCH_SETTINGS_ATTRIBUTE); setCasesPagerAttributes(-1, -1); return getSearchResultsHolder().clearSearchResults(id); } @Override public List<AdvancedProperty> getDefaultSortingOptions(IWContext iwc) { List<AdvancedProperty> defaultSortingOptions = new ArrayList<AdvancedProperty>(); IWResourceBundle iwrb = iwc.getIWMainApplication().getBundle(CasesConstants.IW_BUNDLE_IDENTIFIER).getResourceBundle(iwc); defaultSortingOptions.add(new AdvancedProperty("getCaseIdentifier", iwrb.getLocalizedString("case_nr", "Case nr."))); defaultSortingOptions.add(new AdvancedProperty("getSubject", iwrb.getLocalizedString("description", "Description"))); defaultSortingOptions.add(new AdvancedProperty("getOwnerName", iwrb.getLocalizedString("sender", "Sender"))); defaultSortingOptions.add(new AdvancedProperty("getCreated", iwrb.getLocalizedString("created_date", "Created date"))); defaultSortingOptions.add(new AdvancedProperty("getCaseStatusLocalized", iwrb.getLocalizedString("status", "Status"))); return defaultSortingOptions; } @Override public void onApplicationEvent(ApplicationEvent event) { if (event instanceof CaseModifiedEvent) { Thread cacheReseter = new Thread(new Runnable() { @Override public void run() { try { getCache(DefaultCasesListSearchFilter.SEARCH_FILTER_CACHE_NAME, DefaultCasesListSearchFilter.SEARCH_FILTER_CACHE_TTL).clear(); } catch (Exception e) { e.printStackTrace(); } } }); cacheReseter.start(); } else if (event instanceof UserHasLoggedInEvent) { doLoadCases(((UserHasLoggedInEvent) event).getUserId()); } else if (event instanceof IWMainSlideStartedEvent) { doLoadCases(((IWMainSlideStartedEvent) event).getIWMA()); } } private void doLoadCases(IWMainApplication app) { String groupId = app.getSettings().getProperty("load_cases_for_group"); if (StringUtil.isEmpty(groupId)) return; try { GroupBusiness groupBusiness = IBOLookup.getServiceInstance(app.getIWApplicationContext(), GroupBusiness.class); Group group = groupBusiness.getGroupByGroupID(Integer.valueOf(groupId)); doLoadCases(app, group); if (app.getSettings().getBoolean("load_cases_for_group_children", Boolean.FALSE)) { Collection<Group> children = group.getChildren(); if (ListUtil.isEmpty(children)) { LOGGER.warning("There are no children groups for group " + group + ", ID: " + group.getId()); return; } for (Group child: children) doLoadCases(app, child); } } catch (FinderException e) { LOGGER.warning("Group by ID '" + groupId + "' does not exist!"); } catch (Exception e) { e.printStackTrace(); } } private void doLoadCases(IWMainApplication app, Group group) { if (group == null) { LOGGER.warning("Group is not provided"); return; } try { UserBusiness userBusiness = IBOLookup.getServiceInstance(app.getIWApplicationContext(), UserBusiness.class); Collection<User> users = userBusiness.getUsersInGroup(group); if (ListUtil.isEmpty(users)) { LOGGER.warning("There are no users in group " + group + ", ID: " + group.getId()); return; } LOGGER.info("Will load cases for users: " + users); for (final User user: users) { Thread loader = new Thread(new Runnable() { @Override public void run() { doLoadCases(user); } }); loader.start(); } } catch (Exception e) { e.printStackTrace(); } } @Override public void doLoadCases(User user) { if (user == null) { getLogger().warning("User is not provided!"); return; } getLogger().info("Loading cases for " + user); BuilderLogic builder = BuilderLogic.getInstance(); @SuppressWarnings("unchecked") List<Class<? extends CaseBlock>> classes = Arrays.asList( OpenCases.class, ClosedCases.class, MyCases.class, PublicCases.class, UserCases.class ); for (Class<? extends CaseBlock> theClass: classes) { Collection<ICObjectInstance> instances = null; try { ICObjectInstanceHome instanceHome = (ICObjectInstanceHome) IDOLookup.getHome(ICObjectInstance.class); instances = instanceHome.getByClassName(theClass); } catch (FinderException e) { } catch (Exception e) {} if (ListUtil.isEmpty(instances)) continue; for (ICObjectInstance instance: instances) { if (instance == null) continue; String uniqueId = instance.getUniqueId(); if (StringUtil.isEmpty(uniqueId)) continue; String instanceId = ICObjectBusiness.UUID_PREFIX.concat(uniqueId); ICPage page = builder.findPageForModule(getApplication(), instanceId); if (page == null || page.getDeleted()) continue; String pageKey = page.getId(); String type = getType(builder, pageKey, instanceId); List<String> caseCodes = getCodes(builder, pageKey, instanceId); List<String> statusesToHide = getStatusesToHide(builder, pageKey, instanceId); List<String> statusesToShow = getStatusesToShow(builder, pageKey, instanceId); boolean onlySubscribedCases = isShowSubscribedOnly(builder, pageKey, instanceId); try { getCaseManagersProvider().getCaseManager().getCaseIds(user, type, caseCodes, statusesToHide, statusesToShow, onlySubscribedCases, false); } catch (Exception e) { getLogger().log(Level.WARNING, "Error loading cases for list " + theClass.getName() + " for user " + user + " after login event", e); } } } } private void doLoadCases(final Integer userId) { if (!getApplication().getSettings().getBoolean("load_cases_on_user_login", Boolean.TRUE)) return; if (userId == null || userId < 0) return; Thread loader = new Thread(new Runnable() { @Override public void run() { UserBusiness userBusiness = getServiceInstance(UserBusiness.class); User user = null; try { user = userBusiness.getUser(userId); } catch (Exception e) {} doLoadCases(user); } }); loader.start(); } @Override public Collection<CasePresentation> getReLoadedCases(CasesSearchCriteriaBean criterias) { Collection<CasePresentation> reLoadedCases = getReLoadedCases(null, criterias, null); if (!ListUtil.isEmpty(reLoadedCases)) criterias.setAllDataLoaded(Boolean.FALSE); return reLoadedCases; } private Collection<CasePresentation> getReLoadedCases(CasesSearchResultsHolder resultsHolder, CasesSearchCriteriaBean criterias, String id) { if (criterias instanceof CasesListSearchCriteriaBean) { IWContext iwc = CoreUtil.getIWContext(); CasesListSearchCriteriaBean listCriterias = (CasesListSearchCriteriaBean) criterias; PagedDataCollection<CasePresentation> cases = getCasesByQuery(iwc, listCriterias); if (cases == null) cases = new PagedDataCollection<CasePresentation>(new ArrayList<CasePresentation>()); listCriterias.setAllDataLoaded(Boolean.TRUE); listCriterias.setPageSize(cases.getTotalCount()); setSearchResults(iwc, cases.getCollection(), listCriterias); if (resultsHolder != null && id != null) { Collection<CasePresentation> externalData = getExternalSearchResults(resultsHolder, id); if (ListUtil.isEmpty(cases.getCollection())) { return externalData; } } return cases.getCollection(); } getLogger().warning("Unable to get cases by query " + criterias + " because it is not instance of " + CasesListSearchCriteriaBean.class.getName() + ". Actual implementation: " + (criterias == null ? "null " : criterias.getClass().getName())); return null; } @SuppressWarnings("unchecked") private Collection<CasePresentation> getExternalSearchResults(CasesSearchResultsHolder resultsHolder, String id) { Map<String, ? extends ExternalCasesDataExporter> externalExporters = null; try { externalExporters = WebApplicationContextUtils.getWebApplicationContext(getApplication().getServletContext()).getBeansOfType(ExternalCasesDataExporter.class); } catch (Exception e) { getLogger().log(Level.WARNING, "Error getting beans of type: " + ExternalCasesDataExporter.class, e); } if (externalExporters == null || externalExporters.isEmpty()) { return null; } List<CasePresentation> data = new ArrayList<CasePresentation>(); for (ExternalCasesDataExporter externalExporter: externalExporters.values()) { List<CasePresentation> externalData = externalExporter.getExternalData(id); resultsHolder.concatExternalData(id, externalData); if (!ListUtil.isEmpty(externalData)) { data.addAll(externalData); } } return data; } @Override public String getCaseStatus(Long processInstanceId) { if (processInstanceId == null) { LOGGER.warning("Process instance id is not provided"); return null; } CaseProcInstBind bind = null; try { bind = casesBPMDAO.getCaseProcInstBindByProcessInstanceId(processInstanceId); } catch (Exception e) { LOGGER.log(Level.WARNING, "Error while getting instance of " + CaseProcInstBind.class.getName() + " by process instance: " + processInstanceId, e); } if (bind == null) { return null; } CasePresentation theCase = null; try { theCase = caseManagersProvider.getCaseManager().getCaseByIdLazily(bind.getCaseId()); } catch (Exception e) { LOGGER.log(Level.WARNING, "Error getting case by id: " + bind.getCaseId(), e); } return theCase == null ? null : theCase.getLocalizedStatus(); } @Override public boolean setCasesPagerAttributes(int page, int pageSize) { page = page <= 0 ? 1 : page; pageSize = pageSize <= 0 ? 20 : pageSize; String key = "userCases"; IWContext iwc = CoreUtil.getIWContext(); iwc.setSessionAttribute(ListNavigator.PARAMETER_CURRENT_PAGE + "_" + key, page); iwc.setSessionAttribute(ListNavigator.PARAMETER_NUMBER_OF_ENTRIES + "_" + key, pageSize); return true; } /* * (non-Javadoc) * @see is.idega.idegaweb.egov.cases.business.CasesEngine#getAvailableProcesses(com.idega.presentation.IWContext) */ @Override public List<AdvancedProperty> getAvailableProcesses(IWContext iwc) { ApplicationBusiness appBusiness = null; try { appBusiness = IBOLookup.getServiceInstance(iwc, ApplicationBusiness.class); } catch (IBOLookupException e) { e.printStackTrace(); } if (appBusiness == null) { return null; } ApplicationType appType = null; try { appType = ELUtil.getInstance().getBean("appTypeBPM"); } catch(Exception e) { LOGGER.log(Level.WARNING, "Unable to get application type", e); return null; } Collection<Application> bpmApps = appBusiness.getApplicationsByType(appType.getType()); if (ListUtil.isEmpty(bpmApps)) { return null; } CaseManagersProvider caseManagersProvider = ELUtil.getInstance().getBean(CaseManagersProvider.beanIdentifier); if (caseManagersProvider == null) { return null; } CasesRetrievalManager caseManager = caseManagersProvider.getCaseManager(); if (caseManager == null) { return null; } List<AdvancedProperty> allProcesses = new ArrayList<AdvancedProperty>(); String processId = null; String processName = null; String localizedName = null; Locale locale = iwc.getCurrentLocale(); for (Application bpmApp: bpmApps) { processId = null; processName = bpmApp.getUrl(); localizedName = processName; if (appType.isVisible(bpmApp)) { if (StringUtil.isEmpty(processId)) { processId = String.valueOf(caseManager.getLatestProcessDefinitionIdByProcessName(processName)); } localizedName = caseManager.getProcessName(processName, locale); if (!StringUtil.isEmpty(processId)) { allProcesses.add(new AdvancedProperty(processId, localizedName)); } } else { LOGGER.warning(new StringBuilder("Application '").append(bpmApp.getName()).append("' is not accessible") .append((iwc.isLoggedOn() ? " for user: " + iwc.getCurrentUser() : ": user must be logged in!")).toString()); } } if (ListUtil.isEmpty(allProcesses)) { return null; } Collections.sort(allProcesses, new AdvancedPropertyComparator(iwc.getCurrentLocale())); return allProcesses; } /* * (non-Javadoc) * @see is.idega.idegaweb.egov.cases.business.CasesEngine#isResolverExist(java.lang.String) */ @Override public String isResolverExist(String beanName) { Map<String, String> cache = getResolversCache(); if (cache == null) { getLogger().log(Level.WARNING, "Unable to get cache!"); return null; } if (cache.containsKey(beanName)) return cache.get(beanName); try { MultipleSelectionVariablesResolver resolver = ELUtil.getInstance().getBean(beanName); if (resolver != null) { String className = resolver.getPresentationClass().getName(); cache.put(beanName, className); return className; } } catch (Throwable e) {} cache.put(beanName, CoreConstants.EMPTY); return CoreConstants.EMPTY; } private Map<String, String> getResolversCache() { return getCache("BEAN_NAMES_FOR_BPM_PROCESS_SEARCH"); } @Override public boolean showCaseAssets() { try { CasesBPMAssetsState assetsState = ELUtil.getInstance().getBean(CasesBPMAssetsState.beanIdentifier); assetsState.showAssets(); return true; } catch (Exception e) { getLogger().log(Level.WARNING, "Error while setting instruction to show assets", e); } return false; } @Override public AdvancedProperty getExportedCasesToPDF(CasesExportParams params) { IWResourceBundle iwrb = getResourceBundle(getBundle(IWBundleStarter.IW_BUNDLE_IDENTIFIER)); AdvancedProperty result = new AdvancedProperty( Boolean.FALSE.toString(), iwrb.getLocalizedString("failed_to_export_cases", "Failed to export cases"), String.valueOf(0) ); if (params == null) { return result; } String id = params.getId(); Map<String, List<Integer>> idsCache = getCache("cases_to_export_to_pdf_cache", 86400, 100); Map<String, Map<String, String>> statusesCache = getCache("cases_to_export_to_pdf_statuses_cache", 86400, 100); Map<String, String> exportStatuses = statusesCache.get(id); if (exportStatuses != null) { exportStatuses.remove(id); } Long processDefinitionId = params.getProcessDefinitionId(); if (processDefinitionId == null) { return result; } IWTimestamp from = null, to = null; Date tmp = IWDatePickerHandler.getParsedDate(params.getDateFrom()); if (tmp != null) { from = new IWTimestamp(tmp); } tmp = null; tmp = IWDatePickerHandler.getParsedDate(params.getDateTo()); if (tmp != null) { to = new IWTimestamp(tmp); } List<Integer> casesIds = casesBPMDAO.getCaseIdsByProcessDefinitionIdAndStatusAndDateRange(processDefinitionId, params.getStatus(), from, to); if (ListUtil.isEmpty(casesIds)) { result.setValue(iwrb.getLocalizedString("there_are_no_cases_to_export", "There are no cases to export")); return result; } idsCache.put(id, casesIds); result.setId(id); int seconds = casesIds.size() * 10; int minutes = ((seconds / 60) % 60); int hours = ((seconds / (60*60)) % 24); String label = iwrb.getLocalizedString("found_cases_to_export", "Found applications to export") + ": " + casesIds.size() + ". " + iwrb.getLocalizedString("export_process_may_take_time", "Approximately it may take") + CoreConstants.SPACE + (hours > 0 ? hours + CoreConstants.SPACE + iwrb.getLocalizedString("hours", "hour(s)") + CoreConstants.SPACE : CoreConstants.EMPTY) + (minutes > 0 ? minutes + CoreConstants.SPACE + iwrb.getLocalizedString("minutes", "minute(s)") + CoreConstants.SPACE : CoreConstants.EMPTY) + (seconds % 60 > 0 ? (seconds % 60) + CoreConstants.SPACE + iwrb.getLocalizedString("seconds", "second(s)") + CoreConstants.SPACE : CoreConstants.EMPTY) + iwrb.getLocalizedString("to_export_do_you_want_to_continue", "to export. Do you want to continue?"); result.setValue(label); result.setName(String.valueOf(casesIds.size())); return result; } @Override public AdvancedProperty doActualExport(String id) { IWResourceBundle iwrb = getResourceBundle(getBundle(IWBundleStarter.IW_BUNDLE_IDENTIFIER)); AdvancedProperty result = new AdvancedProperty( Boolean.FALSE.toString(), iwrb.getLocalizedString("failed_to_export_cases", "Failed to export cases") ); Map<String, String> exportStatuses = null; try { if (StringUtil.isEmpty(id)) { return result; } Map<String, List<Integer>> idsCache = getCache("cases_to_export_to_pdf_cache", 86400, 100); List<Integer> casesIds = idsCache.get(id); Map<String, Map<String, String>> statusesCache = getCache("cases_to_export_to_pdf_statuses_cache", 86400, 100); exportStatuses = statusesCache.get(id); if (exportStatuses == null) { exportStatuses = new HashMap<String, String>(); statusesCache.put(id, exportStatuses); } File baseDir = CasesExporter.getDirectory(id); int i = 0; for (Iterator<Integer> casesIdsIter = casesIds.iterator(); casesIdsIter.hasNext();) { Integer caseId = casesIdsIter.next(); i++; exportStatuses.put( id, iwrb.getLocalizedString("exporting", "Exporting") + CoreConstants.SPACE + i+ CoreConstants.SPACE + iwrb.getLocalizedString("of", "of") + CoreConstants.SPACE + casesIds.size() ); List<CasePDF> casePDFs = null; try { casePDFs = caseConverter.getPDFsAndAttachmentsForCase(caseId); } catch (Exception e) { getLogger().log(Level.WARNING, "Error exporting case (ID: " + caseId + ") to PDFs", e); } if (ListUtil.isEmpty(casePDFs)) { continue; } File caseFolder = new File(baseDir.getAbsolutePath() + File.separator + casePDFs.get(0).getIdentifier()); if (!caseFolder.exists()) { caseFolder.mkdir(); } for (CasePDF casePDF: casePDFs) { if (casePDF == null) { continue; } byte[] pdfData = casePDF.getBytes(); if (pdfData == null || pdfData.length <= 0) { continue; } File pdf = new File(caseFolder.getAbsoluteFile() + File.separator + casePDF.getName()); if (!pdf.exists()) { pdf.createNewFile(); } FileUtil.streamToFile(new ByteArrayInputStream(pdfData), pdf); List<CaseAttachment> attachments = casePDF.getAttachments(); if (!ListUtil.isEmpty(attachments)) { File attachmentsFolder = new File(caseFolder.getAbsoluteFile() + File.separator + "attachments"); if (!attachmentsFolder.exists()) { attachmentsFolder.mkdir(); } for (CaseAttachment attachment: attachments) { if (attachment == null) { continue; } byte[] attachmentData = attachment.getBytes(); if (attachmentData == null || attachmentData.length <= 0) { continue; } File attachmentFile = new File(attachmentsFolder.getAbsoluteFile() + File.separator + attachment.getName()); if (!attachmentFile.exists()) { attachmentFile.createNewFile(); } FileUtil.streamToFile(new ByteArrayInputStream(attachmentData), attachmentFile); } } } } } catch (Exception e) { getLogger().log(Level.WARNING, "Error exporting cases to PDFs", e); if (exportStatuses != null) { exportStatuses.remove(id); } return result; } result.setId(Boolean.TRUE.toString()); result.setValue(iwrb.getLocalizedString("cases_were_successfully_exported", "Cases were successfully exported")); result.setName(id); if (exportStatuses != null) { exportStatuses.remove(id); } return result; } @Override public AdvancedProperty getStatusOfExport(String id) { if (StringUtil.isEmpty(id)) { return new AdvancedProperty(Boolean.FALSE.toString()); } Map<String, Map<String, String>> statusesCache = getCache("cases_to_export_to_pdf_statuses_cache", 86400, 100); Map<String, String> exportStatuses = statusesCache.get(id); if (exportStatuses == null) { return null; } String status = exportStatuses.remove(id); if (StringUtil.isEmpty(status)) { return null; } return new AdvancedProperty(Boolean.TRUE.toString(), status); } @Override public Boolean doRemoveFromMemory(String id) { if (StringUtil.isEmpty(id)) { return false; } Map<String, List<Integer>> idsCache = getCache("cases_to_export_to_pdf_cache", 86400, 100); idsCache.remove(id); return true; } @Override public AdvancedProperty getLinkForZippedCases(String id, List<String> casesIdentifiers) { IWResourceBundle iwrb = getResourceBundle(getBundle(IWBundleStarter.IW_BUNDLE_IDENTIFIER)); AdvancedProperty result = new AdvancedProperty( Boolean.FALSE.toString(), iwrb.getLocalizedString("unable_to_download_zipped_cases", "Unable to download exported case(s)") ); if (StringUtil.isEmpty(id)) { return result; } File baseDir = CasesExporter.getDirectory(id); if (baseDir == null || !baseDir.exists() || !baseDir.canRead() || !baseDir.isDirectory()) { return result; } Collection<File> toZip = null; String name = "Exported_cases.zip"; if (ListUtil.isEmpty(casesIdentifiers)) { File[] casesFolders = baseDir.listFiles(); if (ArrayUtil.isEmpty(casesFolders)) { return result; } toZip = Arrays.asList(casesFolders); } else { toZip = new ArrayList<File>(); for (String identifier: casesIdentifiers) { File caseFolderToZip = new File(baseDir.getAbsoluteFile() + File.separator + identifier); if (!caseFolderToZip.exists() || !caseFolderToZip.canRead() || !caseFolderToZip.isDirectory()) { continue; } toZip.add(caseFolderToZip); } if (casesIdentifiers.size() == 1) { name = "Exported_case_" + casesIdentifiers.get(0) + ".zip"; } } if (ListUtil.isEmpty(toZip)) { return result; } File zippedFile = null; try { zippedFile = FileUtil.getZippedFiles(toZip, name, false); } catch (IOException e) { getLogger().log(Level.WARNING, "Error zipping content at " + baseDir.getAbsolutePath(), e); } if (zippedFile == null || !zippedFile.exists() || !zippedFile.canRead()) { return result; } result.setId(Boolean.TRUE.toString()); URIUtil uri = new URIUtil(getApplication().getMediaServletURI()); uri.setParameter(MediaWritable.PRM_WRITABLE_CLASS, IWMainApplication.getEncryptedClassName(DownloadWriter.class)); uri.setParameter(DownloadWriter.PRM_ABSOLUTE_FILE_PATH, zippedFile.getAbsolutePath()); result.setValue(uri.getUri()); result.setName(iwrb.getLocalizedString("downloading_exported_data", "Downloading exported data")); return result; } }