1 package org.kuali.ole.docstore.engine.service.index.solr;
2
3 import org.apache.commons.collections.CollectionUtils;
4 import org.apache.commons.lang.StringUtils;
5 import org.apache.solr.client.solrj.SolrQuery;
6 import org.apache.solr.client.solrj.SolrServer;
7 import org.apache.solr.client.solrj.SolrServerException;
8 import org.apache.solr.client.solrj.response.QueryResponse;
9 import org.apache.solr.client.solrj.response.UpdateResponse;
10 import org.apache.solr.common.SolrDocument;
11 import org.apache.solr.common.SolrInputDocument;
12 import org.kuali.ole.docstore.OleException;
13 import org.kuali.ole.docstore.common.constants.DocstoreConstants;
14 import org.kuali.ole.docstore.common.document.*;
15 import org.kuali.ole.docstore.common.document.config.DocumentSearchConfig;
16 import org.kuali.ole.docstore.common.document.content.bib.marc.*;
17 import org.kuali.ole.docstore.common.document.content.bib.marc.xstream.BibMarcRecordProcessor;
18 import org.kuali.ole.docstore.common.exception.DocstoreIndexException;
19 import org.kuali.ole.docstore.common.util.ReindexBatchStatistics;
20 import org.kuali.ole.docstore.discovery.service.SolrServerManager;
21 import org.kuali.ole.docstore.indexer.solr.DocumentLocalId;
22 import org.kuali.ole.docstore.model.enums.DocCategory;
23 import org.kuali.ole.docstore.model.enums.DocFormat;
24 import org.kuali.ole.docstore.model.enums.DocType;
25 import org.kuali.ole.docstore.utility.ISBNUtil;
26 import org.kuali.ole.utility.Constants;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29 import org.springframework.util.StopWatch;
30
31 import java.io.IOException;
32 import java.text.DateFormat;
33 import java.text.Normalizer;
34 import java.text.ParseException;
35 import java.text.SimpleDateFormat;
36 import java.util.*;
37 import java.util.regex.Matcher;
38 import java.util.regex.Pattern;
39
40
41
42
43
44
45
46
47 public class BibMarcIndexer extends DocstoreSolrIndexService implements DocstoreConstants {
48
49
50
51
52 private static final String SEPERATOR_DATA_FIELD = ", ";
53 private static final String SEPERATOR_SUB_FIELD = " ";
54 private static final String PATTERN_CHAR = "*";
55 private static final String SEPERATOR_HYPHEN = " - ";
56 private static final String SEPERATOR_DOUBLE_HYPHEN = " -- ";
57 private static final String DYNAMIC_FIELD_PREFIX = "mdf_";
58 private static final String BIB_IDENTIFIER = "bibIdentifier";
59 private static final String HOLDINGS_IDENTIFIER = "holdingsIdentifier";
60 private static final String ITEM_IDENTIFIER = "itemIdentifier";
61 private String publicationDateRegex = "[0-9]{4}";
62 private static final Logger LOG = LoggerFactory
63 .getLogger(BibMarcIndexer.class);
64
65 private static BibMarcIndexer bibMarcIndexer = null;
66
67 public static BibMarcRecordProcessor recordProcessor = new BibMarcRecordProcessor();
68 private static DocumentSearchConfig documentSearchConfig = null;
69
70
71
72
73
74
75
76 public static BibMarcIndexer getInstance() {
77 if (bibMarcIndexer == null) {
78 bibMarcIndexer = new BibMarcIndexer();
79 }
80 documentSearchConfig = DocumentSearchConfig.getDocumentSearchConfig();
81 return bibMarcIndexer;
82 }
83
84
85 @Override
86 public void createTree(Object object) {
87 List<SolrInputDocument> solrInputDocuments = new ArrayList<>();
88 buildSolrDocsForBibTree((BibTree) object, solrInputDocuments);
89 indexSolrDocuments(solrInputDocuments, true);
90 }
91
92
93
94
95
96
97
98 private void buildSolrDocsForBibTree(BibTree bibTree, List<SolrInputDocument> solrInputDocuments) {
99 Bib bib = bibTree.getBib();
100 if (bib.getId() != null && bib.getId().contains("wbm")) {
101 BibMarcRecords bibMarcRecords = recordProcessor.fromXML(bib.getContent());
102 SolrInputDocument bibSolrDoc = buildSolrInputDocument(bibMarcRecords.getRecords().get(0));
103 setCommonFields(bib, bibSolrDoc);
104 solrInputDocuments.add(bibSolrDoc);
105 for (HoldingsTree holdingsTree : bibTree.getHoldingsTrees()) {
106 if (holdingsTree.getHoldings() != null && holdingsTree.getHoldings().getOperation() != null && holdingsTree.getHoldings().getOperation().equals(DocstoreDocument.OperationType.NONE)) {
107 continue;
108 }
109 buildSolrDocsForHoldingsTree(solrInputDocuments, bib, bibSolrDoc, holdingsTree);
110 }
111 }
112 }
113
114
115
116
117
118
119
120
121
122
123 private void buildSolrDocsForHoldingsTree(List<SolrInputDocument> solrInputDocuments, Bib bib, SolrInputDocument bibSolrDoc, HoldingsTree holdingsTree) {
124 if (holdingsTree.getHoldings() != null) {
125 HoldingsOlemlIndexer holdingsOlemlIndexer = HoldingsOlemlIndexer.getInstance();
126 if (holdingsTree.getHoldings().getContent() != null || holdingsTree.getHoldings().getContentObject() != null) {
127 SolrInputDocument holdingsSolrInputDoc = holdingsOlemlIndexer.getSolrInputFieldsForHoldings(holdingsTree.getHoldings());
128 linkHoldingsWithBib(bibSolrDoc, holdingsSolrInputDoc, bib.getId(), solrInputDocuments, holdingsTree.getHoldings().getId());
129 holdingsSolrInputDoc.addField(BIB_IDENTIFIER, bib.getId());
130 List<Item> itemDocuments = holdingsTree.getItems();
131 List<String> itemIds = new ArrayList<String>();
132 holdingsSolrInputDoc.addField(ITEM_IDENTIFIER, itemIds);
133 ItemOlemlIndexer itemOlemlIndexer = ItemOlemlIndexer.getInstance();
134 addHoldingsInfoToBib(holdingsSolrInputDoc, bibSolrDoc);
135 for (Item itemDocument : itemDocuments) {
136 itemIds.add(itemDocument.getId());
137 SolrInputDocument itemSolrInputDoc = itemOlemlIndexer.getSolrInputFieldsForItem(itemDocument);
138 itemSolrInputDoc.addField(HOLDINGS_IDENTIFIER, holdingsTree.getHoldings().getId());
139 itemSolrInputDoc.addField(BIB_IDENTIFIER, bib.getId());
140 addBibInfoForHoldingsOrItems(itemSolrInputDoc, holdingsSolrInputDoc);
141 addHoldingsInfoToItem(itemSolrInputDoc, holdingsSolrInputDoc);
142 addItemInfoToBib(itemSolrInputDoc, bibSolrDoc);
143 solrInputDocuments.add(itemSolrInputDoc);
144 }
145
146 solrInputDocuments.add(holdingsSolrInputDoc);
147 } else if (StringUtils.isNotEmpty(holdingsTree.getHoldings().getId())) {
148 bibSolrDoc.addField(HOLDINGS_IDENTIFIER, "who-" + holdingsTree.getHoldings().getId());
149 }
150 }
151 }
152
153 private void linkHoldingsWithBib(SolrInputDocument bibSolrDoc, SolrInputDocument holdingsSolrInputDoc, String bibId, List<SolrInputDocument> solrInputDocuments, String holdingsId) {
154 if (bibSolrDoc == null) {
155 SolrDocument bibSolrDocument = getSolrDocumentByUUID(bibId);
156 bibSolrDoc = buildSolrInputDocFromSolrDoc(bibSolrDocument);
157 solrInputDocuments.add(bibSolrDoc);
158 }
159 bibSolrDoc.addField(HOLDINGS_IDENTIFIER, holdingsId);
160 addBibInfoForHoldingsOrItems(holdingsSolrInputDoc, bibSolrDoc);
161 }
162
163 @Override
164 public void createTrees(Object object) {
165 BibTrees bibTreesObj = (BibTrees) object;
166 List<BibTree> bibTrees = bibTreesObj.getBibTrees();
167 List<SolrInputDocument> solrInputDocuments = new ArrayList<>();
168 for (BibTree bibTree : bibTrees) {
169 buildSolrDocsForBibTree(bibTree, solrInputDocuments);
170 }
171
172 indexSolrDocuments(solrInputDocuments, true);
173 }
174
175
176
177
178
179
180
181 @Override
182 public void processBibTrees(BibTrees bibTrees) {
183 List<SolrInputDocument> solrInputDocuments = new ArrayList<>();
184 List<String> idsToDelete = new ArrayList<>();
185 for (BibTree bibTree : bibTrees.getBibTrees()) {
186 processBibTree(bibTree, solrInputDocuments, idsToDelete);
187 }
188 LOG.info("Solr Input Documents Size : " + solrInputDocuments.size());
189 indexAndDelete(solrInputDocuments, idsToDelete, true);
190 }
191
192
193
194
195
196
197
198
199 private void processBibTree(BibTree bibTree, List<SolrInputDocument> solrInputDocuments, List<String> idsToDelete) {
200 Bib bib = bibTree.getBib();
201 if (null != bib) {
202 SolrInputDocument bibSolrInputDocument = new SolrInputDocument();
203 if (Bib.ResultType.SUCCESS.equals(bib.getResult())) {
204 if (bib.getId() != null) {
205 if (Bib.OperationType.CREATE.equals(bib.getOperation())) {
206 createBibTreeDocforSolr(bibTree, solrInputDocuments);
207 } else if (Bib.OperationType.UPDATE.equals(bib.getOperation())) {
208 updateBibDocument(bib, solrInputDocuments, bibSolrInputDocument);
209 processHoldingsTrees(bibTree.getHoldingsTrees(), bibSolrInputDocument, solrInputDocuments, idsToDelete);
210 } else if (Bib.OperationType.DELETE.equals(bib.getOperation())) {
211 idsToDelete.add(bib.getId());
212 }
213 }
214 } else if (bib.getOperation() == null || StringUtils.isBlank(bib.getOperation().name())) {
215 processHoldingsTrees(bibTree.getHoldingsTrees(), bibSolrInputDocument, solrInputDocuments, idsToDelete);
216 }
217 }
218 }
219
220
221
222
223
224 private void createBibTreeDocforSolr(BibTree bibTree, List<SolrInputDocument> solrInputDocuments) {
225 buildSolrDocsForBibTree(bibTree, solrInputDocuments);
226 }
227
228
229
230
231
232
233
234 private void processHoldingsTrees(List<HoldingsTree> holdingsTrees, SolrInputDocument bibSolrInputDocument, List<SolrInputDocument> solrInputDocuments, List<String> idsToDelete) {
235 for (HoldingsTree holdingsTree : holdingsTrees) {
236 processHoldingsTree(holdingsTree, bibSolrInputDocument, solrInputDocuments, idsToDelete);
237 }
238 }
239
240
241
242
243
244
245
246
247
248
249 private void processHoldingsTree(HoldingsTree holdingsTree, SolrInputDocument bibSolrInputDocument, List<SolrInputDocument> solrInputDocuments, List<String> idsToDelete) {
250 HoldingsOlemlIndexer holdingsOlemlIndexer = HoldingsOlemlIndexer.getInstance();
251 Holdings holdings = holdingsTree.getHoldings();
252 SolrInputDocument holdingsSolrInputDocument = new SolrInputDocument();
253
254 if (Holdings.ResultType.SUCCESS.equals(holdings.getResult())) {
255 if (holdings.getId() != null) {
256 if (Holdings.OperationType.CREATE.equals(holdings.getOperation())) {
257 Bib bib = holdings.getBib();
258 if (null != bib && null != bib.getId()) {
259 buildSolrDocsForHoldingsTree(solrInputDocuments, bib, bibSolrInputDocument, holdingsTree);
260 }
261 } else if (Holdings.OperationType.UPDATE.equals(holdings.getOperation())) {
262 holdingsOlemlIndexer.processHoldingSolrDocumentForUpdate(holdings, solrInputDocuments, holdingsSolrInputDocument);
263 processItems(holdingsTree.getItems(), solrInputDocuments, holdingsSolrInputDocument, idsToDelete);
264 } else if (Holdings.OperationType.DELETE.equals(holdings.getOperation())) {
265 idsToDelete.add(holdings.getId());
266 for(Item item:holdingsTree.getItems()){
267 idsToDelete.add(item.getId());
268 }
269 holdingsOlemlIndexer.processDelete(holdings.getId(), solrInputDocuments);
270 }
271 }
272 } else if ((holdings.getOperation() == null || StringUtils.isBlank(holdings.getOperation().name()))) {
273 processItems(holdingsTree.getItems(), solrInputDocuments, holdingsSolrInputDocument, idsToDelete);
274 }
275
276 }
277
278
279
280
281
282
283
284
285
286
287 private void processItems(List<Item> items, List<SolrInputDocument> solrInputDocuments, SolrInputDocument holdingsSolrInputDocument, List<String> idsToDelete) {
288 ItemOlemlIndexer itemOlemlIndexer = ItemOlemlIndexer.getInstance();
289 for (Item item : items) {
290 if (Item.ResultType.SUCCESS.equals(item.getResult())) {
291 if (item.getId() != null) {
292 if (Item.OperationType.CREATE.equals(item.getOperation())) {
293 itemOlemlIndexer.buildSolrInputDocumentForBatchProcess(item, solrInputDocuments, holdingsSolrInputDocument);
294 } else if (Item.OperationType.UPDATE.equals(item.getOperation())) {
295 itemOlemlIndexer.updateRecordInSolr(item, solrInputDocuments);
296 } else if (Item.OperationType.DELETE.equals(item.getOperation())) {
297 idsToDelete.add(item.getId());
298 itemOlemlIndexer.processDelete(item.getId(), solrInputDocuments);
299 }
300 }
301 }
302 }
303 }
304
305 public void createTrees(Object object, ReindexBatchStatistics reindexBatchStatistics) {
306 BibTrees bibTreesObj = (BibTrees) object;
307 List<BibTree> bibTrees = bibTreesObj.getBibTrees();
308 List<SolrInputDocument> solrInputDocuments = new ArrayList<>();
309 StopWatch stopWatch = new StopWatch();
310
311 stopWatch.start();
312 for (BibTree bibTree : bibTrees) {
313 buildSolrDocsForBibTree(bibTree, solrInputDocuments);
314 }
315 stopWatch.stop();
316 reindexBatchStatistics.addBuildSolrDocsTime(stopWatch.getTotalTimeMillis());
317
318 indexSolrDocuments(solrInputDocuments, true, reindexBatchStatistics);
319 }
320
321 protected void indexSolrDocuments(List<SolrInputDocument> solrDocs, boolean isCommit, ReindexBatchStatistics reindexBatchStatistics) {
322 SolrServer solr = null;
323 try {
324 solr = SolrServerManager.getInstance().getSolrServer();
325 StopWatch stopWatch = new StopWatch();
326 stopWatch.start("add");
327 UpdateResponse response = solr.add(solrDocs);
328 stopWatch.stop();
329 reindexBatchStatistics.addRecToAddInSolr(stopWatch.getLastTaskTimeMillis());
330 if (isCommit) {
331 stopWatch.start("commit");
332 solr.commit(false, false);
333 stopWatch.stop();
334 reindexBatchStatistics.addCommitTime(stopWatch.getLastTaskTimeMillis());
335 }
336 } catch (SolrServerException e) {
337 LOG.info("Exception :", e);
338 rollback(solr);
339 throw new DocstoreIndexException(e.getMessage());
340 } catch (IOException e) {
341 LOG.info("Exception :", e);
342 rollback(solr);
343 throw new DocstoreIndexException(e.getMessage());
344 }
345 }
346
347
348 protected void buildSolrInputDocument(Object object, List<SolrInputDocument> solrInputDocuments) {
349 Bib bib = (Bib) object;
350 BibMarcRecords bibMarcRecords = recordProcessor.fromXML(bib.getContent());
351 SolrInputDocument solrInputDocument = buildSolrInputDocument(bibMarcRecords.getRecords().get(0));
352
353 setCommonFields(bib, solrInputDocument);
354
355 solrInputDocuments.add(solrInputDocument);
356
357 }
358
359 protected void setCommonFields(Bib bib, SolrInputDocument solrInputDocument) {
360 solrInputDocument.setField(ID, bib.getId());
361 solrInputDocument.addField(LOCALID_SEARCH, DocumentLocalId.getDocumentId(bib.getId()));
362 solrInputDocument.addField(LOCALID_DISPLAY, DocumentLocalId.getDocumentIdDisplay(bib.getId()));
363 solrInputDocument.addField(UNIQUE_ID, bib.getId());
364 solrInputDocument.setField(DOC_CATEGORY, DocCategory.WORK.getCode());
365 solrInputDocument.setField(BIB_ID, bib.getId());
366
367 solrInputDocument.setField(STATUS_SEARCH, bib.getStatus());
368 solrInputDocument.setField(STATUS_DISPLAY, bib.getStatus());
369
370 if (StringUtils.isNotEmpty(bib.getStatusUpdatedOn())) {
371 solrInputDocument.setField(STATUS_UPDATED_ON, getDate(bib.getStatusUpdatedOn()));
372 }
373
374 solrInputDocument.addField(STAFF_ONLY_FLAG, bib.isStaffOnly());
375
376 String createdBy = bib.getCreatedBy();
377 solrInputDocument.setField(CREATED_BY, createdBy);
378 solrInputDocument.setField(UPDATED_BY, createdBy);
379
380 Date date = new Date();
381 Date createdDate = null;
382
383 if (StringUtils.isNotBlank(bib.getCreatedOn())) {
384 createdDate = getDate(bib.getCreatedOn());
385 solrInputDocument.setField(DATE_ENTERED, createdDate);
386 } else {
387 solrInputDocument.setField(DATE_ENTERED, date);
388 }
389
390 if (StringUtils.isNotBlank(bib.getUpdatedOn())) {
391 solrInputDocument.setField(DATE_UPDATED, getDate(bib.getUpdatedOn()));
392 } else {
393 if (StringUtils.isNotBlank(bib.getCreatedOn())) {
394
395 solrInputDocument.setField(DATE_UPDATED, createdDate);
396 } else {
397 solrInputDocument.setField(DATE_UPDATED, date);
398 }
399 }
400 }
401
402 protected void updateRecordInSolr(Object object, List<SolrInputDocument> solrInputDocuments) {
403 Bib bib = (Bib) object;
404 List<SolrDocument> solrDocumentList = getSolrDocumentBySolrId(bib.getId());
405 SolrDocument solrDocument = solrDocumentList.get(0);
406 SolrInputDocument solrInputDocument = new SolrInputDocument();
407 if (bib.getContent() != null) {
408 BibMarcRecord workBibMarcRecord = recordProcessor.fromXML(bib.getContent()).getRecords().get(0);
409 solrInputDocument = buildSolrInputDocument(workBibMarcRecord);
410 if (solrDocument != null && solrDocument.getFieldValue(HOLDINGS_IDENTIFIER) != null) {
411 addBibInfoToHoldings(solrInputDocuments, solrInputDocument, solrDocument);
412 }
413 if (StringUtils.isNotEmpty(bib.getStatusUpdatedOn())) {
414 solrInputDocument.setField(STATUS_UPDATED_ON, getDate(bib.getStatusUpdatedOn()));
415 }
416 } else {
417 buildSolrInputDocFromSolrDoc(solrDocument, solrInputDocument);
418 }
419 setCommonFieldsForSolrDoc(solrInputDocument, bib, solrDocument);
420 solrInputDocuments.add(solrInputDocument);
421 }
422
423
424
425
426
427
428
429
430 protected void updateBibDocument(Object object, List<SolrInputDocument> solrInputDocuments, SolrInputDocument solrbibInputDocument) {
431 Bib bib = (Bib) object;
432 List<SolrDocument> solrDocumentList = getSolrDocumentBySolrId(bib.getId());
433 SolrDocument solrDocument = solrDocumentList.get(0);
434
435 if (bib.getContent() != null) {
436 BibMarcRecord workBibMarcRecord = recordProcessor.fromXML(bib.getContent()).getRecords().get(0);
437 solrbibInputDocument = buildSolrInputDocument(workBibMarcRecord, solrbibInputDocument);
438
439 if (solrDocument != null && solrDocument.getFieldValue(HOLDINGS_IDENTIFIER) != null) {
440 addBibInfoToHoldings(solrInputDocuments, solrbibInputDocument, solrDocument);
441 }
442 if (StringUtils.isNotEmpty(bib.getStatus()) || StringUtils.isNotEmpty(bib.getStatusUpdatedOn())) {
443 solrbibInputDocument.setField(STATUS_UPDATED_ON, getDate(bib.getStatusUpdatedOn()));
444 }
445 } else {
446 buildSolrInputDocFromSolrDoc(solrDocument, solrbibInputDocument);
447 }
448 setCommonFieldsForSolrDoc(solrbibInputDocument, bib, solrDocument);
449 solrInputDocuments.add(solrbibInputDocument);
450
451 }
452
453 private void addBibInfoToHoldings(List<SolrInputDocument> solrInputDocuments, SolrInputDocument bibSolrDoc, SolrDocument solrDocument) {
454 Object instanceIdentifier = solrDocument.getFieldValue(HOLDINGS_IDENTIFIER);
455 bibSolrDoc.addField(HOLDINGS_IDENTIFIER, instanceIdentifier);
456 List<String> holdinsgsIds = new ArrayList<>();
457 if (instanceIdentifier instanceof String) {
458 holdinsgsIds.add((String) instanceIdentifier);
459 } else {
460 holdinsgsIds.addAll((List<String>) instanceIdentifier);
461 }
462
463 for (String holdingsId : holdinsgsIds) {
464 List<SolrDocument> solrDocumentList = getSolrDocumentBySolrId(holdingsId);
465 if (CollectionUtils.isNotEmpty(solrDocumentList)) {
466 SolrDocument holdingsSolrDocument = solrDocumentList.get(0);
467 SolrInputDocument holdingsSolrInputDocument = new SolrInputDocument();
468 buildSolrInputDocFromSolrDoc(holdingsSolrDocument, holdingsSolrInputDocument);
469 removeFieldFromSolrInputDocument(holdingsSolrInputDocument);
470 addBibInfoForHoldingsOrItems(holdingsSolrInputDocument, bibSolrDoc);
471 List<String> itemIds = new ArrayList<>();
472
473 Object itemIdentifier = holdingsSolrDocument.getFieldValue(ITEM_IDENTIFIER);
474 if (itemIdentifier != null) {
475 if (itemIdentifier instanceof String) {
476 itemIds.add((String) itemIdentifier);
477 } else {
478 itemIds.addAll((List<String>) itemIdentifier);
479 }
480 }
481
482 for (String itemId : itemIds) {
483
484 List<SolrDocument> itemDocumentList = getSolrDocumentBySolrId(itemId);
485 SolrDocument itemSolrDocument = itemDocumentList.get(0);
486 SolrInputDocument itemSolrInputDocument = new SolrInputDocument();
487 buildSolrInputDocFromSolrDoc(itemSolrDocument, itemSolrInputDocument);
488 removeFieldFromSolrInputDocument(itemSolrInputDocument);
489 addBibInfoForHoldingsOrItems(itemSolrInputDocument, bibSolrDoc);
490 addHoldingsInfoToItem(itemSolrInputDocument, bibSolrDoc);
491 solrInputDocuments.add(itemSolrInputDocument);
492 }
493 solrInputDocuments.add(holdingsSolrInputDocument);
494
495 }
496 }
497
498 }
499
500 protected void deleteRecordInSolr(SolrServer solrServer, String id) throws IOException, SolrServerException {
501 String query = "bibIdentifier:" + id + " OR " + "id:" + id;
502 UpdateResponse updateResponse = solrServer.deleteByQuery(query);
503 LOG.info("updateResponse " + updateResponse);
504
505 String newId = id + "_d";
506 SolrInputDocument solrInputDocument = new SolrInputDocument();
507 solrInputDocument.setField("DocType", "bibliographic_delete");
508 solrInputDocument.setField("dateUpdated", new Date());
509 solrInputDocument.setField("uniqueId", newId);
510 solrInputDocument.setField("id", newId);
511 solrInputDocument.setField("LocalId_display", DocumentLocalId.getDocumentIdDisplay(id));
512 UpdateResponse updateResponseForBib = solrServer.add(solrInputDocument);
513 LOG.debug("updateResponse " + updateResponseForBib);
514
515 }
516
517 private void setCommonFieldsForSolrDoc(SolrInputDocument solrInputDocument, Bib bib, SolrDocument solrDocument) {
518 solrInputDocument.setField(ID, bib.getId());
519 solrInputDocument.addField(UNIQUE_ID, bib.getId());
520 solrInputDocument.setField(DOC_CATEGORY, DocCategory.WORK.getCode());
521 String updatedBy = bib.getUpdatedBy();
522 solrInputDocument.setField(UPDATED_BY, updatedBy);
523 solrInputDocument.setField(DATE_UPDATED, new Date());
524 solrInputDocument.setField(CREATED_BY, solrDocument.getFieldValue(CREATED_BY));
525 solrInputDocument.setField(DATE_ENTERED, solrDocument.getFieldValue(DATE_ENTERED));
526 solrInputDocument.setField(BIB_ID, bib.getId());
527 solrInputDocument.addField(LOCALID_SEARCH, DocumentLocalId.getDocumentId(bib.getId()));
528 solrInputDocument.addField(LOCALID_DISPLAY, DocumentLocalId.getDocumentIdDisplay(bib.getId()));
529 solrInputDocument.addField(STAFF_ONLY_FLAG, bib.isStaffOnly());
530 solrInputDocument.setField(STATUS_SEARCH, bib.getStatus());
531 solrInputDocument.setField(STATUS_DISPLAY, bib.getStatus());
532 }
533
534
535 private Date getDate(String dateStr) {
536 DateFormat format = new SimpleDateFormat(Constants.DATE_FORMAT);
537 try {
538 if (StringUtils.isNotEmpty(dateStr)) {
539 return format.parse(dateStr);
540 } else {
541 return new Date();
542 }
543
544 } catch (ParseException e) {
545 LOG.info("Exception : " + dateStr + " for format:: " + Constants.DATE_FORMAT, e);
546 return new Date();
547 }
548 }
549
550
551
552
553
554
555
556
557 public SolrInputDocument buildSolrInputDocument(BibMarcRecord record) {
558 SolrInputDocument solrDoc = new SolrInputDocument();
559 buildSolrInputDocument(record, solrDoc);
560 return solrDoc;
561 }
562
563 public SolrInputDocument buildSolrInputDocument(BibMarcRecord record, SolrInputDocument solrDoc) {
564
565 solrDoc.addField(LEADER, record.getLeader());
566
567
568 List<ControlField> controlFieldList = record.getControlFields();
569
570 for (ControlField cf : controlFieldList) {
571 solrDoc.addField("controlfield_" + cf.getTag(), cf.getValue());
572 }
573
574 solrDoc.addField(DOC_TYPE, DocType.BIB.getDescription());
575 solrDoc.addField(DOC_FORMAT, DocFormat.MARC.getDescription());
576
577 for (String field : documentSearchConfig.FIELDS_TO_TAGS_2_INCLUDE_MAP.keySet()) {
578 Object object = buildFieldValue(field, record);
579 if(object != null){
580 addFieldToSolrDoc(record, field,object, solrDoc);
581 }
582
583 }
584 addFieldToSolrDoc(record, ALL_TEXT, getAllText(record), solrDoc);
585 addGeneralFieldsToSolrDoc(record, solrDoc);
586 if (record.getLeader() == null || ((record.getLeader().length() >= 8) && (record.getLeader().charAt(7) != 's'))) {
587 solrDoc.removeField(JOURNAL_TITLE_SEARCH);
588 solrDoc.removeField(JOURNAL_TITLE_DISPLAY);
589 solrDoc.removeField(JOURNAL_TITLE_SORT);
590 }
591 addFieldToSolrDoc(record, PUBLISHER_SORT, solrDoc.getFieldValue(PUBLISHER_SEARCH), solrDoc);
592 return solrDoc;
593 }
594
595 private void addFieldToSolrDoc(BibMarcRecord record, String fieldName, Object value,
596 SolrInputDocument solrDoc) {
597 int ind2Value = 0;
598 if (value instanceof List) {
599 if (fieldName.toLowerCase().endsWith("_sort"))
600 {
601 ind2Value = getSecondIndicator(record, fieldName);
602 LOG.debug("field name -->" + fieldName + "----->" + ind2Value);
603 if (ind2Value > 0) {
604 solrDoc.addField(fieldName, ((List) value).get(0).toString().substring(ind2Value));
605 } else {
606 solrDoc.addField(fieldName, ((List) value).get(0));
607 }
608
609 } else if (fieldName.endsWith("_facet")) {
610 solrDoc.addField(fieldName, getSortString((List) value));
611 } else {
612 if (((List) value).size() > 0) {
613 for (Object obj : (List<Object>) value)
614
615 {
616 solrDoc.addField(fieldName, obj);
617 }
618 } else {
619 solrDoc.addField(fieldName, null);
620 }
621 }
622 } else {
623 if (fieldName.toLowerCase().endsWith("_sort"))
624 {
625 ind2Value = getSecondIndicator(record, fieldName);
626 LOG.debug("field name -->" + fieldName + "----->" + ind2Value);
627 if (value != null && ind2Value > 0) {
628 String fieldValue = value.toString();
629 try {
630 fieldValue = value.toString().substring(ind2Value);
631 } catch (Exception e) {
632 LOG.error("Exception while getting value:" + value.toString() + " for field:" + fieldName + ". Exception:" + e.toString());
633
634 }
635 solrDoc.addField(fieldName, fieldValue);
636 } else {
637 solrDoc.addField(fieldName, value);
638 }
639 } else if (fieldName.endsWith("_facet")) {
640 if (value != null) {
641 solrDoc.addField(fieldName, getSortString(value.toString()));
642 }
643 } else {
644 solrDoc.addField(fieldName, value);
645 }
646 }
647 }
648
649
650
651
652
653
654
655
656 public Object buildFieldValue(String fieldName, BibMarcRecord record) {
657 List<ControlField> controlFieldList = record.getControlFields();
658 List<DataField> dataFields = record.getDataFields();
659 String includeTags = documentSearchConfig.FIELDS_TO_TAGS_2_INCLUDE_MAP.get(fieldName);
660 if ((includeTags != null) && (includeTags.length() > 0)) {
661 String excludeTags = documentSearchConfig.FIELDS_TO_TAGS_2_EXCLUDE_MAP.get(fieldName);
662 if (excludeTags == null) {
663 excludeTags = "";
664 }
665 if (fieldName.startsWith("Subject_")) {
666 return getDataFieldValue(includeTags, excludeTags, record, true, fieldName);
667 } else {
668 if (fieldName.equals(ISBN_SEARCH))
669 return normalizeIsbn(getDataFieldValue(includeTags, excludeTags, record, false, fieldName));
670 else
671 return getDataFieldValue(includeTags, excludeTags, record, false, fieldName);
672 }
673 } else if (fieldName.equals(PUBLICATIONDATE_DISPLAY) || fieldName.equals(PUBLICATIONDATE_SEARCH) || fieldName.equals(PUBLICATIONDATE_FACET)
674 || fieldName.equals(PUBLICATIONDATE_SORT)) {
675 String publicationDate = "";
676 String publicationEndDate = "";
677 Object publicationDateValue = null;
678 for (ControlField controlField : controlFieldList) {
679 if (controlField.getTag().equalsIgnoreCase("008")) {
680 String controlField008 = controlField.getValue();
681 if (controlField008 != null && controlField008.length() > 10) {
682 publicationDate = controlField008.substring(7, 11);
683 publicationDate = extractPublicationDateWithRegex(publicationDate);
684 if (controlField008.length() > 14) {
685 publicationEndDate = controlField008.substring(11, 15);
686 publicationEndDate = extractPublicationDateWithRegex(publicationEndDate);
687 }
688 }
689 }
690 }
691 if (publicationDate == null || publicationDate.trim().length() == 0) {
692 if (getDataFieldValue("260-c", "", record, true, fieldName) instanceof String) {
693 publicationDate = (String) getDataFieldValue("260-c", "", record, true, fieldName);
694 } else if (getDataFieldValue("260-c", "", record, true, fieldName) instanceof List) {
695 publicationDate = ((List<String>) getDataFieldValue("260-c", "", record, true, fieldName)).get(0);
696 }
697 publicationDate = extractPublicationDateWithRegex(publicationDate);
698 }
699 if (fieldName.equals(PUBLICATIONDATE_FACET)) {
700 if (publicationDate.equalsIgnoreCase("")) {
701 publicationDateValue = "Date could not be determined";
702 } else {
703 publicationDateValue = buildPublicationDateFacetValue(publicationDate, publicationEndDate);
704 }
705 return publicationDateValue;
706 }
707 return publicationDate;
708 } else if (fieldName.equals(LANGUAGE_DISPLAY) || fieldName.equals(LANGUAGE_SEARCH) || fieldName.equals(LANGUAGE_FACET)) {
709 List<Object> langs = new ArrayList<Object>();
710 for (ControlField controlField : controlFieldList) {
711 if (controlField.getTag().equalsIgnoreCase("008")) {
712 String cf8 = controlField.getValue();
713 if (cf8 != null && cf8.length() > 37) {
714 String lang = Languages.getInstance(Languages.ISO_639_3).getLanguageDescription(
715 cf8.substring(35, 38));
716 langs.add(lang == null ? "Undefined" : lang);
717 }
718 }
719 }
720 if (fieldName.equals(LANGUAGE_SEARCH) || fieldName.equals(LANGUAGE_FACET)) {
721 for (DataField df : dataFields) {
722 if (df.getTag().equals("546")) {
723 try {
724 for (SubField subfield : df.getSubFields()) {
725 if (subfield.getCode().equalsIgnoreCase("a")) {
726 langs.add(subfield.getValue());
727 }
728 }
729 } catch (RuntimeException re) {
730 LOG.info("Exception :", re);
731 }
732 }
733 }
734 }
735 return langs;
736 } else if (fieldName.equals(FORMAT_DISPLAY) || fieldName.equals(FORMAT_SEARCH) || fieldName.equals(FORMAT_FACET)) {
737 return getRecordFormat(record);
738 } else if (fieldName.equals(RESOURCETYPE_DISPLAY) || fieldName.equals(RESOURCETYPE_SEARCH)) {
739 return getRecordFormat_ResourceType(record);
740 } else if (fieldName.equals(CARRIER_DISPLAY) || fieldName.equals(CARRIER_SEARCH)) {
741 return getRecordFormat_Carrier(record);
742 } else if(fieldName.equals(DESCRIPTION_SEARCH)) {
743 String excludeTags = documentSearchConfig.FIELDS_TO_TAGS_2_EXCLUDE_MAP.get(fieldName);
744 if (excludeTags == null) {
745 excludeTags = "";
746 }
747 if (includeTags == null) {
748 includeTags = "";
749 }
750 return getDataFieldValue(includeTags, excludeTags, record, false, fieldName);
751 } else {
752 return null;
753 }
754 }
755
756
757
758
759
760
761
762 public String getAllText(BibMarcRecord record) {
763 StringBuilder allText = new StringBuilder();
764 allText.append(record.getLeader());
765 allText.append(SEPERATOR_DATA_FIELD);
766 for (ControlField cf : record.getControlFields()) {
767 allText.append(cf.getValue());
768 allText.append(SEPERATOR_DATA_FIELD);
769 }
770 for (DataField df : record.getDataFields()) {
771 for (SubField sf : df.getSubFields()) {
772 allText.append(sf.getValue());
773 allText.append(SEPERATOR_SUB_FIELD);
774 if(sf.getValue().contains("-")){
775 allText.append(sf.getValue().replace("-",""));
776 allText.append(SEPERATOR_SUB_FIELD);
777 }
778 }
779 allText.append(SEPERATOR_DATA_FIELD);
780 }
781 return allText.toString();
782 }
783
784
785
786
787
788
789
790 public String getRecordFormat(BibMarcRecord record) {
791 String format = null;
792 String cF7 = null;
793 String cF8 = null;
794 String formatData = "";
795 char cF8Ch21 = ' ';
796 char cF8Ch22 = ' ';
797 char cF8Ch28 = ' ';
798 char cF7Ch0 = ' ';
799 int cFIndex = record.getControlFields().indexOf(new ControlField("007"));
800 if (cFIndex != -1) {
801 cF7 = record.getControlFields().get(cFIndex).getValue();
802 }
803 cFIndex = record.getControlFields().indexOf(new ControlField("008"));
804 if (cFIndex != -1) {
805 cF8 = record.getControlFields().get(cFIndex).getValue();
806 }
807 Object tmp = null;
808 tmp = getDataFieldValue("111-a", "", record, false, "");
809 String dF111a = tmp != null ? tmp.toString() : null;
810 tmp = getDataFieldValue("254-h", "", record, false, "");
811 String dF254h = tmp != null ? tmp.toString() : null;
812 tmp = getDataFieldValue("254-k", "", record, false, "");
813 String dF254k = tmp != null ? tmp.toString() : null;
814 tmp = getDataFieldValue("260-b", "", record, false, "");
815 String dF260b = tmp != null ? tmp.toString() : null;
816 tmp = getDataFieldValue("502-a", "", record, false, "");
817 String dF502a = tmp != null ? tmp.toString() : null;
818 tmp = getDataFieldValue("711-a", "", record, false, "");
819 String dF711a = tmp != null ? tmp.toString() : null;
820
821 if (cF8 != null && cF8.length() > 22) {
822 cF8Ch21 = cF8.charAt(21);
823 cF8Ch22 = cF8.charAt(22);
824 }
825 if (cF8 != null && cF8.length() > 28) {
826 cF8Ch28 = cF8.charAt(28);
827 }
828 if (cF7 != null) {
829 cF7Ch0 = cF7.charAt(0);
830 }
831 if (record.getLeader() != null && record.getLeader().length() > 8) {
832 formatData = record.getLeader().substring(6, 8);
833 }
834
835 if (dF254h != null && dF254h.contains("micro")) {
836 format = "Microformat";
837 } else if (formatData.equals("tm") && dF502a != null) {
838 format = "Thesis/Dissertation";
839 } else if (dF111a != null || dF711a != null) {
840 format = "Conference/Event";
841 } else if (formatData.equals("aa") || formatData.equals("am") || formatData.equals("ac") || formatData
842 .equals("tm")) {
843 if (dF254k != null && dF254k.contains("kit")) {
844 format = "Other";
845 } else {
846 format = "Book";
847 }
848 } else if (formatData.equals("im") || formatData.equals("jm") || formatData.equals("jc")
849 || formatData.equals("jd") || formatData.equals("js")) {
850 format = "Sound recording";
851 } else if (formatData.equals("cm") || formatData.equals("dm") || formatData.equals("ca")
852 || formatData.equals("cb") || formatData.equals("cd") || formatData.equals("cs")) {
853 format = "Musical score";
854 } else if (formatData.equals("fm") || ("".equals(formatData) && formatData.startsWith("e"))) {
855 format = "Map/Atlas";
856 } else if (formatData.equals("gm") || (cF7 != null && (cF7Ch0 == ('v')))) {
857 format = "Video";
858 } else if (formatData.equals("gm") || (cF7 != null && (cF7Ch0 == ('g')))) {
859 format = "Projected graphic";
860 } else if (formatData.equals("as") || formatData.equals("gs")) {
861 format = "Journal/Periodical";
862 } else if (formatData.equals("km")) {
863 format = "Image";
864 } else if (formatData.equals("mm")) {
865 format = "Datafile";
866 } else if (formatData.equals("as") && (cF8Ch21 == 'n' || cF8Ch22 == 'e')) {
867 format = "Newspaper";
868 } else if ("".equals(formatData) && formatData.startsWith("r")) {
869 format = "3D object";
870 } else if (formatData != "" && formatData.endsWith("i")) {
871 format = "Database/Website";
872 } else if (("".equals(formatData) && (!formatData.startsWith("c") || !formatData.startsWith("d")
873 || !formatData.startsWith("i") || !formatData.startsWith("j"))) && (
874 (cF8Ch28 == 'f' || cF8Ch28 == 'i' || cF8Ch28 == 'o') && (dF260b != null && !dF260b
875 .contains("press")))) {
876 format = "Government document";
877 } else {
878 format = "Other";
879 }
880 return format;
881 }
882
883
884
885
886
887
888
889 public String getRecordFormat_ResourceType(BibMarcRecord record) {
890 String format = null;
891 char leader6 = ' ';
892 char leader7 = ' ';
893 if (record.getLeader() != null) {
894 String leader = record.getLeader().trim();
895 if (StringUtils.isNotBlank(leader)) {
896 if (leader.length() >= 7) {
897 leader6 = leader.charAt(6);
898 }
899 if (leader.length() >= 8) {
900 leader7 = leader.charAt(7);
901 }
902
903 if ((leader6 == 'a' || leader6 == 't') && leader7 == 'm') {
904 format = "Book";
905 }
906 if (leader6 == 'a' && leader7 == 's') {
907 format = "Serial";
908 }
909 if (leader6 == 'c' || leader6 == 'd') {
910 format = "Score";
911 }
912 if (leader6 == 'j' || leader6 == 'i') {
913 format = "Sound recording";
914 }
915 if (leader6 == 'e' || leader6 == 'f') {
916 format = "Map";
917 }
918 if (leader6 == 'g') {
919 format = "Motion picture";
920 }
921 if (leader6 == 'k') {
922 format = "Photo/Print";
923 }
924 if (leader6 == 'm') {
925 format = "Computer file";
926 }
927 if (leader6 == 'p') {
928 format = "Archival materials";
929 }
930 if (leader6 == 'r') {
931 format = "Artifacts";
932 }
933 }
934 }
935 return format;
936 }
937
938 public String getRecordFormat_Carrier(BibMarcRecord record) {
939 String format = null;
940 String cF7 = null;
941 String cF8 = null;
942 char cF70 = ' ';
943 char cF71 = ' ';
944 char cF823 = ' ';
945 char cF829 = ' ';
946 char leader06 = ' ';
947 String leader ="";
948 if (record.getLeader() != null) {
949 leader = record.getLeader();
950 }
951 for (ControlField controlField : record.getControlFields()) {
952 if (controlField.getTag().equals("007")) {
953 cF7 = controlField.getValue();
954 }else if(controlField.getTag().equals("008")){
955 cF8 = controlField.getValue();
956 }
957 }
958
959 if(StringUtils.isNotBlank(cF7) && cF7.length() >= 1){
960 cF70 = cF7.charAt(0);
961 }
962 if(StringUtils.isNotBlank(cF7) && cF7.length() >= 2){
963 cF71 = cF7.charAt(1);
964 }
965 if(StringUtils.isNotBlank(cF8) && cF8.length() >= 24){
966 cF823 = cF8.charAt(23);
967 }
968 if(StringUtils.isNotBlank(cF8) && cF8.length() >= 30){
969 cF829 = cF8.charAt(29);
970 }
971 if(StringUtils.isNotBlank(leader) && leader.length() >= 7){
972 leader06 = leader.charAt(6);
973 }
974
975 if(cF70 == 'h'){
976 format = "Microform";
977 return format;
978 }
979 if(cF70 == 'c' && cF71 == 'r'){
980 format = "Remote e-resource";
981 return format;
982 }
983 if(cF70 == 'c' && cF71 != 'r'){
984 format = "Direct access 3-resource";
985 return format;
986 }
987 if((leader06 == 'a' || leader06 == 'c' || leader06 == 'd' || leader06 == 'p' || leader06 == 't') && (cF823 == 'd' || cF823 == 'f' || cF823 == 'r' || cF823 == ' ')){
988 format = "Print";
989 }
990 if((leader06 == 'e' || leader06 == 'f' || leader06 == 'k') && (cF829 == 'd' || cF829 == 'r' || cF829 == ' ')){
991 format = "Print";
992 }
993 return format;
994 }
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007 private Object getDataFieldValue(String includeTags, String excludeTags, BibMarcRecord record,
1008 boolean isHyphenSeperatorFirst, String fieldName) {
1009 List<Object> fieldValues = new ArrayList<Object>();
1010 StringTokenizer includeTagsTokenizer = new StringTokenizer(includeTags, ",");
1011
1012 while (includeTagsTokenizer.hasMoreElements()) {
1013 String tag = includeTagsTokenizer.nextToken();
1014 tag = tag.trim();
1015 int subFieldIdx = tag.indexOf('-');
1016 String tagNum = (subFieldIdx == -1) ? tag : tag.substring(0, subFieldIdx);
1017
1018 for (int i = 0; i < record.getDataFields().size(); i++) {
1019 DataField dataField = record.getDataFields().get(i);
1020 if (isValidTag(dataField.getTag(), tagNum)) {
1021 StringBuilder fieldValue = new StringBuilder();
1022 List<SubField> subFields = dataField.getSubFields();
1023 if (subFieldIdx != -1) {
1024 if (!excludeTags.contains(tag)) {
1025 String subFieldCodes = tag.substring(subFieldIdx + 1, tag.length());
1026 boolean isHyphenCodedOnce = false;
1027 for (SubField subField : subFields) {
1028 if (subFieldCodes.contains(subField.getCode())) {
1029 if (fieldValue.length() != 0) {
1030 if (!isHyphenSeperatorFirst || isHyphenCodedOnce || (
1031 dataField.getTag().endsWith("00") || dataField.getTag().endsWith("10")
1032 || dataField.getTag().endsWith("11"))) {
1033 fieldValue.append(SEPERATOR_SUB_FIELD);
1034 } else {
1035 fieldValue.append(SEPERATOR_HYPHEN);
1036 isHyphenCodedOnce = true;
1037 }
1038 }
1039 fieldValue.append(subField.getValue());
1040 }
1041 }
1042 }
1043 } else {
1044 boolean isHyphenCodedOnce = false;
1045 boolean isFirstSubField = false;
1046 for (SubField subField : subFields) {
1047 if (!excludeTags.contains(dataField.getTag() + "-" + subField.getCode()) && !excludeTags
1048 .contains(tagNum + "-" + subField.getCode())) {
1049 if (fieldValue.length() != 0) {
1050 if (!isHyphenSeperatorFirst || isHyphenCodedOnce || (
1051 dataField.getTag().endsWith("00") || dataField.getTag().endsWith("10")
1052 || dataField.getTag().endsWith("11"))) {
1053 fieldValue.append(SEPERATOR_SUB_FIELD);
1054 } else if (fieldName != null && (fieldName.equalsIgnoreCase(SUBJECT_FACET)
1055 || fieldName.equalsIgnoreCase(SUBJECT_DISPLAY))) {
1056 if (dataField.getTag().equalsIgnoreCase("630")) {
1057 if (subField.getCode().equals("v") || subField.getCode().equals("x")
1058 || subField.getCode().equals("y") || subField.getCode().equals("z")) {
1059 fieldValue.append(SEPERATOR_DOUBLE_HYPHEN);
1060 }
1061 } else if (dataField.getTag().equalsIgnoreCase("650") || dataField.getTag()
1062 .equalsIgnoreCase(
1063 "651")) {
1064 if (isFirstSubField && fieldName.equalsIgnoreCase(SUBJECT_FACET)) {
1065 fieldValues.add(fieldValue.toString().trim());
1066 }
1067 fieldValue.append(SEPERATOR_DOUBLE_HYPHEN);
1068 isFirstSubField = true;
1069 } else {
1070 fieldValue.append(SEPERATOR_SUB_FIELD);
1071 }
1072 } else {
1073 if (fieldName.startsWith("Subject_")) {
1074 fieldValue.append(SEPERATOR_SUB_FIELD);
1075 } else {
1076 fieldValue.append(SEPERATOR_HYPHEN);
1077 isHyphenCodedOnce = true;
1078 }
1079 }
1080 }
1081 fieldValue.append(subField.getValue());
1082 }
1083 }
1084 }
1085 if ((dataField.getTag().equalsIgnoreCase("650") || dataField.getTag().equalsIgnoreCase("651"))
1086 && fieldValue != null && fieldValue.length() > 1 && fieldValue.toString().trim().length() > 1) {
1087 String fieldVal = fieldValue.toString().trim();
1088 String lastChar = String.valueOf(fieldVal.charAt(fieldVal.length() - 1));
1089 if (!lastChar.equalsIgnoreCase(".")) {
1090 fieldValue.append(".");
1091 }
1092 }
1093 fieldValues.add(fieldValue.toString().trim());
1094 }
1095 }
1096 }
1097 if (fieldValues.size() == 1) {
1098 return fieldValues.get(0);
1099 } else if (fieldValues.size() > 0) {
1100 return fieldValues;
1101 } else {
1102 return null;
1103 }
1104 }
1105
1106
1107
1108
1109
1110
1111
1112
1113 private boolean isValidTag(String tag, String tagFormat) {
1114 try {
1115 if (!tagFormat.contains(PATTERN_CHAR)) {
1116 return tagFormat.equals(tag);
1117 } else {
1118 int idx = tagFormat.lastIndexOf(PATTERN_CHAR);
1119 return isValidTag(tag.substring(0, idx) + tag.substring(idx + PATTERN_CHAR.length(), tag.length()), tagFormat.substring(0, idx)
1120 + tagFormat.substring(idx + PATTERN_CHAR.length(), tagFormat.length()));
1121 }
1122 } catch (Exception e) {
1123 LOG.info("Exception :", e);
1124 return false;
1125 }
1126 }
1127
1128 private void addGeneralFieldsToSolrDoc(BibMarcRecord record, SolrInputDocument solrDoc) {
1129 String isbnDataFields = documentSearchConfig.FIELDS_TO_TAGS_2_INCLUDE_MAP.get(ISBN_SEARCH);
1130 for (DataField dataField : record.getDataFields()) {
1131 String tag = dataField.getTag();
1132 for (SubField subField : dataField.getSubFields()) {
1133 String subFieldKey = subField.getCode();
1134 String subFieldValue = subField.getValue();
1135 String key = tag + subFieldKey;
1136 subFieldValue = processGeneralFieldValue(tag, subFieldKey, subFieldValue, isbnDataFields);
1137 solrDoc.addField(DYNAMIC_FIELD_PREFIX + key, subFieldValue);
1138 }
1139 }
1140 }
1141
1142 private String processGeneralFieldValue(String tag, String subFieldKey, String subFieldValue, String isbnKey) {
1143 String value = subFieldValue;
1144 if (isbnKey.contains(tag) && isbnKey.contains(subFieldKey)) {
1145 value = (String) normalizeIsbn(subFieldValue);
1146 }
1147 return value;
1148 }
1149
1150 private Object normalizeIsbn(Object isbnValue) {
1151 Object result = null;
1152 ISBNUtil isbnUtil = new ISBNUtil();
1153 if (isbnValue != null) {
1154 if (isbnValue instanceof List) {
1155 result = new ArrayList<String>();
1156 for (Object obj : (List<Object>) isbnValue) {
1157 if (((String) obj).length() > 0) {
1158 try {
1159 ((List<String>) result).add(isbnUtil.normalizeISBN(obj));
1160 } catch (OleException e) {
1161
1162 ((List<String>) result).add((String) obj + " " + ISBN_NOT_NORMALIZED);
1163 }
1164 } else {
1165 ((List<String>) result).add((String) obj);
1166 }
1167 }
1168 } else {
1169 if (((String) isbnValue).length() > 0) {
1170 try {
1171 result = isbnUtil.normalizeISBN(isbnValue);
1172 } catch (OleException e) {
1173
1174 result = isbnValue + " " + ISBN_NOT_NORMALIZED;
1175 }
1176 } else {
1177 result = isbnValue;
1178 }
1179 }
1180 }
1181 return result;
1182 }
1183
1184
1185
1186
1187
1188
1189 private void pubCentury(int pubCen, List<String> pubList) {
1190 String pubCentury = String.valueOf(pubCen);
1191 if (pubCentury.endsWith("1")) {
1192 if (pubCentury.equalsIgnoreCase("11")) {
1193 pubList.add(pubCentury + "th Century");
1194 } else {
1195 pubList.add(pubCentury + "st Century");
1196 }
1197 } else if (pubCentury.endsWith("2")) {
1198 if (pubCentury.equalsIgnoreCase("12")) {
1199 pubList.add(pubCentury + "th Century");
1200 } else {
1201 pubList.add(pubCentury + "nd Century");
1202 }
1203 } else if (pubCentury.endsWith("3")) {
1204 if (pubCentury.equalsIgnoreCase("13")) {
1205 pubList.add(pubCentury + "th Century");
1206 } else {
1207 pubList.add(pubCentury + "rd Century");
1208 }
1209 } else {
1210 pubList.add(pubCentury + "th Century");
1211 }
1212
1213 }
1214
1215
1216 public String extractPublicationDateWithRegex(String publicationDate) {
1217 Pattern pattern = Pattern.compile(publicationDateRegex);
1218 Matcher matcher = pattern.matcher(publicationDate);
1219 if (matcher.find()) {
1220 if (matcher.group(0).equalsIgnoreCase("0000")) {
1221 return "";
1222 }
1223 return matcher.group(0);
1224 } else {
1225 return "";
1226 }
1227
1228
1229 }
1230
1231
1232
1233
1234
1235
1236 public Object buildPublicationDateFacetValue(String publicationDate, String publicationEndDate) {
1237 int pubDat = 0;
1238 List<String> pubList = new ArrayList<String>();
1239 Calendar cal = Calendar.getInstance();
1240 int year = cal.get(Calendar.YEAR);
1241 if (publicationDate != null && publicationDate.length() == 4 && Integer.parseInt(publicationDate) <= year) {
1242 int pubStartDate = Integer.parseInt(publicationDate);
1243 if (publicationEndDate != null && publicationEndDate.length() == 4 && pubStartDate < Integer
1244 .parseInt(publicationEndDate)) {
1245 if (Integer.parseInt(publicationEndDate) > year) {
1246 publicationEndDate = String.valueOf(year);
1247 }
1248 int pubEndDate = Integer.parseInt(publicationEndDate);
1249 while (pubStartDate < pubEndDate) {
1250 pubStartDate = (pubStartDate / 10) * 10;
1251 if (pubStartDate == 0) {
1252 pubList.add("Date could not be determined");
1253 } else {
1254 pubList.add(String.valueOf(pubStartDate) + "s");
1255 }
1256 pubStartDate = pubStartDate + 10;
1257 }
1258 pubStartDate = Integer.parseInt(publicationDate);
1259 pubEndDate = Integer.parseInt(publicationEndDate);
1260 while (pubStartDate < pubEndDate) {
1261 pubStartDate = (pubStartDate) / 100;
1262 pubDat = (pubStartDate) + 1;
1263 pubCentury(pubDat, pubList);
1264 pubStartDate = pubStartDate * 100 + 100;
1265 }
1266 } else {
1267 pubDat = (pubStartDate / 10) * 10;
1268 int pubCen = ((pubStartDate) / 100) + 1;
1269 if (pubDat == 0) {
1270 pubList.add("Date could not be determined");
1271 } else {
1272 pubList.add(String.valueOf(pubDat) + "s");
1273 pubCentury(pubCen, pubList);
1274 }
1275 }
1276 } else {
1277 pubList.add("Date could not be determined");
1278 }
1279 return pubList;
1280 }
1281
1282
1283
1284
1285
1286
1287
1288
1289 public List<String> buildPublicationDateFacetValues(List<String> publicationDates) {
1290 List<String> valueList = null;
1291 if (!CollectionUtils.isEmpty(publicationDates)) {
1292 valueList = new ArrayList<String>(publicationDates.size());
1293 for (int i = 0; i < publicationDates.size(); i++) {
1294 String pubDate = publicationDates.get(i);
1295 Object pubDt = buildPublicationDateFacetValue(pubDate, "");
1296 if (pubDt instanceof String) {
1297 valueList.add((String) pubDt);
1298 } else if (pubDt instanceof List) {
1299 List<String> pubDateList = (List<String>) pubDt;
1300 for (String pubDtVal : pubDateList) {
1301 valueList.add(pubDtVal);
1302 }
1303 }
1304 }
1305 }
1306 return valueList;
1307 }
1308
1309
1310 public String getSortString(String str) {
1311 String ret = "";
1312 StringBuffer sortString = new StringBuffer();
1313 ret = str.toLowerCase();
1314 ret = ret.replaceAll("[\\-\\/]", " ");
1315 ret = ret.replace("<", "");
1316 ret = ret.replace(">", "");
1317 ret = ret.replaceAll("[\\.\\,\\;\\:\\(\\)\\{\\}\\'\\!\\?\\\"\\<\\>\\[\\]]", "");
1318 ret = Normalizer.normalize(ret, Normalizer.Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+", "");
1319 ret = ret.replaceAll("\\s+", " ");
1320 sortString.append(ret);
1321 sortString.append(" /r/n!@#$");
1322 sortString.append(str);
1323 return sortString.toString();
1324 }
1325
1326 public List<String> getSortString(List<String> list) {
1327 List<String> sortStringList = new ArrayList<String>();
1328 for (String str : list) {
1329 sortStringList.add(getSortString(str));
1330 }
1331 return sortStringList;
1332 }
1333
1334 private int getSecondIndicator(BibMarcRecord record, String fieldName) {
1335 int ind2Value = 0;
1336 String fieldTags = documentSearchConfig.FIELDS_TO_TAGS_2_INCLUDE_MAP.get(fieldName);
1337 String[] tagValueList = null;
1338 if (fieldTags != null) {
1339 tagValueList = fieldTags.split(",");
1340 List<DataField> dataFieldList = record.getDataFields();
1341 String ind2 = null;
1342 boolean isVisit = true;
1343 for (DataField dataField : dataFieldList) {
1344 String tag = dataField.getTag();
1345 for (String tagValue : tagValueList) {
1346 StringBuffer sb = null;
1347 if (fieldName.equalsIgnoreCase(AUTHOR_SORT) || fieldName.equalsIgnoreCase(TITLE_SORT)) {
1348 sb = getTagValues(dataField, tag, tagValue);
1349 if (sb != null && sb.toString().length() > 0 && isVisit) {
1350 ind2 = dataField.getInd2();
1351 isVisit = false;
1352 }
1353
1354 }
1355 }
1356 }
1357 try {
1358 if (ind2 != null)
1359 ind2Value = Integer.parseInt(ind2);
1360
1361 } catch (Exception e) {
1362 ind2Value = -1;
1363 }
1364
1365 }
1366 return ind2Value;
1367 }
1368
1369 private StringBuffer getTagValues(DataField dataField, String tag, String tagValue) {
1370 StringBuffer sb = new StringBuffer();
1371 String[] tags = tagValue.split("-");
1372 for (String tagName : tags) {
1373 if (tag.equalsIgnoreCase(tagName)) {
1374 List<SubField> subFieldList = dataField.getSubFields();
1375 for (SubField subField : subFieldList) {
1376 sb.append(subField.getValue() + " ");
1377 }
1378
1379 }
1380 }
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390 return sb;
1391 }
1392
1393 public void bind(String holdingsId, List<String> bibIds) throws SolrServerException, IOException {
1394 List<SolrInputDocument> solrInputDocumentList = new ArrayList<SolrInputDocument>();
1395 updateHoldingsDocument(holdingsId, bibIds, solrInputDocumentList);
1396 updateBibDocument(holdingsId, bibIds, solrInputDocumentList);
1397 LOG.info("solrInputDocumentList-->" + solrInputDocumentList);
1398 SolrServer server = SolrServerManager.getInstance().getSolrServer();
1399 UpdateResponse updateResponse = server.add(solrInputDocumentList);
1400 server.commit();
1401 }
1402
1403 private void updateBibDocument(String holdingsId, List<String> bibIds, List<SolrInputDocument> solrInputDocumentList) {
1404 for (String bibId : bibIds) {
1405 SolrInputDocument bibSolrInputDocument = new SolrInputDocument();
1406 bibSolrInputDocument.addField(AtomicUpdateConstants.UNIQUE_ID, bibId);
1407 Map<String, String> holdingsIdsMap = new HashMap<>();
1408 holdingsIdsMap.put(AtomicUpdateConstants.ADD, holdingsId);
1409 bibSolrInputDocument.setField(HOLDINGS_IDENTIFIER, holdingsIdsMap);
1410 solrInputDocumentList.add(bibSolrInputDocument);
1411 }
1412 }
1413
1414 private void updateHoldingsDocument(String holdingsId, List<String> bibIds, List<SolrInputDocument> solrInputDocumentList) throws SolrServerException {
1415 SolrInputDocument holdingsSolrInputDocument = new SolrInputDocument();
1416 holdingsSolrInputDocument.addField(AtomicUpdateConstants.UNIQUE_ID, holdingsId);
1417 Map<String, List<String>> bibIdsMap = new HashMap<String, List<String>>();
1418 bibIdsMap.put(AtomicUpdateConstants.ADD, bibIds);
1419 holdingsSolrInputDocument.setField(BIB_ID, bibIdsMap);
1420 holdingsSolrInputDocument.setField(IS_BOUND_WITH, Boolean.TRUE);
1421 solrInputDocumentList.add(holdingsSolrInputDocument);
1422 updateItemDocsOfHoldings(holdingsId, solrInputDocumentList, bibIdsMap);
1423 }
1424
1425 private void updateItemDocsOfHoldings(String holdingsId, List<SolrInputDocument> solrInputDocumentList, Map<String, List<String>> bibIdsMap) {
1426 SolrDocument holdingsSolrDocument = getSolrDocumentByUUID(holdingsId);
1427 List<String> itemIdentifierList = null;
1428 Object itemIdentifier = holdingsSolrDocument.getFieldValue(ITEM_IDENTIFIER);
1429 if (itemIdentifier instanceof List) {
1430 itemIdentifierList = (List<String>) itemIdentifier;
1431 } else if (itemIdentifier instanceof String) {
1432 itemIdentifierList = new ArrayList<String>();
1433 itemIdentifierList.add((String) itemIdentifier);
1434 }
1435 for (String itemId : itemIdentifierList) {
1436 SolrInputDocument itemSolrInputDocument = new SolrInputDocument();
1437 itemSolrInputDocument.addField(AtomicUpdateConstants.UNIQUE_ID, itemId);
1438 itemSolrInputDocument.setField(BIB_ID, bibIdsMap);
1439 solrInputDocumentList.add(itemSolrInputDocument);
1440 }
1441 }
1442
1443 public void bindAnalytics(String seriesHoldingsId, List<String> itemIds, String createOrBreak) throws SolrServerException, IOException {
1444 List<SolrInputDocument> solrInputDocumentList = new ArrayList<SolrInputDocument>();
1445 updateHoldingsDocument(seriesHoldingsId, itemIds, solrInputDocumentList, createOrBreak);
1446 updateItemDocument(seriesHoldingsId, itemIds, solrInputDocumentList, createOrBreak);
1447 LOG.info("solrInputDocumentList-->" + solrInputDocumentList);
1448 SolrServer server = SolrServerManager.getInstance().getSolrServer();
1449 UpdateResponse updateResponse = server.add(solrInputDocumentList);
1450 server.commit();
1451 }
1452
1453 private void updateHoldingsDocument(String seriesHoldingsId, List<String> itemIds, List<SolrInputDocument> holdingsSolrInputDocumentList, String createOrBreak) {
1454 SolrInputDocument holdingsSolrInputDocument = new SolrInputDocument();
1455 holdingsSolrInputDocument.addField(AtomicUpdateConstants.UNIQUE_ID, seriesHoldingsId);
1456 Map<String, List<String>> itemIdsMap = new HashMap<String, List<String>>();
1457 if (createOrBreak.equalsIgnoreCase(CREATE_RELATION)) {
1458 itemIdsMap.put(AtomicUpdateConstants.ADD, itemIds);
1459 holdingsSolrInputDocument.setField(ITEM_IDENTIFIER, itemIdsMap);
1460 holdingsSolrInputDocument.setField(IS_SERIES, Boolean.TRUE);
1461 holdingsSolrInputDocument.setField(IS_ANALYTIC, Boolean.TRUE);
1462 } else if (createOrBreak.equalsIgnoreCase(BREAK_RELATION)) {
1463 itemIdsMap.put(AtomicUpdateConstants.REMOVE, itemIds);
1464 holdingsSolrInputDocument.addField(ITEM_IDENTIFIER, itemIdsMap);
1465 if (!hasAnalyticItemInHoldings(seriesHoldingsId, itemIds)) {
1466 Map analyticMap = new HashMap();
1467 analyticMap.put(AtomicUpdateConstants.SET, null);
1468 holdingsSolrInputDocument.setField(IS_SERIES, Boolean.FALSE);
1469 holdingsSolrInputDocument.setField(IS_ANALYTIC, analyticMap);
1470 }
1471 }
1472 holdingsSolrInputDocumentList.add(holdingsSolrInputDocument);
1473 }
1474
1475 private void updateItemDocument(String seriesHoldingsId, List<String> itemIds, List<SolrInputDocument> solrInputDocumentList, String createOrBreak) {
1476 for (String itemId : itemIds) {
1477 SolrInputDocument itemSolrInputDocument = new SolrInputDocument();
1478 itemSolrInputDocument.addField(AtomicUpdateConstants.UNIQUE_ID, itemId);
1479 Map holdingsIdsMap = new HashMap();
1480 if (createOrBreak.equalsIgnoreCase(CREATE_RELATION)) {
1481 holdingsIdsMap.put(AtomicUpdateConstants.ADD, seriesHoldingsId);
1482 itemSolrInputDocument.setField(HOLDINGS_IDENTIFIER, holdingsIdsMap);
1483 itemSolrInputDocument.setField(IS_ANALYTIC, Boolean.TRUE);
1484 updateHoldingsDocsOfAnalyticItem(seriesHoldingsId, itemId, itemIds, solrInputDocumentList, CREATE_RELATION);
1485 } else if (createOrBreak.equalsIgnoreCase(BREAK_RELATION)) {
1486 holdingsIdsMap.put(AtomicUpdateConstants.REMOVE, seriesHoldingsId);
1487 itemSolrInputDocument.addField(HOLDINGS_IDENTIFIER, holdingsIdsMap);
1488 itemSolrInputDocument.setField(IS_ANALYTIC, Boolean.FALSE);
1489 updateHoldingsDocsOfAnalyticItem(seriesHoldingsId, itemId, itemIds, solrInputDocumentList, BREAK_RELATION);
1490 }
1491 solrInputDocumentList.add(itemSolrInputDocument);
1492 }
1493 }
1494
1495 private void updateHoldingsDocsOfAnalyticItem(String seriesHoldingsId, String itemId, List<String> itemIds, List<SolrInputDocument> solrInputDocumentList, String createOrBreak) {
1496 List<String> holdingsIdentifierList = null;
1497 SolrDocument itemSolrDocument = getSolrDocumentByUUID(itemId);
1498 Object holdingsIdentifier = itemSolrDocument.getFieldValue(HOLDINGS_IDENTIFIER);
1499 if (holdingsIdentifier instanceof List) {
1500 holdingsIdentifierList = (List<String>) holdingsIdentifier;
1501 } else if (holdingsIdentifier instanceof String) {
1502 holdingsIdentifierList = new ArrayList<String>();
1503 holdingsIdentifierList.add((String) holdingsIdentifier);
1504 }
1505 Map analyticMap = new HashMap();
1506 if (CollectionUtils.isNotEmpty(holdingsIdentifierList)) {
1507 for (String holdingsId : holdingsIdentifierList) {
1508 if (!holdingsId.equalsIgnoreCase(seriesHoldingsId)) {
1509 if (createOrBreak.equalsIgnoreCase(CREATE_RELATION)) {
1510 analyticMap.put(AtomicUpdateConstants.SET, Boolean.TRUE);
1511 SolrInputDocument holdingsSolrInputDocument = new SolrInputDocument();
1512 holdingsSolrInputDocument.addField(AtomicUpdateConstants.UNIQUE_ID, holdingsId);
1513 holdingsSolrInputDocument.addField(IS_ANALYTIC, analyticMap);
1514 solrInputDocumentList.add(holdingsSolrInputDocument);
1515 } else if (createOrBreak.equalsIgnoreCase(BREAK_RELATION)) {
1516 if (!hasAnalyticItemInHoldings(holdingsId, itemIds)) {
1517 analyticMap.put(AtomicUpdateConstants.SET, null);
1518 SolrInputDocument holdingsSolrInputDocument = new SolrInputDocument();
1519 holdingsSolrInputDocument.addField(AtomicUpdateConstants.UNIQUE_ID, holdingsId);
1520 holdingsSolrInputDocument.addField(IS_ANALYTIC, analyticMap);
1521 solrInputDocumentList.add(holdingsSolrInputDocument);
1522 }
1523 }
1524 }
1525 }
1526 }
1527 }
1528
1529 private Boolean hasAnalyticItemInHoldings(String holdingsId, List<String> itemIds) {
1530 SolrDocument holdingsSolrDocument = getSolrDocumentByUUID(holdingsId);
1531 List<String> itemIdentifierList = null;
1532 Object itemIdentifier = holdingsSolrDocument.getFieldValue(ITEM_IDENTIFIER);
1533 if (itemIdentifier instanceof List) {
1534 itemIdentifierList = (List<String>) itemIdentifier;
1535 } else if (itemIdentifier instanceof String) {
1536 itemIdentifierList = new ArrayList<String>();
1537 itemIdentifierList.add((String) itemIdentifier);
1538 }
1539 boolean hasAnalytic = false;
1540 for (String itemId : itemIdentifierList) {
1541 if (!itemIds.contains(itemId)) {
1542 SolrDocument itemSolrDocument = getSolrDocumentByUUID(itemId);
1543 if (itemSolrDocument.getFieldValue(IS_ANALYTIC) instanceof Boolean) {
1544 hasAnalytic = (Boolean) itemSolrDocument.getFieldValue(IS_ANALYTIC);
1545 if (hasAnalytic) {
1546 break;
1547 }
1548 }
1549 }
1550 }
1551 return hasAnalytic;
1552 }
1553
1554
1555 public void unbindOne(List<String> holdingsIds, String bibId) throws SolrServerException, IOException {
1556 List<SolrInputDocument> solrInputDocumentList = new ArrayList<>();
1557 updateBibToUnbindOneBib(holdingsIds, bibId, solrInputDocumentList);
1558 SolrServer server = SolrServerManager.getInstance().getSolrServer();
1559 server.add(solrInputDocumentList);
1560 server.commit();
1561 }
1562
1563 public void unbindAll(List<String> holdingsIds, String bibId) throws SolrServerException, IOException {
1564 List<SolrInputDocument> solrInputDocumentList = new ArrayList<>();
1565 updateBibToUnbindAllBib(holdingsIds, bibId, solrInputDocumentList);
1566 SolrServer server = SolrServerManager.getInstance().getSolrServer();
1567 server.add(solrInputDocumentList);
1568 server.commit();
1569 }
1570
1571 private void updateBibToUnbindOneBib(List<String> holdingsIds, String bibId, List<SolrInputDocument> solrInputDocumentList) throws SolrServerException {
1572 SolrDocument bibSolrDocument = getSolrDocumentByUUID(bibId);
1573 Object object = bibSolrDocument.getFieldValue(HOLDINGS_IDENTIFIER);
1574 List<String> holdingsIdsSolr = new ArrayList<>();
1575 if (object instanceof List) {
1576 holdingsIdsSolr = (List<String>) object;
1577 } else if (object instanceof String) {
1578 holdingsIdsSolr.add((String) object);
1579 }
1580 for (String holdingsId : holdingsIds) {
1581 holdingsIdsSolr.remove(holdingsId);
1582 SolrDocument holdingsSolrDocument = getSolrDocumentByUUID(holdingsId);
1583 object = holdingsSolrDocument.getFieldValue(BIB_IDENTIFIER);
1584 List<String> bibIds = new ArrayList<>();
1585 if (object instanceof List) {
1586 bibIds = (List<String>) object;
1587
1588 } else if (object instanceof String) {
1589 bibIds.add((String) object);
1590 }
1591 bibIds.remove(bibId);
1592 holdingsSolrDocument.setField(BIB_IDENTIFIER, bibIds);
1593 holdingsSolrDocument.setField("isBoundwith", false);
1594 solrInputDocumentList.add(buildSolrInputDocFromSolrDoc(holdingsSolrDocument));
1595 }
1596 bibSolrDocument.setField(HOLDINGS_IDENTIFIER, holdingsIdsSolr);
1597 solrInputDocumentList.add(buildSolrInputDocFromSolrDoc(bibSolrDocument));
1598 }
1599
1600 private void updateBibToUnbindAllBib(List<String> holdingsIds, String bibId, List<SolrInputDocument> solrInputDocumentList) throws SolrServerException {
1601 Object object;
1602 Set<String> removedBibIdList = new HashSet<>();
1603 for (String holdingsId : holdingsIds) {
1604 SolrDocument holdingsSolrDocument = getSolrDocumentByUUID(holdingsId);
1605 object = holdingsSolrDocument.getFieldValue(BIB_IDENTIFIER);
1606 List<String> bidIds = new ArrayList<>();
1607 Set<String> bidIdsToAdd = new HashSet<>();
1608 if (object instanceof List) {
1609 bidIds = (List<String>) object;
1610 } else if (object instanceof String) {
1611 bidIds.add((String) object);
1612 }
1613 bidIdsToAdd.addAll(bidIds);
1614 for (String bibIdToRemove : bidIds) {
1615 if (!bibIdToRemove.equals(bibId)) {
1616 bidIdsToAdd.remove(bibIdToRemove);
1617 removedBibIdList.add(bibIdToRemove);
1618 }
1619 }
1620 holdingsSolrDocument.setField(BIB_IDENTIFIER, bidIdsToAdd);
1621 holdingsSolrDocument.setField("isBoundwith", false);
1622 solrInputDocumentList.add(buildSolrInputDocFromSolrDoc(holdingsSolrDocument));
1623 }
1624 for (String removedBibId : removedBibIdList) {
1625 SolrDocument bibsSolrDocument = getSolrDocumentByUUID(removedBibId);
1626 object = bibsSolrDocument.getFieldValue(HOLDINGS_IDENTIFIER);
1627 List<String> holdingsIdList = new ArrayList<>();
1628 Set<String> holdingsIdSet = new HashSet<>();
1629 if (object instanceof List) {
1630 holdingsIdList = (List<String>) object;
1631 } else if (object instanceof String) {
1632 holdingsIdList.add((String) object);
1633 }
1634 holdingsIdSet.addAll(holdingsIdList);
1635 for (String holdingsId : holdingsIds) {
1636 holdingsIdList.remove(holdingsId);
1637 }
1638 bibsSolrDocument.setField(HOLDINGS_IDENTIFIER, holdingsIdList);
1639 solrInputDocumentList.add(buildSolrInputDocFromSolrDoc(bibsSolrDocument));
1640 }
1641 }
1642
1643
1644 }