View Javadoc
1   package org.kuali.ole.describe.service;
2   
3   import org.apache.commons.collections.comparators.NullComparator;
4   import org.apache.commons.lang.StringUtils;
5   import org.kuali.ole.OLEConstants;
6   import org.kuali.ole.describe.bo.BibDocumentSearchResult;
7   import org.kuali.ole.describe.bo.OleBibliographicRecordStatus;
8   import org.kuali.ole.describe.bo.OleShelvingScheme;
9   import org.kuali.ole.describe.bo.ImportBibUserPreferences;
10  import org.kuali.ole.describe.form.ImportBibForm;
11  import org.kuali.ole.describe.form.WorkInstanceOlemlForm;
12  import org.kuali.ole.docstore.common.client.DocstoreClientLocator;
13  import org.kuali.ole.docstore.common.document.*;
14  import org.kuali.ole.docstore.common.document.HoldingsTree;
15  import org.kuali.ole.docstore.common.document.content.bib.marc.*;
16  import org.kuali.ole.docstore.common.document.content.bib.marc.xstream.BibMarcRecordProcessor;
17  import org.kuali.ole.docstore.common.document.content.enums.DocCategory;
18  import org.kuali.ole.docstore.common.document.content.enums.DocFormat;
19  import org.kuali.ole.docstore.common.document.content.enums.DocType;
20  import org.kuali.ole.docstore.common.document.content.instance.*;
21  import org.kuali.ole.docstore.common.document.content.instance.Item;
22  import org.kuali.ole.docstore.common.document.content.instance.Items;
23  import org.kuali.ole.docstore.common.document.content.instance.xstream.HoldingOlemlRecordProcessor;
24  import org.kuali.ole.docstore.common.document.content.instance.xstream.InstanceOlemlRecordProcessor;
25  import org.kuali.ole.docstore.common.document.content.instance.xstream.ItemOlemlRecordProcessor;
26  import org.kuali.ole.docstore.common.search.*;
27  import org.kuali.ole.docstore.model.xmlpojo.ingest.AdditionalAttributes;
28  import org.kuali.ole.docstore.model.xmlpojo.ingest.Content;
29  import org.kuali.ole.docstore.model.xmlpojo.ingest.Request;
30  import org.kuali.ole.docstore.model.xmlpojo.ingest.RequestDocument;
31  import org.kuali.ole.sys.context.SpringContext;
32  import org.kuali.rice.krad.service.BusinessObjectService;
33  import org.kuali.rice.krad.service.KRADServiceLocator;
34  import org.kuali.rice.krad.util.GlobalVariables;
35  
36  import java.text.SimpleDateFormat;
37  import java.util.*;
38  import java.util.regex.Matcher;
39  import java.util.regex.Pattern;
40  
41  /**
42   * Created with IntelliJ IDEA.
43   * User: PJ7789
44   * Date: 18/12/12
45   * Time: 6:50 PM
46   * To change this template use File | Settings | File Templates.
47   */
48  public class ImportBibService extends WorkBenchService implements Comparator<BibDocumentSearchResult> {
49  
50      private DocstoreClientLocator docstoreClientLocator;
51  
52      public DocstoreClientLocator getDocstoreClientLocator() {
53          if (null == docstoreClientLocator) {
54              return SpringContext.getBean(DocstoreClientLocator.class);
55          }
56          return docstoreClientLocator;
57      }
58  
59      public BibMarcRecordProcessor bibMarcRecordProcessor = new BibMarcRecordProcessor();
60  
61      public void applyUserPref(ImportBibForm importBibForm) throws Exception {
62          ImportBibUserPreferences userPref = importBibForm.getImportBibUserPreferences();
63          String cfNum = null;
64          if (userPref.getImportType().equalsIgnoreCase("overLayMatchPoint")) {
65              BibMarcRecord newMarcRecord = importBibForm.getNewBibMarcRecord();
66              // getting MatchPoint value from new marc record and setting existing uuid to control field 001.
67              if (newMarcRecord != null) {
68                  for (ControlField cf : newMarcRecord.getControlFields()) {
69                      if (cf != null && cf.getTag().equals("001")) {
70                          String cfVal = cf.getValue();
71                          cfNum = getNumber(cfVal);
72                          importBibForm.getImportBibConfirmReplace().setMatchPoint(cfNum);
73                          break;
74                      }
75                  }
76                  //getting matching existing marc record from solr
77                  /*DiscoveryHelperService disHelperService = new DiscoveryHelperService();
78                  List responseFromSOLR = disHelperService.getResponseFromSOLR("035a", cfNum);*/
79                  String id = null;
80                  // marc record id field
81                  SearchParams searchParams = buildSearchParams(cfNum);
82                  SearchResponse searchResponse = getDocstoreClientLocator().getDocstoreClient().search(searchParams);
83                  for(SearchResult searchResult : searchResponse.getSearchResults()){
84                      for(SearchResultField searchResultField : searchResult.getSearchResultFields()) {
85                          if(searchResultField.getDocType().equalsIgnoreCase(DocType.BIB.getCode())) {
86                              if(searchResultField.getFieldName().equalsIgnoreCase(OLEConstants.ID)) {
87                                  importBibForm.setUuid(searchResultField.getFieldValue());
88                                  break;
89                              }
90                          }
91                      }
92                  }
93                  /*for (Iterator iterator = responseFromSOLR.iterator(); iterator.hasNext(); ) {
94                      Map map = (Map) iterator.next();
95                      if (map.containsKey(OLEConstants.ID)) {
96                          id = (String) map.get(OLEConstants.ID);
97                          importBibForm.setUuid(id);
98                          break;
99                      }
100                 }*/
101                 // checkout marc record content from docstore
102                 BibMarcRecord existingMarcRecord = null;
103                 if (id != null && id.length() > 0) {
104                     Bib bib = getDocstoreClientLocator().getDocstoreClient().retrieveBib(id);
105                     String marcXml = bib.getContent();
106                     BibMarcRecords marcRecords = bibMarcRecordProcessor.fromXML(marcXml);
107 
108                     if (marcRecords != null && marcRecords.getRecords() != null
109                             && marcRecords.getRecords().size() > 0) {
110                         existingMarcRecord = marcRecords.getRecords().get(0);
111                         importBibForm.setExistingBibMarcRecord(existingMarcRecord);
112 
113                     }
114                     if (existingMarcRecord != null) {
115                         //converting the workbibmarc record to workbib marc document and setting that to display in confirm replace screen.
116                         //TODO : retrieve bib and set to overlay
117                         importBibForm.getImportBibConfirmReplace().setOverLayMarcRecord(bib);
118                         setUuidToNewMarcRecord(newMarcRecord, importBibForm.getUuid());
119                         //applying removal and protected tag settings for marc
120                         BibMarcRecord newBibMarcRec = applyUserPrefToMarcRecord(existingMarcRecord, userPref,
121                                 newMarcRecord);
122                         importBibForm.setExistingBibMarcRecord(newBibMarcRec);
123                     } else {
124                         applyUserPrefToMarcRecord(null, userPref, newMarcRecord);
125                         //applying user pref details to new instance
126                         applyUsePrefNewInstanceFile(newMarcRecord, userPref, importBibForm);
127                         importBibForm.setMessage("There is no record available with match point " + cfNum + " if you click on next, new import will be performed.");
128                     }
129 
130                 }
131             }
132         } else if (userPref.getImportType().equalsIgnoreCase("overLay")) {
133             BibMarcRecord newMarcRecord = importBibForm.getNewBibMarcRecord();
134             BibMarcRecord existingMarcRecord = importBibForm.getExistingBibMarcRecord();
135             setUuidToNewMarcRecord(newMarcRecord, importBibForm.getUuid());
136             BibMarcRecord newBibMarcRec = applyUserPrefToMarcRecord(existingMarcRecord, userPref, newMarcRecord);
137 //            applyUsePrefNewInstanceFile(newMarcRecord, userPref, importBibForm);
138             importBibForm.setExistingBibMarcRecord(newBibMarcRec);
139         } else if (userPref.getImportType().equalsIgnoreCase("newImport")) {
140             BibMarcRecord newMarcRecord = importBibForm.getNewBibMarcRecord();
141             applyUserPrefToMarcRecord(null, userPref, newMarcRecord);
142             applyUsePrefNewInstanceFile(newMarcRecord, userPref, importBibForm);
143         }
144     }
145 
146     private void setUuidToNewMarcRecord(BibMarcRecord newMarcRecord, String uuid) {
147         for (ControlField cf : newMarcRecord.getControlFields()) {
148             if (cf != null && cf.getTag().equals("001")) {
149                 cf.setValue(uuid);
150                 newMarcRecord.setControlFields(newMarcRecord.getControlFields());
151                 break;
152             }
153         }
154     }
155 
156     private void applyUsePrefNewInstanceFile(BibMarcRecord newMarcRecord, ImportBibUserPreferences userPref,
157                                              ImportBibForm importBibForm) {
158         String shelScheme = userPref.getShelvingScheme();
159         OleShelvingScheme shelvingScheme = new OleShelvingScheme();
160         if (shelScheme != null && shelScheme.length() > 0) {
161             BusinessObjectService businessObjectService = KRADServiceLocator.getBusinessObjectService();
162             Map parentCriteria = new HashMap();
163             parentCriteria.put("shelvingSchemeCode", shelScheme);
164             shelvingScheme = businessObjectService.findByPrimaryKey(OleShelvingScheme.class, parentCriteria);
165         }
166         List<String> callNumList = new ArrayList<String>();
167         callNumList.add(userPref.getCallNumberSource1());
168         callNumList.add(userPref.getCallNumberSource2());
169         callNumList.add(userPref.getCallNumberSource3());
170         String callVal = getCallNumberValue(newMarcRecord, callNumList);
171 
172         // creating new Instance
173         Instance newInstance = new Instance();
174         CallNumber callNumber = new CallNumber();
175         callNumber.setNumber(callVal);
176         ShelvingScheme shelveScheme = new ShelvingScheme();
177         shelveScheme.setCodeValue(shelvingScheme.getShelvingSchemeCode());
178         callNumber.setShelvingScheme(shelveScheme);
179 
180         // creating new holding
181         OleHoldings newHolding = new WorkInstanceOlemlForm().getSelectedHolding();
182         newHolding.setCallNumber(callNumber);
183         newHolding.setLocation(getLocation(userPref.getPermLocation()));
184 
185 
186         // creating new Item
187         Item newItem = new Item();
188         newItem.setLocation(getLocation(userPref.getTempLocation()));
189         if(newItem.getAccessInformation() == null) {
190             AccessInformation accessInformation = new AccessInformation();
191             Uri uri = new Uri();
192             uri.setValue("");
193             uri.setResolvable("");
194             accessInformation.setUri(uri);
195             newItem.setAccessInformation(accessInformation);
196         }
197         List<Item> itemList = new ArrayList<Item>();
198         itemList.add(newItem);
199         newInstance.setOleHoldings(newHolding);
200         Items items = new Items();
201         items.setItem(itemList);
202         newInstance.setItems(items);
203 
204         // creating new instance collection and setting that to form
205         InstanceCollection instanceCollection = new InstanceCollection();
206         List<Instance> instanceList = new ArrayList<Instance>();
207         instanceList.add(newInstance);
208         instanceCollection.setInstance(instanceList);
209         importBibForm.setNewInstanceCollection(instanceCollection);
210     }
211 
212     private Location getLocation(String location) {
213         Location locationObj = new Location();
214         if (location != null && location.length() > 0) {
215             String loc = location.substring(location.lastIndexOf("/") + 1, location.length());
216 
217             if (loc != null && loc.length() > 0) {
218                 BusinessObjectService businessObjectService = KRADServiceLocator.getBusinessObjectService();
219                 Map parentCriteria = new HashMap();
220                 parentCriteria.put("locationCode", loc);
221                 LocationLevel locationLevel = new LocationLevel();
222                 locationLevel.setName(location);
223                 locationObj.setLocationLevel(locationLevel);
224             }
225         }
226         return locationObj;
227     }
228 
229     private String getCallNumberValue(BibMarcRecord newMarcRecord, List<String> callNumList) {
230         String callVal = null;
231         for (String callNum : callNumList) {
232             if (callNum != null && callNum.length() > 0) {
233                 for (DataField df : newMarcRecord.getDataFields()) {
234                     if (df.getTag().equalsIgnoreCase(callNum)) {
235                         for (SubField subF : df.getSubFields()) {
236                             if (callVal == null) {
237                                 callVal = subF.getValue();
238                             } else {
239                                 callVal = callVal + " " + subF.getValue();
240                             }
241                         }
242                         return callVal.trim();
243                     }
244 
245                 }
246             }
247         }
248         if (callVal == null) {
249             callVal = "";
250         }
251         return callVal;
252     }
253 
254     private BibMarcRecord applyUserPrefToMarcRecord(BibMarcRecord existingMarcRecord,
255                                                         ImportBibUserPreferences userPref,
256                                                         BibMarcRecord newMarcRec) {
257         String adminProtectedTags = userPref.getAdminProtectedTags();
258         String protectedTags = adminProtectedTags + "," + userPref.getProtectedTags();
259         String adminRemovalTags = userPref.getAdminRemovalTags();
260         String removalTags = adminRemovalTags + "," + userPref.getRemovalTags();
261         boolean isProtected = false;
262         //applying removalFields
263         applyProtectedNRemovalTags(removalTags, isProtected, existingMarcRecord, newMarcRec);
264         isProtected = true;
265         // applying protectedFields
266         applyProtectedNRemovalTags(protectedTags, isProtected, existingMarcRecord, newMarcRec);
267         return newMarcRec;
268     }
269 
270     private void applyProtectedNRemovalTags(String protectedTags, boolean isProtected,
271                                             BibMarcRecord existingMarcRecord, BibMarcRecord newMarcRec) {
272         String str[] = protectedTags.split(",");
273         for (int i = 0; i < str.length; i++) {
274             String field = str[i];
275             if (field != null && field.length() >= 3) {
276                 String dataFieldPref = field.substring(0, 3);
277                 if (dataFieldPref != null && newMarcRec != null) {
278                     applyDataFieldPref(dataFieldPref, existingMarcRecord, newMarcRec, isProtected);
279                 }
280             }
281         }
282     }
283 
284     private void applyDataFieldPref(String dataFieldPref, BibMarcRecord existingMarcRecord,
285                                     BibMarcRecord newMarcRec, boolean isProtected) {
286         DataField dataField = null;
287         if (isProtected && existingMarcRecord != null) {
288             //get protected existing dataField from Existing Marc Record
289             List<DataField> dataFields = getProtectedTagFromExisting(existingMarcRecord, dataFieldPref);
290             if (dataFields != null && dataFields.size() > 0) {
291                 //remove protected dataField from new Marc Record if existing
292                 removeProtectedTag(newMarcRec, dataFieldPref);
293                 //add existing protected dataField to new Marc record
294                 for (DataField df : dataFields) {
295                     newMarcRec.getDataFields().add(df);
296                 }
297             }
298         } else if (!isProtected) {
299             removeProtectedTag(newMarcRec, dataFieldPref);
300         }
301     }
302 
303 
304     private void removeProtectedTag(BibMarcRecord newMarcRecord, String dataFieldPref) {
305         List<DataField> dfList = new ArrayList<DataField>();
306         dfList.addAll(newMarcRecord.getDataFields());
307         // remove the protected dataField in New Marc record if existing
308         for (DataField newDataField : newMarcRecord.getDataFields()) {
309             if (newDataField.getTag().equals(dataFieldPref)) {
310                 dfList.remove(newDataField);
311             }
312         }
313         newMarcRecord.setDataFields(dfList);
314     }
315 
316     private List<DataField> getProtectedTagFromExisting(BibMarcRecord existingMarcRecord, String dataFieldPref) {
317         List<DataField> dataFieldList = new ArrayList<DataField>();
318         for (DataField dfExisting : existingMarcRecord.getDataFields()) {
319             if (dfExisting.getTag().equals(dataFieldPref)) {
320                 dataFieldList.add(dfExisting);
321             }
322         }
323         return dataFieldList;
324     }
325 
326     public String getNumber(String str) {
327         String val = "";
328         Pattern p = Pattern.compile("\\d+");
329         Matcher m = p.matcher(str);
330         while (m.find()) {
331             val = m.group();
332             return val;
333         }
334         return val;
335     }
336 
337     public boolean callNumValidation(ImportBibUserPreferences userPreferences) {
338         boolean isValid = false;
339         List<String> callNumbers = new ArrayList<String>();
340         callNumbers.add(userPreferences.getCallNumberSource1());
341         callNumbers.add(userPreferences.getCallNumberSource2());
342         callNumbers.add(userPreferences.getCallNumberSource3());
343         for (String callNum : callNumbers) {
344             if (callNum != null && callNum.length() > 0) {
345                 isValid = true;
346                 if (callNum.length() == 3 && getValidNumber(callNum)) {
347                     isValid = false;
348                 } else {
349                     return isValid;
350                 }
351             }
352         }
353         return isValid;
354     }
355 
356     public boolean proNRemTagValidation(ImportBibUserPreferences userPreferences) {
357         boolean isValid = false;
358         String tags = userPreferences.getProtectedTags() + "," + userPreferences.getRemovalTags();
359         String str[] = tags.split(",");
360         for (int i = 0; i < str.length; i++) {
361             String field = str[i];
362             if (field != null && field.length() > 0) {
363                 isValid = true;
364                 if (field.length() == 3 && getValidNumber(field)) {
365                     isValid = false;
366                 } else {
367                     return isValid;
368                 }
369             }
370         }
371 
372         return isValid;
373     }
374 
375 
376     public boolean getValidNumber(String str) {
377         Pattern p = Pattern.compile("\\d{3}");
378         Matcher m = p.matcher(str);
379         while (m.find()) {
380             return true;
381         }
382         return false;
383     }
384 
385 
386     public Request buildRequest(BibMarcRecord newWorkBibMarcRecord, InstanceCollection newWorkInstanceOlemlRecord, String status) {
387         Request req = new Request();
388         String user = GlobalVariables.getUserSession().getPrincipalName();
389         req.setUser(user);
390         req.setOperation("ingest");
391         if (newWorkBibMarcRecord != null) {
392             // build marc request document
393             List<BibMarcRecord> marcRecList = new ArrayList<BibMarcRecord>();
394             marcRecList.add(newWorkBibMarcRecord);
395             BibMarcRecords marcRecords = new BibMarcRecords();
396             marcRecords.setRecords(marcRecList);
397             String marcContent = bibMarcRecordProcessor.toXml(marcRecords);
398             RequestDocument reqDoc = new RequestDocument();
399             buildRequestDoc("work", "bibliographic", "marc", marcContent, reqDoc, status);
400             //build Instance request document
401             if (newWorkInstanceOlemlRecord != null) {
402                 InstanceOlemlRecordProcessor instanceProcessor = new InstanceOlemlRecordProcessor();
403                 String instContent = instanceProcessor.toXML(newWorkInstanceOlemlRecord);
404                 RequestDocument instDoc = new RequestDocument();
405                 buildRequestDoc("work", "instance", "oleml", instContent, instDoc, null);
406                 List<RequestDocument> linkedRequestDocumentList = new ArrayList<RequestDocument>();
407                 linkedRequestDocumentList.add(instDoc);
408                 reqDoc.setLinkedRequestDocuments(linkedRequestDocumentList);
409             }
410             List<RequestDocument> requestDocumentList = new ArrayList<RequestDocument>();
411             requestDocumentList.add(reqDoc);
412             req.setRequestDocuments(requestDocumentList);
413         }
414         return req;
415     }
416 
417     private void buildRequestDoc(String cat, String type, String format, String content, RequestDocument reqDoc, String status) {
418         reqDoc.setId("1");
419         reqDoc.setCategory(cat);
420         reqDoc.setType(type);
421         reqDoc.setFormat(format);
422         Content contentObj = new Content();
423         contentObj.setContent(content);
424         reqDoc.setContent(contentObj);
425         if (status != null) {
426             Date date = new Date();
427             SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
428             String dateStr = sdf.format(date);
429             String user = null;
430             if (GlobalVariables.getUserSession() != null && GlobalVariables.getUserSession().getLoggedInUserPrincipalName() != null) {
431                 user = GlobalVariables.getUserSession().getLoggedInUserPrincipalName();
432             }
433             AdditionalAttributes additionalAttributes = new AdditionalAttributes();
434             BusinessObjectService boService = KRADServiceLocator.getBusinessObjectService();
435             additionalAttributes.setAttribute(AdditionalAttributes.DATE_ENTERED, dateStr);
436             additionalAttributes.setAttribute(AdditionalAttributes.CREATED_BY, user);
437             Map parentCriteria = new HashMap();
438             parentCriteria.put("bibliographicRecordStatusCode", status);
439             OleBibliographicRecordStatus bibliographicRecordStatus = boService
440                     .findByPrimaryKey(OleBibliographicRecordStatus.class, parentCriteria);
441             if (bibliographicRecordStatus != null) {
442                 additionalAttributes.setAttribute(AdditionalAttributes.STATUS,
443                         bibliographicRecordStatus.getBibliographicRecordStatusName());
444             } else {
445                 additionalAttributes.setAttribute(AdditionalAttributes.STATUS, "");
446             }
447             reqDoc.setAdditionalAttributes(additionalAttributes);
448         }
449     }
450 
451     @Override
452     public int compare(BibDocumentSearchResult o1, BibDocumentSearchResult o2) {
453         if (o1.getTitle() == null && o2.getTitle() == null) {
454             return 0;
455         }
456         if (o1.getTitle() == null) {
457             return 1;
458         }
459         if (o2.getTitle() == null) {
460             return -1;
461         }
462         return delegate.compare(o1.getTitle(), o2.getTitle());
463     }
464 
465     private NullComparator delegate = new NullComparator(false);
466 
467     public BibTree createBibTree(BibMarcRecord newBibMarcRecord, InstanceCollection newInstanceCollection, String importStatus) {
468         BibTree bibTree = new BibTree();
469         Bib bib = new BibMarc();
470 
471 
472         BibMarcRecords bibMarcRecords=new BibMarcRecords();
473         List<BibMarcRecord> bibMarcRecordList=new ArrayList<>();
474         bibMarcRecordList.add(newBibMarcRecord);
475 
476         bibMarcRecords.setRecords(bibMarcRecordList);
477         BibMarcRecordProcessor bibMarcRecordProcessor=new BibMarcRecordProcessor();
478 
479         bib.setCategory(DocCategory.WORK.getCode());
480         bib.setType(DocType.BIB.getCode());
481         bib.setFormat(DocFormat.MARC.getCode());
482         bib.setContent(bibMarcRecordProcessor.toXml(bibMarcRecords));
483 
484         ItemOlemlRecordProcessor itemOlemlRecordProcessor=new ItemOlemlRecordProcessor();
485         HoldingOlemlRecordProcessor holdingOlemlRecordProcessor = new HoldingOlemlRecordProcessor();
486 
487         org.kuali.ole.docstore.common.document.Item itemOleml=new ItemOleml();
488         if(newInstanceCollection != null && newInstanceCollection.getInstance() != null && newInstanceCollection.getInstance().size() > 0) {
489             OleHoldings oleHoldings = newInstanceCollection.getInstance().get(0).getOleHoldings();
490             Item item = newInstanceCollection.getInstance().get(0).getItems().getItem().get(0);
491             itemOleml.setContent(itemOlemlRecordProcessor.toXML(item));
492             Holdings holdings = new PHoldings();
493             holdings.setContent(holdingOlemlRecordProcessor.toXML(oleHoldings));
494 
495             HoldingsTree holdingsTree=new HoldingsTree();
496 
497             holdingsTree.setHoldings(holdings);
498             holdingsTree.getItems().add(itemOleml);
499             bibTree.getHoldingsTrees().add(holdingsTree);
500         }
501         bibTree.setBib(bib);
502         return bibTree;
503     }
504 
505     private SearchParams buildSearchParams(String cfn) {
506         SearchParams searchParams = new SearchParams();
507         List<SearchCondition>  searchConditions = new ArrayList<>();
508         if(StringUtils.isNotEmpty(cfn)) {
509             searchConditions.add(searchParams.buildSearchCondition("AND", searchParams.buildSearchField(DocType.BIB.getCode(), "035a", cfn), "AND"));
510         }
511         searchParams.getSearchResultFields().add(searchParams.buildSearchResultField(DocType.BIB.getCode(),OLEConstants.ID));
512         return searchParams;
513     }
514 }