001package org.kuali.ole.deliver.executor;
002
003import org.apache.log4j.Logger;
004import org.kuali.ole.DataCarrierService;
005import org.kuali.ole.OLEConstants;
006import org.kuali.ole.deliver.bo.OleDeliverRequestBo;
007import org.kuali.ole.ingest.pojo.MatchBo;
008import org.kuali.rice.core.api.exception.RiceRuntimeException;
009import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
010import org.kuali.rice.core.api.util.xml.XmlHelper;
011import org.kuali.rice.kew.engine.RouteContext;
012import org.kuali.rice.kew.framework.support.krms.RulesEngineExecutor;
013import org.kuali.rice.kew.rule.xmlrouting.XPathHelper;
014import org.kuali.rice.krad.service.BusinessObjectService;
015import org.kuali.rice.krad.service.KRADServiceLocator;
016import org.kuali.rice.krad.util.GlobalVariables;
017import org.kuali.rice.krms.api.engine.*;
018import org.kuali.rice.krms.impl.repository.AgendaBo;
019import org.w3c.dom.Document;
020
021import javax.xml.xpath.XPath;
022import javax.xml.xpath.XPathConstants;
023import java.io.ByteArrayInputStream;
024import java.util.*;
025
026/**
027 * OleLicenseRulesEngineExecutor validates rules from krms and executes people flow action.
028 */
029public class OleDeliverRequestEngineExecutor implements RulesEngineExecutor {
030    private List<OleDeliverRequestBo> recallList = new ArrayList<OleDeliverRequestBo>();
031    private List<OleDeliverRequestBo> holdList = new ArrayList<OleDeliverRequestBo>();
032    private List<OleDeliverRequestBo> pageList = new ArrayList<OleDeliverRequestBo>();
033    private List<OleDeliverRequestBo> requestsByBorrower = new ArrayList<OleDeliverRequestBo>();
034    private BusinessObjectService businessObjectService;
035    private static final Logger LOG = Logger.getLogger(OleDeliverRequestEngineExecutor.class);
036
037    public BusinessObjectService getBusinessObjectService() {
038        if (businessObjectService == null) {
039            return KRADServiceLocator.getBusinessObjectService();
040        }
041        return businessObjectService;
042    }
043
044    /**
045     * This method validates rules from krms and execute people flow action
046     *
047     * @param routeContext
048     * @param engine
049     * @return EngineResults
050     */
051    @Override
052    public EngineResults execute(RouteContext routeContext, Engine engine) {
053        EngineResults engineResult = null;
054        DataCarrierService dataCarrierService = GlobalResourceLoader.getService(OLEConstants.DATA_CARRIER_SERVICE);
055        HashMap<String, Object> agendaValue = new HashMap<String, Object>();
056        agendaValue.put(OLEConstants.NAME_NM, OLEConstants.REQUEST_AGENDA_NM);
057        List<AgendaBo> agendaBos = (List<AgendaBo>) KRADServiceLocator.getBusinessObjectService().findMatching(AgendaBo.class, agendaValue);
058        if (agendaBos != null && agendaBos.size() > 0) {
059            AgendaBo agendaBo = agendaBos.get(0);
060            HashMap<String, String> map = new HashMap<String, String>();
061            map.put(OLEConstants.AGENDA_NAME, agendaBo.getName());
062            List<MatchBo> matchBos = (List<MatchBo>) KRADServiceLocator.getBusinessObjectService().findMatching(MatchBo.class, map);
063
064            SelectionCriteria selectionCriteria =
065                    SelectionCriteria.createCriteria(null, getSelectionContext(agendaBo.getContext().getName()),
066                            getAgendaContext(OLEConstants.REQUEST_AGENDA_NM));
067
068            ExecutionOptions executionOptions = new ExecutionOptions();
069            executionOptions.setFlag(ExecutionFlag.LOG_EXECUTION, true);
070
071            Facts.Builder factBuilder = Facts.Builder.create();
072
073            String docContent = routeContext.getDocument().getDocContent();
074
075            String borrowerType =
076                    getElementValue(docContent, OLEConstants.DATA_OBJECT + OLEConstants.PATRON_TYPE_NAME);
077            String itemType =
078                    getElementValue(docContent, OLEConstants.DATA_OBJECT + OLEConstants.ITEM_TYPE_NM);
079            String requestTypeId =
080                    getElementValue(docContent, OLEConstants.DATA_OBJECT + OLEConstants.OleDeliverRequest.REQUEST_TYPE_ID);
081            String requestTypeCd =
082                    getElementValue(docContent, OLEConstants.DATA_OBJECT + OLEConstants.OleDeliverRequest.REQUEST_TYPE_CD);
083            String location =
084                    getElementValue(docContent, OLEConstants.DATA_OBJECT + OLEConstants.SHELVING_LOCATION);
085            String itemCollection =
086                    getElementValue(docContent, OLEConstants.DATA_OBJECT + OLEConstants.ITEM_COLLECTION);
087            String itemLibrary =
088                    getElementValue(docContent, OLEConstants.DATA_OBJECT + OLEConstants.ITEM_LIBRARY);
089            String itemCampus =
090                    getElementValue(docContent, OLEConstants.DATA_OBJECT + OLEConstants.ITEM_CAMPUS);
091            String itemInstitution =
092                    getElementValue(docContent, OLEConstants.DATA_OBJECT + OLEConstants.ITEM_INSTITUTION);
093            String itemUUID = getElementValue(docContent, OLEConstants.DATA_OBJECT + OLEConstants.OleDeliverRequest.ITEM_UUID);
094            String borrowerId = getElementValue(docContent, OLEConstants.DATA_OBJECT + OLEConstants.OleDeliverRequest.BORROWER_ID);
095            String itemId = getElementValue(docContent, OLEConstants.DATA_OBJECT + OLEConstants.OleDeliverRequest.ITEM_ID);
096            Map<String, String> requestMap = new HashMap<String, String>();
097            requestMap.put(OLEConstants.ITEM_UUID, itemUUID);
098            if (requestTypeId.equals("1") || (requestTypeId.equals("2"))) {
099                requestMap.put(OLEConstants.OleDeliverRequest.REQUEST_TYPE_ID, "1");
100                recallList = (List<OleDeliverRequestBo>) getBusinessObjectService().findMatching(OleDeliverRequestBo.class, requestMap);
101                requestMap.put(OLEConstants.OleDeliverRequest.REQUEST_TYPE_ID, "2");
102                recallList.addAll((List<OleDeliverRequestBo>) getBusinessObjectService().findMatching(OleDeliverRequestBo.class, requestMap));
103            } else if (requestTypeId.equals("3") || requestTypeId.equals("4")) {
104                //  holdList = (List<OleDeliverRequestBo>)getBusinessObjectService().findMatching(OleDeliverRequestBo.class,requestMap);
105                requestMap.put(OLEConstants.OleDeliverRequest.REQUEST_TYPE_ID, "3");
106                holdList = (List<OleDeliverRequestBo>) getBusinessObjectService().findMatching(OleDeliverRequestBo.class, requestMap);
107                requestMap.put(OLEConstants.OleDeliverRequest.REQUEST_TYPE_ID, "4");
108                holdList.addAll((List<OleDeliverRequestBo>) getBusinessObjectService().findMatching(OleDeliverRequestBo.class, requestMap));
109            } else if (requestTypeId.equals("5") || requestTypeId.equals("6")) {
110                // pageList = (List<OleDeliverRequestBo>)getBusinessObjectService().findMatching(OleDeliverRequestBo.class,requestMap);
111                requestMap.put(OLEConstants.OleDeliverRequest.REQUEST_TYPE_ID, "5");
112                pageList = (List<OleDeliverRequestBo>) getBusinessObjectService().findMatching(OleDeliverRequestBo.class, requestMap);
113                requestMap.put(OLEConstants.OleDeliverRequest.REQUEST_TYPE_ID, "6");
114                pageList.addAll((List<OleDeliverRequestBo>) getBusinessObjectService().findMatching(OleDeliverRequestBo.class, requestMap));
115            }
116            Map<String, String> requestByBorrower = new HashMap<String, String>();
117            requestByBorrower.put(OLEConstants.OleDeliverRequest.BORROWER_ID, borrowerId);
118            requestsByBorrower = (List<OleDeliverRequestBo>) getBusinessObjectService().findMatching(OleDeliverRequestBo.class, requestByBorrower);
119            HashMap<String, Object> termValues = new HashMap<String, Object>();
120            termValues.put(OLEConstants.BORROWER_TYPE, borrowerType);
121            termValues.put(OLEConstants.ITEM_TYPE, itemType);
122            termValues.put(OLEConstants.LOCATION, location);
123            termValues.put(OLEConstants.ITEM_SHELVING, location);
124            termValues.put(OLEConstants.ITEM_COLLECTION, itemCollection);
125            termValues.put(OLEConstants.ITEM_LIBRARY, itemLibrary);
126            termValues.put(OLEConstants.ITEM_CAMPUS, itemCampus);
127            termValues.put(OLEConstants.ITEM_INSTITUTION, itemInstitution);
128            termValues.put(OLEConstants.MAX_NO_OF_RECALL_REQUEST, new Integer(recallList.size()) + 1);
129            termValues.put(OLEConstants.MAX_NO_OF_HOLD_REQUEST, new Integer(holdList.size()) + 1);
130            termValues.put(OLEConstants.MAX_NO_OF_PAGE_REQUEST, new Integer(pageList.size()) + 1);
131            // termValues.put("maxNumberOfRequestByBorrower",requestsByBorrower.size());
132            termValues.put(OLEConstants.OleDeliverRequest.REQUEST_TYPE_ID, requestTypeId);
133            termValues.put(OLEConstants.REQUEST_TYPE, requestTypeCd);
134            termValues.put(OLEConstants.PATRON_ID_POLICY,borrowerId);
135            termValues.put(OLEConstants.ITEM_ID_POLICY,itemId);
136
137            for (Iterator<MatchBo> matchBoIterator = matchBos.iterator(); matchBoIterator.hasNext(); ) {
138                MatchBo matchBo = matchBoIterator.next();
139                factBuilder.addFact(matchBo.getTermName(), termValues.get((matchBo.getTermName())));
140            }
141
142
143            engineResult = engine.execute(selectionCriteria, factBuilder.build(), executionOptions);
144            dataCarrierService.removeData(borrowerId+itemId);
145            List<String> errorMessage = (List<String>) engineResult.getAttribute(OLEConstants.ERROR_ACTION);
146            StringBuffer failures = new StringBuffer();
147            if (errorMessage != null && errorMessage.size() > 0) {
148                int i = 1;
149                for (String errMsg : errorMessage) {
150                    failures.append(i++ + ". " + errMsg + OLEConstants.BREAK);
151                }
152            }
153            if (!failures.toString().isEmpty()) {
154                GlobalVariables.getMessageMap().putError("Error", failures.toString());
155
156            }
157
158        }
159        return engineResult;  //To change body of implemented methods use File | Settings | File Templates.
160    }
161
162
163    /**
164     * This method returns ElementValue using docContent and xpathExpression..
165     *
166     * @param docContent
167     * @param xpathExpression
168     * @return value
169     */
170    private String getElementValue(String docContent, String xpathExpression) {
171        try {
172            Document document = XmlHelper.trimXml(new ByteArrayInputStream(docContent.getBytes()));
173
174            XPath xpath = XPathHelper.newXPath();
175            String value = (String) xpath.evaluate(xpathExpression, document, XPathConstants.STRING);
176
177            return value;
178
179        } catch (Exception e) {
180            LOG.error("Exception", e);
181            throw new RiceRuntimeException();
182        }
183    }
184
185    /**
186     * This method returns SelectionContext using contextName.
187     *
188     * @param contextName
189     * @return Map
190     */
191    protected Map<String, String> getSelectionContext(String contextName) {
192        Map<String, String> selector = new HashMap<String, String>();
193        selector.put(OLEConstants.NAMESPACE_CODE, OLEConstants.OLE_NAMESPACE);
194        selector.put(OLEConstants.NAME, contextName);
195        return selector;
196    }
197
198    /**
199     * This method returns AgendaContext using agendaName..
200     *
201     * @param agendaName
202     * @return Map
203     */
204    protected Map<String, String> getAgendaContext(String agendaName) {
205        Map<String, String> selector = new HashMap<String, String>();
206        selector.put(OLEConstants.NAME, agendaName);
207        return selector;
208    }
209
210
211    private void populateRequestList(String requestTypeId, String itemId) {
212
213
214    }
215
216
217}