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
43
44
45
46
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
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
77
78
79 String id = null;
80
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
94
95
96
97
98
99
100
101
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
116
117 importBibForm.getImportBibConfirmReplace().setOverLayMarcRecord(bib);
118 setUuidToNewMarcRecord(newMarcRecord, importBibForm.getUuid());
119
120 BibMarcRecord newBibMarcRec = applyUserPrefToMarcRecord(existingMarcRecord, userPref,
121 newMarcRecord);
122 importBibForm.setExistingBibMarcRecord(newBibMarcRec);
123 } else {
124 applyUserPrefToMarcRecord(null, userPref, newMarcRecord);
125
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
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
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
181 OleHoldings newHolding = new WorkInstanceOlemlForm().getSelectedHolding();
182 newHolding.setCallNumber(callNumber);
183 newHolding.setLocation(getLocation(userPref.getPermLocation()));
184
185
186
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
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
263 applyProtectedNRemovalTags(removalTags, isProtected, existingMarcRecord, newMarcRec);
264 isProtected = true;
265
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
289 List<DataField> dataFields = getProtectedTagFromExisting(existingMarcRecord, dataFieldPref);
290 if (dataFields != null && dataFields.size() > 0) {
291
292 removeProtectedTag(newMarcRec, dataFieldPref);
293
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
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
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
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 }