001package org.kuali.ole.docstore.discovery.service;
002
003import com.thoughtworks.xstream.XStream;
004import org.apache.commons.io.FileUtils;
005import org.apache.solr.client.solrj.SolrQuery;
006import org.apache.solr.client.solrj.SolrServer;
007import org.apache.solr.client.solrj.response.QueryResponse;
008import org.apache.solr.common.SolrDocument;
009import org.kuali.ole.BibliographicRecordHandler;
010import org.kuali.ole.RepositoryManager;
011import org.kuali.ole.docstore.discovery.bo.OleDiscoveryMarcExportProfile;
012import org.kuali.ole.docstore.discovery.bo.OleDiscoveryMarcMappingField;
013import org.kuali.ole.docstore.model.xmlpojo.work.bib.marc.DataField;
014import org.kuali.ole.docstore.common.document.content.instance.InstanceCollection;
015import org.kuali.ole.pojo.OleException;
016import org.kuali.ole.pojo.bib.BibliographicRecord;
017import org.kuali.ole.pojo.bib.Collection;
018import org.kuali.ole.repository.CheckoutManager;
019import org.marc4j.MarcXmlReader;
020import org.marc4j.MarcXmlWriter;
021import org.marc4j.marc.Record;
022import org.slf4j.Logger;
023import org.slf4j.LoggerFactory;
024
025import javax.jcr.Node;
026import javax.jcr.NodeIterator;
027import javax.jcr.RepositoryException;
028import java.io.ByteArrayInputStream;
029import java.io.File;
030import java.io.FileOutputStream;
031import java.io.InputStream;
032import java.util.ArrayList;
033import java.util.Iterator;
034import java.util.List;
035
036/**
037 * Created with IntelliJ IDEA.
038 * User: ?
039 * Date: 2/19/13
040 * Time: 12:42 PM
041 * To change this template use File | Settings | File Templates.
042 */
043public class OleDocstoreDumpService {
044    private static final Logger LOG = LoggerFactory.getLogger(OleDocstoreDumpService.class);
045
046    public String exportDocstoreData(String requestXML) throws Exception {
047        OleDiscoveryMarcExportProfile oleDiscMarcExpProfile = getMarcRequest(requestXML);
048        if (browseRepositoryContentForDataExport("work", "bibliographic", "marc", oleDiscMarcExpProfile)) {
049            return "Success";
050        } else {
051            return "Failed";
052        }
053    }
054
055    private boolean browseRepositoryContentForDataExport(String category, String type,
056                                                         String format, OleDiscoveryMarcExportProfile oleDiscMarcExpProfile) throws RepositoryException, OleException {
057        try {
058            int fileCount = 0;
059            List<String> bibMarcRecordList = new ArrayList<String>();
060            List<String> recordList = new ArrayList<String>();
061            BibliographicRecordHandler bibliographicRecordHandler = new BibliographicRecordHandler();
062            RepositoryManager oleRepositoryManager = RepositoryManager.getRepositoryManager();
063            Node rootNode = oleRepositoryManager.getSession("repositoryBrowser", "getbibUuids").getRootNode();
064            Node categoryNode = rootNode.getNode(category);
065            Node typeNode = categoryNode.getNode(type);
066            Node formatNode = typeNode.getNode(format);
067            Iterator<Node> formatIterator = formatNode.getNodes();
068            while (formatIterator.hasNext()) {
069                Node levelNode = formatIterator.next();
070                Iterator<Node> levelNodeIterator = levelNode.getNodes();
071                while (levelNodeIterator.hasNext()) {
072                    Node fileNode = levelNodeIterator.next();
073                    if (fileNode.getName().equalsIgnoreCase("marcFile")) {
074                        fileNode.getIdentifier();           // this its self should give you all the uuids
075                        String bibId = fileNode.getProperty("jcr:uuid").getValue().getString(); // this should give you uuid values
076                        NodeIterator nodes = fileNode.getNodes();
077                        while (nodes.hasNext()) {
078                            Node contentNode = nodes.nextNode();
079                            if (contentNode.hasProperty("jcr:data")) {
080                                System.out.println("uuid: -----> " + contentNode.getIdentifier());
081                                String bibContent = contentNode.getProperty("jcr:data").getString(); // other way
082                                Collection collection = bibliographicRecordHandler.fromXML(bibContent);
083                                BibliographicRecord bibliographicRecord = new BibliographicRecord();
084                                bibliographicRecord = collection.getRecords().get(0);
085                                bibliographicRecord = getInstanceDetails(bibId, bibliographicRecord, oleDiscMarcExpProfile);
086                                String bibMarcRecord = bibliographicRecordHandler.generateXML(bibliographicRecord);
087                                bibMarcRecordList.add(bibMarcRecord);
088                            }
089                        }
090                    } else {
091                        levelNodeIterator = fileNode.getNodes();
092                    }
093                }
094            }
095            int totalBibMarcRecords = bibMarcRecordList.size();
096            int noOfRecords = oleDiscMarcExpProfile.getNoOfRecords();
097            int i = 0;
098            if (noOfRecords > 0) {
099                while (i < totalBibMarcRecords) {
100                    List<String> records = new ArrayList<String>();
101                    for (int j = 0; j < noOfRecords; j++) {
102                        records.add(bibMarcRecordList.get(i));
103                        if (i == totalBibMarcRecords - 1) {
104                            i++;
105                            break;
106                        }
107                        i++;
108                    }
109                    StringBuffer recordContent = new StringBuffer();
110                    recordList.clear();
111                    for (int k = 0; k < records.size(); k++) {
112                        recordList.add(records.get(k));
113                        recordContent.append(recordList.get(k) + "\n");
114                    }
115                    fileCount++;
116                    String xmlVersion = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
117                    if (oleDiscMarcExpProfile.getExportFormat().equalsIgnoreCase("MARC XML"))
118                        writeFileToLocation(xmlVersion + recordContent.toString(), oleDiscMarcExpProfile.getExportTo(), fileCount);
119                    else if (oleDiscMarcExpProfile.getExportFormat().equalsIgnoreCase("MARC21"))
120                        generateMarcFromXml(xmlVersion + recordContent.toString(), oleDiscMarcExpProfile.getExportTo(), fileCount);
121                    else
122                        return false;
123                    records.clear();
124                }
125            } else {
126                return false;
127            }
128        } catch (Exception e) {
129            LOG.error(e.getMessage(), e);
130            return false;
131        }
132        return true;
133    }
134
135    private OleDiscoveryMarcExportProfile getMarcRequest(String marcXml) {
136        XStream xstream = new XStream();
137        xstream.alias("request", OleDiscoveryMarcExportProfile.class);
138        xstream.alias("exportProfiles", OleDiscoveryMarcExportProfile.class);
139        xstream.alias("exportProfile", OleDiscoveryMarcExportProfile.class);
140        xstream.aliasField("exportMappingFields", OleDiscoveryMarcExportProfile.class, "oleDiscoveryMarcMappingFields");
141        xstream.alias("exportMappingField", OleDiscoveryMarcMappingField.class);
142
143        OleDiscoveryMarcExportProfile oleDiscMarcExpProfile = (OleDiscoveryMarcExportProfile) xstream.fromXML(marcXml);
144        return oleDiscMarcExpProfile;
145    }
146
147
148    public BibliographicRecord getInstanceDetails(String bibUUID, BibliographicRecord bibliographicRecord, OleDiscoveryMarcExportProfile oleDiscMarcExpProfile) {
149        try {
150            SolrQuery solrQuery = new SolrQuery();
151            solrQuery.setQuery("id:" + bibUUID);
152            solrQuery.setRows(500);
153            SolrServer server = SolrServerManager.getInstance().getSolrServer();
154            QueryResponse response = server.query(solrQuery);
155            List<SolrDocument> solrDocumentList = response.getResults();
156            for (SolrDocument solrDocument : solrDocumentList) {
157                if (solrDocument.getFieldValue("instanceIdentifier") instanceof List) {
158                    List<String> instanceIdentifierList = (List<String>) solrDocument.getFieldValue("instanceIdentifier");
159                    for (String instanceIdentifier : instanceIdentifierList) {
160                        LOG.info("Instant Identifier Value is :" + instanceIdentifier);
161                        CheckoutManager checkoutManager = new CheckoutManager();
162                        String instanceOutput = checkoutManager.checkOut(instanceIdentifier, null, "checkout");
163                        OleDocstoreDataRetrieveService oleDocstoreDataRetrieveService = new OleDocstoreDataRetrieveService();
164                        InstanceCollection instanceCollection = oleDocstoreDataRetrieveService.getInstanceCollection(instanceOutput);
165                        OleInstanceToMarcConvertor oleInstanceToMarcConvertor = new OleInstanceToMarcConvertor();
166                        List<DataField> dataFields = bibliographicRecord.getDatafields();
167                        List<DataField> instanceItemDataField = oleInstanceToMarcConvertor.generateDataField(instanceCollection, oleDiscMarcExpProfile);
168                        dataFields.addAll(instanceItemDataField);
169                    }
170                } else {
171                    String instanceIdentifier = (String) solrDocument.getFieldValue("instanceIdentifier");
172                    LOG.info("Instant Identifier Value is :" + instanceIdentifier);
173                    CheckoutManager checkoutManager = new CheckoutManager();
174                    String instanceOutput = checkoutManager.checkOut(instanceIdentifier, null, "checkout");
175                    OleDocstoreDataRetrieveService oleDocstoreDataRetrieveService = new OleDocstoreDataRetrieveService();
176                    InstanceCollection instanceCollection = oleDocstoreDataRetrieveService.getInstanceCollection(instanceOutput);
177                    OleInstanceToMarcConvertor oleInstanceToMarcConvertor = new OleInstanceToMarcConvertor();
178                    List<DataField> dataFields = bibliographicRecord.getDatafields();
179                    List<DataField> instanceItemDataField = oleInstanceToMarcConvertor.generateDataField(instanceCollection, oleDiscMarcExpProfile);
180                    dataFields.addAll(instanceItemDataField);
181                }
182            }
183
184        } catch (Exception e) {
185            LOG.error(e.getMessage(), e);
186        }
187        return bibliographicRecord;
188    }
189
190    private void writeFileToLocation(String bibContent, String location, int fileName) throws Exception {
191        LOG.info("Docstore dump location : " + location);
192        File dumpFile = new File(location + "/" + fileName + ".xml");
193        FileUtils.writeStringToFile(dumpFile, bibContent, "UTF-8");
194    }
195
196    private void generateMarcFromXml(String bibContent, String location, int fileName) throws Exception {
197        LOG.info("Docstore dump location : " + location);
198        InputStream input = new ByteArrayInputStream(bibContent.getBytes());
199        File file = new File(location + "/" + fileName + ".mrk");
200        if (!file.exists()) {
201            file.getParentFile().mkdirs();
202            file.createNewFile();
203        }
204        FileOutputStream fileOutputStream = new FileOutputStream(file);
205        MarcXmlReader marcXmlReader = new MarcXmlReader(input);
206        MarcXmlWriter marcXmlWriter = new MarcXmlWriter(fileOutputStream, true);
207
208        while (marcXmlReader.hasNext()) {
209            Record record = marcXmlReader.next();
210            marcXmlWriter.write(record);
211        }
212        marcXmlWriter.close();
213    }
214
215
216}