package is.idega.idegaweb.egov.bpm.cases.presentation.beans; import is.idega.idegaweb.egov.bpm.cases.search.CasesListSearchCriteriaBean; import java.io.Serializable; import java.lang.reflect.Method; import java.text.Collator; import java.util.ArrayList; import java.util.Collection; 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 org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import com.idega.block.process.presentation.beans.CasePresentation; import com.idega.block.process.presentation.beans.CasePresentationComparator; import com.idega.builder.bean.AdvancedProperty; import com.idega.idegaweb.egov.bpm.data.CaseProcInstBind; import com.idega.idegaweb.egov.bpm.data.dao.CasesBPMDAO; import com.idega.jbpm.bean.VariableInstanceInfo; import com.idega.jbpm.data.VariableInstanceQuerier; import com.idega.util.CoreConstants; import com.idega.util.ListUtil; import com.idega.util.StringUtil; import com.idega.util.expression.ELUtil; import com.idega.util.reflect.MethodInvoker; public class BPMCasePresentationComparator extends CasePresentationComparator { private Locale locale; private CasesListSearchCriteriaBean searchCriterias; private Map<String, List<VariableInstanceInfo>> variables; @Autowired private CasesBPMDAO casesBPMDAO; @Autowired private VariableInstanceQuerier variablesQuerier; private Collator collator; public BPMCasePresentationComparator(Locale locale, CasesListSearchCriteriaBean searchCriterias) { variables = new HashMap<String, List<VariableInstanceInfo>>(); this.locale = locale; this.searchCriterias = searchCriterias; collator = Collator.getInstance(this.locale); } @Override public int compare(CasePresentation case1, CasePresentation case2) { StringBuilder compareValue1 = new StringBuilder(); StringBuilder compareValue2 = new StringBuilder(); boolean datesUsed = false; String getCreatedSortingOption = "getCreated"; for (AdvancedProperty sortingOption: searchCriterias.getSortingOptions()) { String sortingOptionValue = sortingOption.getId(); datesUsed = getCreatedSortingOption.equals(sortingOptionValue); compareValue1.append(getSortableFieldValue(case1, sortingOptionValue)); compareValue2.append(getSortableFieldValue(case2, sortingOptionValue)); } int result = (StringUtil.isEmpty(compareValue1.toString()) && StringUtil.isEmpty(compareValue2.toString())) ? 0 : collator.compare(compareValue1.toString(), compareValue2.toString()); return datesUsed ? -1 * result : result; } private String getSortableFieldValue(CasePresentation theCase, String sortableIdentifier) { if (theCase == null || StringUtil.isEmpty(sortableIdentifier)) { Logger.getLogger(getClass().getName()).warning("Some parameters are not provided: case presentation: " + theCase + ", method: " + sortableIdentifier); return CoreConstants.EMPTY; } if (isDefaultField(sortableIdentifier)) { try { return MethodInvoker.getInstance().invokeMethodWithNoParameters(theCase, sortableIdentifier).toString(); } catch(Exception e) { Logger.getLogger(getClass().getName()).log(Level.WARNING, "Error invoking " + sortableIdentifier, e); } } else { return getVariableValue(theCase, sortableIdentifier); } return CoreConstants.EMPTY; } private boolean isDefaultField(String methodName) { if (StringUtil.isEmpty(methodName)) { return false; } for (Method method: CasePresentation.class.getMethods()) { if (methodName.equals(method.getName())) { return true; } } return false; } private List<VariableInstanceInfo> getCaseVariables(String caseId) { List<VariableInstanceInfo> variables = this.variables.get(caseId); if (variables == null) { CaseProcInstBind cpi = getCasesBPMDAO().getCaseProcInstBindByCaseId(Integer.valueOf(caseId)); Long piId = cpi == null ? null : cpi.getProcInstId(); Collection<VariableInstanceInfo> tmpVariables = piId == null ? null : getVariablesQuerier().getFullVariablesByProcessInstanceId(piId); if (tmpVariables == null) { variables = new ArrayList<VariableInstanceInfo>(0); } else { variables = new ArrayList<VariableInstanceInfo>(tmpVariables); } this.variables.put(caseId, variables); } return variables; } @Transactional(readOnly=true) private String getVariableValue(CasePresentation theCase, String variableName) { try { List<VariableInstanceInfo> variables = getCaseVariables(theCase.getId()); if (ListUtil.isEmpty(variables)) { return CoreConstants.EMPTY; } String value = null; for (Iterator<VariableInstanceInfo> variablesIter = variables.iterator(); (variablesIter.hasNext() && StringUtil.isEmpty(value));) { VariableInstanceInfo variable = variablesIter.next(); String name = variable.getName(); if (variableName.equals(name)) { Serializable tmpValue = variable.getValue(); if (tmpValue != null) { value = tmpValue.toString(); } } } return StringUtil.isEmpty(value) ? CoreConstants.EMPTY : value.toString(); } catch(Exception e) { Logger.getLogger(getClass().getName()).log(Level.WARNING, "Error getting variable's value: " + variableName, e); } return CoreConstants.EMPTY; } private CasesBPMDAO getCasesBPMDAO() { if (casesBPMDAO == null) { ELUtil.getInstance().autowire(this); } return casesBPMDAO; } public void setCaseBPMDAO(CasesBPMDAO casesBPMDAO) { this.casesBPMDAO = casesBPMDAO; } public VariableInstanceQuerier getVariablesQuerier() { if (variablesQuerier == null) { ELUtil.getInstance().autowire(this); } return variablesQuerier; } public void setVariablesQuerier(VariableInstanceQuerier variablesQuerier) { this.variablesQuerier = variablesQuerier; } }