001package org.kuali.ole.batch.impl; 002 003import org.apache.commons.lang.StringUtils; 004import org.apache.log4j.Logger; 005import org.apache.solr.common.SolrDocument; 006import org.kuali.ole.BibliographicRecordHandler; 007import org.kuali.ole.batch.bo.OLEBatchProcessProfileBo; 008import org.kuali.ole.batch.helper.EInstanceMappingHelper; 009import org.kuali.ole.batch.helper.InstanceMappingHelper; 010import org.kuali.ole.batch.helper.OLEBatchProcessDataHelper; 011import org.kuali.ole.batch.service.ExportDataService; 012import org.kuali.ole.describe.service.DocstoreHelperService; 013import org.kuali.ole.docstore.discovery.solr.work.bib.WorkBibCommonFields; 014import org.kuali.ole.docstore.discovery.solr.work.instance.WorkInstanceCommonFields; 015import org.kuali.ole.docstore.model.enums.DocType; 016import org.kuali.ole.docstore.model.xmlpojo.work.bib.marc.DataField; 017import org.kuali.ole.docstore.model.xmlpojo.work.instance.oleml.InstanceCollection; 018import org.kuali.ole.pojo.bib.BibliographicRecord; 019 020import java.util.ArrayList; 021import java.util.Collections; 022import java.util.Date; 023import java.util.List; 024 025import static org.kuali.ole.OLEConstants.OLEBatchProcess.*; 026 027/** 028 * Created with IntelliJ IDEA. 029 * User: meenrajd 030 * Date: 7/5/13 031 * Time: 2:38 PM 032 */ 033public class ExportDataServiceImpl implements ExportDataService { 034 035 private static final Logger LOG = Logger.getLogger(ExportDataServiceImpl.class); 036 037 private static volatile ExportDataService service = new ExportDataServiceImpl(); 038 private static volatile List<String> bibIdList = new ArrayList<>(); 039 040 private ExportDataServiceImpl() { 041 } 042 043 public static synchronized ExportDataService getInstance() { 044 bibIdList.clear(); 045 return service; 046 } 047 048 /** 049 * public method to retrieves the list of bib / instance records for the given profile 050 * 051 * Returns object array - array size is 4 052 * Following positions of the array has the details of the data it contains 053 * 0 - has the count of bib records 054 * 1 - List with xml data of the bib records , if the export type is marc xml the list will have only one item will 055 * all the bib records in a single String object, if the export type is marc the list will have each record as an item 056 * 2 - Errors generated 057 * 3 - Error count 058 * 059 * @param solrDocumentList 060 * @param profile 061 * @return 062 * @throws Exception 063 */ 064 public Object[] getExportDataBySolr(List<SolrDocument> solrDocumentList, OLEBatchProcessProfileBo profile) throws Exception { 065 List<String> bibMarcRecordList = new ArrayList<String>(); 066 DocstoreHelperService helperService = new DocstoreHelperService(); 067 List<BibliographicRecord> bibRecords = new ArrayList<BibliographicRecord>(); 068 StringBuilder errBuilder = new StringBuilder(); 069 int errCnt = 0; 070 for (SolrDocument solrDocument : solrDocumentList) { 071 try { 072 String bibId = getBibId(solrDocument); 073 if (bibIdList.contains(bibId)) continue; 074 else bibIdList.add(bibId); 075 List<String> instanceIdentifierList = new ArrayList<String>(); 076 if (solrDocument.getFieldValue(WorkBibCommonFields.DOC_TYPE).equals(DocType.INSTANCE.getDescription())) { 077 String instanceIdentifier = (String) solrDocument.getFieldValue(WorkBibCommonFields.ID); 078 instanceIdentifierList.add(instanceIdentifier); 079 } else if (solrDocument.getFieldValue(WorkInstanceCommonFields.INSTANCE_IDENTIFIER) != null) { 080 if (solrDocument.getFieldValue(WorkInstanceCommonFields.INSTANCE_IDENTIFIER) instanceof List) { 081 instanceIdentifierList = (List<String>) solrDocument.getFieldValue(WorkInstanceCommonFields.INSTANCE_IDENTIFIER); 082 } else { 083 String instanceIdentifier = (String) solrDocument.getFieldValue(WorkInstanceCommonFields.INSTANCE_IDENTIFIER); 084 instanceIdentifierList.add(instanceIdentifier); 085 } 086 } 087 try { 088 BibliographicRecord bibliographicRecord = helperService.getBibliographicRecord(bibId); 089 //Intance mapping 090 if (!instanceIdentifierList.isEmpty() && !profile.getOleBatchProcessProfileDataMappingOptionsBoList().isEmpty() 091 && StringUtils.isNotEmpty(profile.getDataToExport()) && profile.getDataToExport().equalsIgnoreCase(OLEBatchProcess.EXPORT_BIB_AND_INSTANCE)) { 092 try { 093 getInstanceDetails(bibliographicRecord, instanceIdentifierList, profile, errBuilder); 094 LOG.info("Instance data mapping completed"); 095 } catch (Exception ex) { 096 LOG.error("Instance data mapping Error for Bib record id::" + bibliographicRecord.getRecordId(),ex); 097 buildError(errBuilder,ERR_BIB,bibliographicRecord.getRecordId(),"Instance Id(s)",instanceIdentifierList.toString(), 098 ERR_CAUSE,ex.getMessage(),TIME_STAMP,new Date().toString()); 099 errCnt++; 100 continue; 101 } 102 } 103 //Marc record rename 104 if (!profile.getOleBatchProcessProfileRenameFieldsList().isEmpty()) { 105 try { 106 OLEBatchProcessDataHelper.getInstance().renameMarcFieldsSubFields(profile, bibliographicRecord); 107 LOG.info("Rename of bib marc records completed"); 108 } catch (Exception ex) { 109 LOG.error("Marc Record Rename error for Bib record id::" + bibliographicRecord.getRecordId(),ex); 110 buildError(errBuilder,ERR_BIB,bibliographicRecord.getRecordId(),ERR_CAUSE,ex.getMessage()," ::At:: ","renameMarcFieldsSubFields",TIME_STAMP,new Date().toString()); 111 errCnt++; 112 continue; 113 } 114 } 115 //Marc record delete 116 if (!profile.getOleBatchProcessProfileDeleteFieldsList().isEmpty()) { 117 try { 118 OLEBatchProcessDataHelper.getInstance().deleteFieldsSubfields(profile, bibliographicRecord); 119 LOG.info("Deletion of bib marc records completed"); 120 } catch (Exception ex) { 121 LOG.error("Marc record delete Error for Bib record id::" + bibliographicRecord.getRecordId(),ex); 122 buildError(errBuilder,ERR_BIB,bibliographicRecord.getRecordId(),ERR_CAUSE,ex.getMessage()," ::At:: ","deleteFieldsSubfields",TIME_STAMP,new Date().toString()); 123 errCnt++; 124 continue; 125 } 126 } 127 //Setting record id as 001 field 128 try { 129 OLEBatchProcessDataHelper.getInstance().setRecordNumber(bibliographicRecord, solrDocument.getFieldValue(WorkBibCommonFields.LOCALID_SEARCH).toString()); 130 } catch (Exception ex) { 131 LOG.error("Error while setting record number for record id::" + bibliographicRecord.getRecordId(),ex); 132 buildError(errBuilder,ERR_BIB,bibliographicRecord.getRecordId(),ERR_CAUSE,ex.getMessage()," ::At:: ","setRecordNumber",TIME_STAMP,new Date().toString()); 133 errCnt++; 134 continue; 135 } 136 bibRecords.add(bibliographicRecord); 137 } catch (Exception ex) { 138 LOG.error("Error while getting bib information for record id::" + bibId,ex); 139 buildError(errBuilder,ERR_BIB,bibId,ERR_CAUSE,ex.getMessage()," ::At:: ","getBibliographicRecord",TIME_STAMP,new Date().toString()); 140 errCnt++; 141 } 142 } catch (Exception ex) { 143 LOG.error("Error while Exporting bibs :: No of bibs processed while error occured :: " + bibIdList.size(),ex); 144 145 if (!bibIdList.isEmpty()) { 146 LOG.error("Bib record where error occured: " + bibIdList.get(bibIdList.size() - 1), ex); 147 buildError(errBuilder,ERR_BIB,bibIdList.get(bibIdList.size() - 1),ERR_CAUSE,ex.getMessage()," ::At:: ","getBibliographicRecord-P",TIME_STAMP,new Date().toString()); 148 errCnt++; 149 } 150 } 151 }//End loop of bib ids 152 BibliographicRecordHandler bibliographicRecordHandler = new BibliographicRecordHandler(errBuilder); 153 try{ 154 if(profile.getFileType().equalsIgnoreCase(OLEBatchProcess.MARCXML)){ 155 getResult(bibliographicRecordHandler,bibRecords,bibMarcRecordList); 156 }else if(profile.getFileType().equalsIgnoreCase(OLEBatchProcess.MARC)){ 157 for(BibliographicRecord record : bibRecords){ 158 getResult(bibliographicRecordHandler,record,bibMarcRecordList); 159 } 160 } 161 }catch (Exception ex) { 162 LOG.error("Error while Exporting bibs :: No of bibs processed while error occured :: " + bibIdList.size(),ex); 163 buildError(errBuilder,ERR_CAUSE,"Error while getting bib data::"+ex.getMessage(),TIME_STAMP,new Date().toString()); 164 } 165 return new Object[]{String.valueOf(bibRecords.size()), bibMarcRecordList, errBuilder.toString(), String.valueOf((errCnt + bibliographicRecordHandler.getErrCnt()))}; 166 167 } 168 169 170 /** 171 * Method retrives the list of instances record for the bib record with the given instanceIdentifier list 172 * 173 * @param bibliographicRecord 174 * @param instanceIdentifierList 175 * @param profile 176 */ 177 private void getInstanceDetails(BibliographicRecord bibliographicRecord, List<String> instanceIdentifierList, OLEBatchProcessProfileBo profile, StringBuilder errBuilder) throws Exception { 178 DocstoreHelperService helperService = new DocstoreHelperService(); 179 List<DataField> dataFields = bibliographicRecord.getDatafields(); 180 for (String instanceIdentifier : instanceIdentifierList) { 181 Object object = helperService.getInstanceCollectionData(instanceIdentifier); 182 List<DataField> instanceItemDataField = Collections.emptyList(); 183 if(object instanceof InstanceCollection){ 184 InstanceCollection instanceCollection = (InstanceCollection)object; 185 instanceItemDataField = new InstanceMappingHelper().generateDataField(instanceCollection, profile, errBuilder); 186 }else if(object instanceof org.kuali.ole.docstore.model.xmlpojo.work.einstance.oleml.InstanceCollection){ 187 org.kuali.ole.docstore.model.xmlpojo.work.einstance.oleml.InstanceCollection instanceCollection = (org.kuali.ole.docstore.model.xmlpojo.work.einstance.oleml.InstanceCollection)object; 188 if(instanceCollection!=null){ 189 LOG.info("eInstance Collection :: "+instanceCollection.getEInstance().toString()+"processed"); 190 instanceItemDataField = new EInstanceMappingHelper().generateDataField(instanceCollection,profile,errBuilder); 191 } 192 193 } 194 dataFields.addAll(instanceItemDataField); 195 } 196 } 197 198 /** 199 * Pubic method that retrieves the list of bib / instance records for the given profile an additional task this method 200 * does is to prepare solr query to get the solr doc list 201 * 202 * @param bibIds 203 * @param profile 204 * @return 205 * @throws Exception 206 */ 207 public Object[] getExportDataByBibIds(List<String> bibIds, OLEBatchProcessProfileBo profile) throws Exception { 208 //TODO need to prepare the solr query to retrieve the solr document list for the given bib ids 209 List<SolrDocument> solrDocumentList = Collections.EMPTY_LIST; 210 return getExportDataBySolr(solrDocumentList, profile); 211 } 212 213 /** 214 * returns the bib id for the solr document 215 * 216 * @param solrDocument 217 * @return 218 */ 219 private String getBibId(SolrDocument solrDocument) { 220 String docType = solrDocument.getFieldValue(WorkBibCommonFields.DOC_TYPE).toString(); 221 if (docType.equals(DocType.BIB.getDescription())) { 222 return solrDocument.getFieldValue(WorkBibCommonFields.ID).toString(); 223 } else if (docType.equals(DocType.INSTANCE.getDescription()) 224 || docType.equals(DocType.HOLDINGS.getDescription()) 225 || docType.equals(DocType.ITEM.getDescription())) { 226 return solrDocument.getFieldValue(WorkInstanceCommonFields.BIB_IDENTIFIER).toString(); 227 } else { 228 return ""; 229 } 230 } 231 232 private void getResult(BibliographicRecordHandler bibliographicRecordHandler,List<BibliographicRecord> bibRecords,List<String> bibMarcRecordList){ 233 String bibMarcRecord = bibliographicRecordHandler.generateXML(bibRecords); 234 bibMarcRecordList.add(bibMarcRecord); 235 } 236 237 private void getResult(BibliographicRecordHandler bibliographicRecordHandler,BibliographicRecord bibRecords,List<String> bibMarcRecordList){ 238 String bibMarcRecord = bibliographicRecordHandler.generateXML(bibRecords); 239 bibMarcRecordList.add(bibMarcRecord); 240 } 241 242 private void buildError(StringBuilder errBuilder,String...errorString){ 243 for(String str : errorString){ 244 errBuilder.append(str).append(COMMA); 245 } 246 errBuilder.append(lineSeparator); 247 } 248}