001package org.kuali.ole.select.executor;
002
003import org.kuali.ole.OLEConstants;
004import org.kuali.ole.ingest.pojo.MatchBo;
005import org.kuali.ole.select.bo.OleAgreementMethod;
006import org.kuali.ole.select.bo.OleLicenseRequestType;
007import org.kuali.ole.select.bo.OleLicenseRequestWorkflowType;
008import org.kuali.rice.core.api.exception.RiceRuntimeException;
009import org.kuali.rice.core.api.util.xml.XmlHelper;
010import org.kuali.rice.kew.engine.RouteContext;
011import org.kuali.rice.kew.framework.support.krms.RulesEngineExecutor;
012import org.kuali.rice.kew.rule.xmlrouting.XPathHelper;
013import org.kuali.rice.kim.impl.role.RoleBo;
014import org.kuali.rice.kim.impl.role.RoleMemberBo;
015import org.kuali.rice.krad.service.KRADServiceLocator;
016import org.kuali.rice.krms.api.engine.*;
017import org.kuali.rice.krms.impl.repository.AgendaBo;
018import org.w3c.dom.Document;
019
020import javax.xml.xpath.XPath;
021import javax.xml.xpath.XPathConstants;
022import java.io.ByteArrayInputStream;
023import java.util.*;
024
025/**
026 * LicenseRulesEngineExecutor validates rules from krms and executes people flow action.
027 */
028public class LicenseRulesEngineExecutor implements RulesEngineExecutor {
029
030    /**
031     * This method validates rules from krms and execute people flow action
032     *
033     * @param routeContext
034     * @param engine
035     * @return EngineResults
036     */
037    @Override
038    public EngineResults execute(RouteContext routeContext, Engine engine) {
039        EngineResults engineResult = null;
040        HashMap<String, Object> agendaValue = new HashMap<String, Object>();
041        agendaValue.put("nm", OLEConstants.OleLicenseRequest.LICENSE_AGENDA_NM);
042        List<AgendaBo> agendaBos = (List<AgendaBo>) KRADServiceLocator.getBusinessObjectService().findMatching(AgendaBo.class, agendaValue);
043        if (agendaBos != null && agendaBos.size() > 0) {
044            AgendaBo agendaBo = agendaBos.get(0);
045            HashMap<String, String> map = new HashMap<String, String>();
046            map.put("AGENDA_NAME", agendaBo.getName());
047            List<MatchBo> matchBos = (List<MatchBo>) KRADServiceLocator.getBusinessObjectService().findMatching(MatchBo.class, map);
048
049            SelectionCriteria selectionCriteria =
050                    SelectionCriteria.createCriteria(null, getSelectionContext(agendaBo.getContext().getName()),
051                            getAgendaContext(OLEConstants.OleLicenseRequest.LICENSE_AGENDA_NM));
052
053            ExecutionOptions executionOptions = new ExecutionOptions();
054            executionOptions.setFlag(ExecutionFlag.LOG_EXECUTION, true);
055
056            Facts.Builder factBuilder = Facts.Builder.create();
057
058            String docContent = routeContext.getDocument().getDocContent();
059
060            String licenseRequestWorkflowTypeCode =
061                    getElementValue(docContent, "//newMaintainableObject/dataObject/licenseRequestWorkflowTypeCode");
062
063            String agreementMethodId =
064                    getElementValue(docContent, "//newMaintainableObject/dataObject/agreementMethodId");
065            String licenseRequestTypeId =
066                    getElementValue(docContent, "//newMaintainableObject/dataObject/licenseRequestTypeId");
067            String oleLicenseRequestStatusCode =
068                    getElementValue(docContent, "//newMaintainableObject/dataObject/oleLicenseRequestStatus/code");
069            String owner =
070                    getElementValue(docContent, "//newMaintainableObject/dataObject/assignee");
071
072            String licenseType = "";
073            String workflowName = "";
074            String agreementMethod = "";
075            if (licenseRequestTypeId != null && !licenseRequestTypeId.isEmpty()) {
076                licenseType = getLicenseType(licenseRequestTypeId);
077            }
078            if (licenseRequestWorkflowTypeCode != null && !licenseRequestWorkflowTypeCode.isEmpty()) {
079                workflowName = getWorkFlowName(licenseRequestWorkflowTypeCode);
080            }
081            if (agreementMethodId != null && !agreementMethodId.isEmpty()) {
082                agreementMethod = getAgreementMethod(agreementMethodId);
083            }
084            HashMap<String, Object> termValues = new HashMap<String, Object>();
085            if (licenseRequestWorkflowTypeCode.equalsIgnoreCase(OLEConstants.OleLicenseRequest.SIGNATORY_ONLY) ||
086                    licenseRequestWorkflowTypeCode.equalsIgnoreCase(OLEConstants.OleLicenseRequest.REVIEW_ONLY)
087                    || licenseRequestWorkflowTypeCode.equalsIgnoreCase(OLEConstants.OleLicenseRequest.APPROVE_ONLY)
088                    && !oleLicenseRequestStatusCode.equalsIgnoreCase(OLEConstants.OleLicenseRequest.LICENSE_COMPLETE)) {
089                termValues.put("licenseType", licenseType);
090                termValues.put("agreementMethod", agreementMethod);
091                termValues.put("workflowName", workflowName);
092                if (owner != null && !owner.isEmpty()) {
093                    changeLicenseMangerRoleToOwner(owner);
094                }
095            }
096
097            for (Iterator<MatchBo> matchBoIterator = matchBos.iterator(); matchBoIterator.hasNext(); ) {
098                MatchBo matchBo = matchBoIterator.next();
099                factBuilder.addFact(matchBo.getTermName(), termValues.get((matchBo.getTermName())));
100            }
101
102
103            engineResult = engine.execute(selectionCriteria, factBuilder.build(), executionOptions);
104        }
105        return engineResult;  //To change body of implemented methods use File | Settings | File Templates.
106    }
107
108    private String getAgreementMethod(String agreementMethodId) {
109        OleAgreementMethod agreementMethod = KRADServiceLocator.getBusinessObjectService().findBySinglePrimaryKey(OleAgreementMethod.class, agreementMethodId);
110        return agreementMethod.getAgreementMethodName();
111    }
112
113    /**
114     * This method returns LicenseType using licenseRequestTypeId.
115     *
116     * @param licenseRequestTypeId
117     * @return oleLicenseRequestType
118     */
119    private String getLicenseType(String licenseRequestTypeId) {
120        OleLicenseRequestType oleLicenseRequestType = KRADServiceLocator.getBusinessObjectService().findBySinglePrimaryKey(OleLicenseRequestType.class, licenseRequestTypeId);
121        return oleLicenseRequestType.getName();
122    }
123
124    private String getWorkFlowName(String licenseRequestWorkflowTypeCode) {
125        OleLicenseRequestWorkflowType oleLicenseRequestWorkflowType = KRADServiceLocator.getBusinessObjectService().findBySinglePrimaryKey(OleLicenseRequestWorkflowType.class, licenseRequestWorkflowTypeCode);
126        return oleLicenseRequestWorkflowType.getName();
127    }
128
129    /**
130     * This method returns ElementValue using docContent and xpathExpression..
131     *
132     * @param docContent
133     * @param xpathExpression
134     * @return value
135     */
136    private String getElementValue(String docContent, String xpathExpression) {
137        try {
138            Document document = XmlHelper.trimXml(new ByteArrayInputStream(docContent.getBytes()));
139
140            XPath xpath = XPathHelper.newXPath();
141            String value = (String) xpath.evaluate(xpathExpression, document, XPathConstants.STRING);
142
143            return value;
144
145        } catch (Exception e) {
146            throw new RiceRuntimeException();
147        }
148    }
149
150    /**
151     * This method returns SelectionContext using contextName.
152     *
153     * @param contextName
154     * @return Map
155     */
156    protected Map<String, String> getSelectionContext(String contextName) {
157        Map<String, String> selector = new HashMap<String, String>();
158        selector.put(OLEConstants.NAMESPACE_CODE_SELECTOR, OLEConstants.OLE_NAMESPACE);
159        selector.put(OLEConstants.NAME_SELECTOR, contextName);
160        return selector;
161    }
162
163    /**
164     * This method returns AgendaContext using agendaName..
165     *
166     * @param agendaName
167     * @return Map
168     */
169    protected Map<String, String> getAgendaContext(String agendaName) {
170        Map<String, String> selector = new HashMap<String, String>();
171        selector.put(OLEConstants.NAME_SELECTOR, agendaName);
172        return selector;
173    }
174
175    /**
176     * This method change the license role using owner.
177     *
178     * @param owner
179     */
180    private void changeLicenseMangerRoleToOwner(String owner) {
181        HashMap<String, String> map = new HashMap<String, String>();
182        map.put("ROLE_NM", OLEConstants.OleLicenseRequest.LICENSE_MNGR_ROLE_NM);
183        List<RoleBo> roleBos = (List<RoleBo>) KRADServiceLocator.getBusinessObjectService().findMatching(RoleBo.class, map);
184        List<RoleMemberBo> roleMemberBos = roleBos != null && roleBos.size() > 0 ? roleBos.get(0).getMembers() : new ArrayList<RoleMemberBo>();
185        RoleMemberBo roleMemberBo = roleMemberBos.size() > 0 ? roleMemberBos.get(0) : null;
186        if (roleMemberBo != null) {
187            roleMemberBo.setMemberId(owner);
188            KRADServiceLocator.getBusinessObjectService().save(roleMemberBo);
189        }
190    }
191}