View Javadoc

1   package org.kuali.ole.ingest;
2   
3   import org.kuali.ole.BibliographicRecordHandler;
4   import org.kuali.ole.DataCarrierService;
5   import org.kuali.ole.OLEConstants;
6   import org.kuali.ole.OLETranscationalRecordGenerator;
7   import org.kuali.ole.ingest.pojo.IngestRecord;
8   import org.kuali.ole.ingest.pojo.MatchBo;
9   import org.kuali.ole.ingest.pojo.ProfileAttributeBo;
10  import org.kuali.ole.ingest.pojo.ProfileTerm;
11  import org.kuali.ole.pojo.OleBibRecord;
12  import org.kuali.ole.pojo.OleOrderRecord;
13  import org.kuali.ole.pojo.OleTxRecord;
14  import org.kuali.ole.pojo.bib.BibliographicRecord;
15  import org.kuali.ole.pojo.bib.Collection;
16  import org.kuali.ole.pojo.edi.EDIOrder;
17  import org.kuali.ole.pojo.edi.EDIOrders;
18  import org.kuali.ole.pojo.edi.LineItemOrder;
19  import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
20  import org.kuali.rice.krad.service.BusinessObjectService;
21  import org.kuali.rice.krad.service.KRADServiceLocator;
22  import org.kuali.rice.krms.api.KrmsApiServiceLocator;
23  import org.kuali.rice.krms.api.engine.*;
24  import org.kuali.rice.krms.impl.repository.AgendaBo;
25  import org.xml.sax.SAXException;
26  
27  import javax.xml.parsers.ParserConfigurationException;
28  import javax.xml.xpath.XPathExpressionException;
29  import java.io.IOException;
30  import java.net.URISyntaxException;
31  import java.util.*;
32  
33  /**
34   * AbstractIngestProcessor which does the pre-processing for Staff Upload process to create Requisition.
35   */
36  public abstract class AbstractIngestProcessor {
37      private static final String NAMESPACE_CODE_SELECTOR = "namespaceCode";
38      private static final String NAME_SELECTOR = "name";
39      private BusinessObjectService businessObjectService;
40      private List<EngineResults> engineResults = new ArrayList<EngineResults>();
41  
42      String marcXMLContent;
43      String ediXMLContent;
44      private IngestRecord ingestRecord;
45  
46      /**
47       *  Gets the engineResults attribute.
48       * @return engineResults
49       */
50  
51      public List<EngineResults> getEngineResults() {
52          return engineResults;
53      }
54  
55      /**
56       *   This method takes the initial request when Ingesting a record.
57       * @param ingestRecord
58       */
59  
60      public void start(IngestRecord ingestRecord) {
61          this.ingestRecord = ingestRecord;
62  
63          byPassLogicForPreProcess(ingestRecord.getMarcFileContent(), ingestRecord.getEdiFileContent(), ingestRecord.getByPassPreProcessing());
64          try {
65              process();
66          } catch (URISyntaxException e) {
67              System.out.println(e.getMessage());
68          } catch (IOException e) {
69              System.out.println(e.getMessage());
70          } catch (SAXException e) {
71              System.out.println(e.getMessage());
72          } catch (XPathExpressionException e) {
73              System.out.println(e.getMessage());
74          } catch (ParserConfigurationException e) {
75              System.out.println(e.getMessage());
76          } catch (InterruptedException e) {
77              System.out.println(e.getMessage());
78          }
79          postProcess();
80      }
81  
82      /**
83       * This method forwards to preProcess method if preProcessReq is true else sets the marcXmlContent and ediXmlContent.
84       * @param rawMarcContent
85       * @param rawEdiContent
86       * @param preProcessingReq
87       */
88      private void byPassLogicForPreProcess(String rawMarcContent, String rawEdiContent, boolean preProcessingReq) {
89          if (preProcessingReq) {
90              preProcess(rawMarcContent, rawEdiContent);
91          } else {
92              marcXMLContent = rawMarcContent;
93              ediXMLContent = rawEdiContent;
94          }
95      }
96  
97      /**
98       *   This method forwards to preProcessMarc and preProcessEDI method.
99       * @param rawMarcContent
100      * @param rawEdiContent
101      */
102     private void preProcess(String rawMarcContent, String rawEdiContent) {
103         marcXMLContent = preProcessMarc(rawMarcContent);
104         ediXMLContent = preProcessEDI(rawEdiContent);
105     }
106 
107     /**
108      *  This method starts the process for marcXmlContent and ediXmlContent.
109      * @throws URISyntaxException
110      * @throws IOException
111      * @throws SAXException
112      * @throws XPathExpressionException
113      * @throws ParserConfigurationException
114      * @throws InterruptedException
115      */
116     public void process() throws URISyntaxException, IOException, SAXException, XPathExpressionException, ParserConfigurationException, InterruptedException {
117         Engine engine = KrmsApiServiceLocator.getEngine();
118 
119         HashMap<String, String> map = new HashMap<String, String>();
120         map.put("AGENDA_NAME", ingestRecord.getAgendaName());
121         List<MatchBo> matchBos = (List<MatchBo>) getBusinessObjectService().findMatching(MatchBo.class, map);
122 
123         HashMap<String, Object> agendaValue = new HashMap<String, Object>();
124         agendaValue.put("nm", ingestRecord.getAgendaName());
125         List<AgendaBo> agendaBos = (List<AgendaBo>) getBusinessObjectService().findMatching(AgendaBo.class, agendaValue);
126         AgendaBo agendaBo = agendaBos.get(0);
127 
128         SelectionCriteria selectionCriteria =
129                 SelectionCriteria.createCriteria(null, getSelectionContext(agendaBo.getContext().getName()), getAgendaContext(ingestRecord.getAgendaName()));
130 
131         ExecutionOptions executionOptions = new ExecutionOptions();
132         executionOptions.setFlag(ExecutionFlag.LOG_EXECUTION, true);
133 
134         OLETranscationalRecordGenerator oleTranscationalRecordGenerator = new OLETranscationalRecordGenerator();
135         EDIOrders ediOrders = oleTranscationalRecordGenerator.fromXml(ediXMLContent);
136 
137         BibliographicRecordHandler bibliographicRecordHandler = new BibliographicRecordHandler();
138         Collection bibliographicRecords = bibliographicRecordHandler.fromXML(marcXMLContent);
139 
140         List<BibliographicRecord> records = bibliographicRecords.getRecords();
141 
142         List<ProfileAttributeBo> profileAttributeBos = getProfileAttributeBos(ingestRecord.getAgendaName());
143 
144         EDIOrder ediOrder = ediOrders.getOrders().get(0);
145         //TODO: Removing this validation as need to fix in OLE_Rice1.0-from load summary if re-ingested
146         //TODO: the num of marc and edi files may not match as the edi order is a whole and needs to be broken
147         //TODO: into one marc to one line item order and not one marc to one edi order.
148         // if (isNumMarcMatchingNumEdiRecords(ediOrder, records)) {
149         for (Iterator<BibliographicRecord> iterator = records.iterator(); iterator.hasNext(); ) {
150             BibliographicRecord bibliographicRecord = iterator.next();
151             String singleMarcXML = bibliographicRecordHandler.generateXML(bibliographicRecord);
152             Map<String, String> valuesMap = bibliographicRecordHandler.valuesMapFromXML(singleMarcXML);
153 
154             Facts.Builder factBuilder = Facts.Builder.create();
155             for (Iterator<MatchBo> matchBoIterator = matchBos.iterator(); matchBoIterator.hasNext(); ) {
156                 MatchBo matchBo = matchBoIterator.next();
157                 ProfileTerm term = new ProfileTerm();
158                 term.setIncomingField(valuesMap.get(matchBo.getIncomingField()));
159                 term.setExistingField(matchBo.getExistingField());
160                 factBuilder.addFact(matchBo.getTermName(), term);
161             }
162 
163             DataCarrierService dataCarrierService = GlobalResourceLoader.getService(OLEConstants.DATA_CARRIER_SERVICE);
164             dataCarrierService.addData(OLEConstants.REQUEST_BIB_RECORD, bibliographicRecord);
165             dataCarrierService.addData(OLEConstants.PROFILE_ATTRIBUTE_LIST, profileAttributeBos);
166 
167             EngineResults engineResult = engine.execute(selectionCriteria, factBuilder.build(), executionOptions);
168             OleBibRecord oleBibRecord = (OleBibRecord) engineResult.getAttribute(OLEConstants.OLE_BIB_RECORD);
169             OleOrderRecord oleOrderRecord = new OleOrderRecord();
170             oleOrderRecord.setAgendaName(ingestRecord.getAgendaName());
171             oleOrderRecord.setOleOriginalBibRecordFileName(ingestRecord.getOriginalMarcFileName());
172             oleOrderRecord.setOriginalEDIFileName(ingestRecord.getOriginalEdiFileName());
173             oleOrderRecord.setOriginalRecord(bibliographicRecord);
174             oleOrderRecord.setDescription(ingestRecord.getAgendaDescription());
175             oleOrderRecord.setOriginalEdi(ediOrder);
176 
177             if (null != oleBibRecord) {
178                 oleOrderRecord.setOleBibRecord(oleBibRecord);
179                 OleTxRecord oleTxRecord = getMatchingTxRecord(ediOrder, bibliographicRecord, profileAttributeBos);
180                 oleOrderRecord.setOleTxRecord(oleTxRecord);
181             }
182             List<ResultEvent> allResults = engineResult.getAllResults();
183             for (Iterator<ResultEvent> resultEventIterator = allResults.iterator(); resultEventIterator.hasNext(); ) {
184                 ResultEvent resultEvent = resultEventIterator.next();
185                 String ruleEvaluated = null;
186                 if (resultEvent.getType().equals("Rule Evaluated")) {
187                     ruleEvaluated = resultEvent.getSource() + " : " + resultEvent.getResult();
188                     List rulesEvaluatedList = (List) oleOrderRecord.getMessageMap().get("rulesEvaluated");
189                     if (null == rulesEvaluatedList) {
190                         rulesEvaluatedList = new ArrayList();
191                     }
192                     rulesEvaluatedList.add(ruleEvaluated);
193                     oleOrderRecord.addMessageToMap("rulesEvaluated", rulesEvaluatedList);
194                 }
195             }
196             engineResult.setAttribute(OLEConstants.OLE_ORDER_RECORD, oleOrderRecord);
197             engineResults.add(engineResult);
198         }
199         //} else {
200 //        EngineResultsImpl exceptionResult = new EngineResultsImpl();
201 //        exceptionResult.setAttribute(OLEConstants.OLE_ORDER_RECORD, null);
202 //        engineResults.add(exceptionResult);
203         // }
204     }
205 
206     /**
207      *  This method checks the size of marc record  and edi record, if it is equal it will return true otherwise return false.
208      * @param ediOrder
209      * @param records
210      * @return   boolean
211      */
212     private boolean isNumMarcMatchingNumEdiRecords(EDIOrder ediOrder, List<BibliographicRecord> records) {
213         return records.size() == ediOrder.getLineItemOrder().size();
214     }
215 
216     /**
217      *  This method returns Vendor Profile code based on profileAttributeBo.
218      * @param profileAttributeBo
219      * @return   attributeValue.
220      */
221     private String getVendorProfileCode(List<ProfileAttributeBo> profileAttributeBo) {
222         for (Iterator<ProfileAttributeBo> iterator = profileAttributeBo.iterator(); iterator.hasNext(); ) {
223             ProfileAttributeBo attributeBo = iterator.next();
224             if (attributeBo.getAttributeName().equals(OLEConstants.VENDOR_PROFILE_CODE)) {
225                 return attributeBo.getAttributeValue();
226             }
227         }
228         return null;
229     }
230 
231     /**
232      *  This method gets the ProfileAttributeBos based on agendaName.
233      * @param agendaName
234      * @return  matching
235      */
236     public List<ProfileAttributeBo> getProfileAttributeBos(String agendaName) {
237         HashMap map = new HashMap();
238         map.put("agenda_name", agendaName);
239         List<ProfileAttributeBo> matching = (List<ProfileAttributeBo>) getBusinessObjectService().findMatching(ProfileAttributeBo.class, map);
240         return matching;
241     }
242 
243     /**
244      * This method gets the oleTxRecord based on lineItemOrder,ediOrder.
245      * @param ediOrder
246      * @param bibliographicRecord
247      * @param profileAttributeBos
248      * @return  oleTxRecord
249      */
250     private OleTxRecord getMatchingTxRecord(EDIOrder ediOrder, BibliographicRecord bibliographicRecord, List<ProfileAttributeBo> profileAttributeBos) {
251         LineItemOrderMatcherForBib lineItemOrderMatcherForBib = new LineItemOrderMatcherForBib();
252         LineItemOrder lineItemOrder = lineItemOrderMatcherForBib.getLineItemOrder(ediOrder.getLineItemOrder(), bibliographicRecord, getVendorProfileCode(profileAttributeBos));
253         OleTxRecord oleTxRecord = OleTxRecordBuilder.getInstance().build(lineItemOrder, profileAttributeBos, ediOrder);
254         return oleTxRecord;
255     }
256 
257     /**
258      *  Gets the instance of businessObjectService.
259      *  if businessObjectService is null it will create a new instance else it will return existing businessObjectService.
260      * @return  businessObjectService
261      */
262     private BusinessObjectService getBusinessObjectService() {
263         if (null == businessObjectService) {
264             businessObjectService = KRADServiceLocator.getBusinessObjectService();
265         }
266         return businessObjectService;
267     }
268 
269     /**
270      *  This method returns selector map contains OLE code  and contextName.
271      * @param contextName
272      * @return  selector
273      */
274     protected Map<String, String> getSelectionContext(String contextName) {
275         Map<String, String> selector = new HashMap<String, String>();
276         selector.put(NAMESPACE_CODE_SELECTOR, "OLE");
277         selector.put(NAME_SELECTOR, contextName);
278         return selector;
279     }
280 
281     /**
282      *   This method returns selector map contains agendaName
283      * @param agendaName
284      * @return  selector
285      */
286     protected Map<String, String> getAgendaContext(String agendaName) {
287         Map<String, String> selector = new HashMap<String, String>();
288         selector.put(NAME_SELECTOR, agendaName);
289         return selector;
290     }
291 
292     public abstract String preProcessMarc(String marcFileContent);
293 
294     public abstract String preProcessEDI(String ediFileContent);
295 
296     public abstract void postProcess();
297 
298 }