001/*
002 * Copyright 2011 The Kuali Foundation.
003 * 
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * 
008 * http://www.opensource.org/licenses/ecl2.php
009 * 
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.ole.web;
017
018import gov.loc.repository.bagit.utilities.FormatHelper;
019import org.apache.commons.fileupload.FileItem;
020import org.apache.commons.fileupload.disk.DiskFileItemFactory;
021import org.apache.commons.fileupload.servlet.ServletFileUpload;
022import org.apache.commons.io.FileUtils;
023import org.apache.commons.lang.StringUtils;
024import org.kuali.ole.DocumentUniqueIDPrefix;
025import org.kuali.ole.RepositoryManager;
026import org.kuali.ole.docstore.OleDocStoreException;
027import org.kuali.ole.docstore.discovery.service.OleDocstoreDataRetrieveService;
028import org.kuali.ole.docstore.discovery.service.OleDocstoreDumpService;
029import org.kuali.ole.docstore.discovery.service.ServiceLocator;
030import org.kuali.ole.docstore.model.enums.DocCategory;
031import org.kuali.ole.docstore.model.enums.DocFormat;
032import org.kuali.ole.docstore.model.enums.DocType;
033import org.kuali.ole.docstore.model.xmlpojo.ingest.*;
034import org.kuali.ole.docstore.model.xstream.ingest.RequestHandler;
035import org.kuali.ole.docstore.model.xstream.ingest.ResponseHandler;
036import org.kuali.ole.docstore.process.ProcessParameters;
037import org.kuali.ole.docstore.service.BeanLocator;
038import org.kuali.ole.docstore.service.IngestNIndexHandlerService;
039import org.kuali.ole.pojo.OleException;
040import org.kuali.ole.repository.DeleteManager;
041import org.kuali.ole.repository.DocumentStoreManager;
042import org.kuali.ole.repository.NodeHandler;
043import org.kuali.ole.service.OleUuidCheckWebService;
044import org.kuali.ole.service.OleWebServiceProvider;
045import org.kuali.ole.service.impl.OleWebServiceProviderImpl;
046import org.kuali.ole.utility.CompressUtils;
047import org.kuali.rice.core.api.config.property.ConfigContext;
048import org.slf4j.Logger;
049import org.slf4j.LoggerFactory;
050import javax.jcr.Node;
051import javax.jcr.RepositoryException;
052import javax.jcr.Session;
053import javax.servlet.ServletException;
054import javax.servlet.ServletOutputStream;
055import javax.servlet.http.HttpServlet;
056import javax.servlet.http.HttpServletRequest;
057import javax.servlet.http.HttpServletResponse;
058import java.io.*;
059import java.util.*;
060
061public class DocumentServlet
062        extends HttpServlet {
063
064    private static final long serialVersionUID = -3717561557966540651L;
065    private static final Logger LOG = LoggerFactory
066            .getLogger(DocumentServlet.class);
067    private CompressUtils compressUtils = new CompressUtils();
068    /**
069     * Singleton instance of DocumentStoreManager used by any servlet request.
070     */
071    private DocumentStoreManager documentStoreManager = BeanLocator.getDocumentStoreManager();
072    /**
073     * Singleton instance of IngestNIndexHandlerService used by any servlet request.
074     */
075    private IngestNIndexHandlerService ingestNIndexHandlerService = BeanLocator
076            .getIngestNIndexHandlerService();
077
078
079    /**
080     * @see HttpServlet#HttpServlet()
081     */
082    public DocumentServlet() {
083        super();
084    }
085
086    /**
087     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
088     */
089    protected void doPost(HttpServletRequest request, HttpServletResponse response)
090            throws ServletException, IOException {
091        String docAction = null;
092        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
093        //        String updatesEnabled = getServletConfig().getInitParameter("updatesEnabled");
094        //        boolean isUpdateEnabled = false;
095        //        if ("false".equalsIgnoreCase(updatesEnabled)) {
096        //            isUpdateEnabled = false;
097        //        } else {
098        //            isUpdateEnabled = true;
099        //        }
100        boolean isUpdateEnabled = ProcessParameters.IS_UPDATE_ENABLED;
101        LOG.debug("updateEnabled = " + isUpdateEnabled);
102        if (isMultipart) {
103            LOG.debug("Processing in Multipart : START");
104            try {
105                ArrayList<File> files = extractBagFilesFromRequest(request, response);
106                RequestHandler rh = new RequestHandler();
107                Request dsRequest = null;
108                for (File file : files)
109                    if (file.getName().equalsIgnoreCase("request.xml")) {
110                        String rqStr = FileUtils.readFileToString(file);
111                        dsRequest = rh.toObject(rqStr);
112                        for (RequestDocument rd : dsRequest.getRequestDocuments())
113                            if (rd.getDocumentName() != null)
114                                for (File fl : files)
115                                    if (fl.getName().equals(rd.getDocumentName())) {
116                                        rd.setDocumentName(fl.getAbsolutePath());
117                                        break;
118                                    }
119                        if ("ingest".equalsIgnoreCase(dsRequest.getOperation())) {
120                            if (isUpdateEnabled) {
121                                Response docStoreResponse = ingestNIndexHandlerService.ingestNIndexRequestDocuments(dsRequest);
122                                sendResponseBag(response, docStoreResponse);
123                            } else {
124                                sendUnavailableResponseString(response);
125                            }
126                        } else if ("checkOut".equalsIgnoreCase(dsRequest.getOperation())) {
127                            File output = documentStoreManager.checkOutMultiPart(dsRequest);
128                            sendResponseAsFile(response, output);
129                            output.delete();
130                        } else if ("checkIn".equalsIgnoreCase(dsRequest.getOperation())) {
131                            if (isUpdateEnabled) {
132                                Response dsResponse = new Response();
133                                checkIn(dsRequest, dsResponse);
134                                sendResponseBag(response, dsResponse);
135                            } else {
136                                sendUnavailableResponseString(response);
137                            }
138                        } else if ("delete".equalsIgnoreCase(dsRequest.getOperation())) {
139                            if (isUpdateEnabled) {
140                                Response dsResponse = processDeleteRequest(dsRequest);
141                                sendResponseBag(response, dsResponse);
142                            } else {
143                                sendUnavailableResponseString(response);
144                            }
145                        } else {
146                            response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid Request Operation: " + dsRequest.getOperation());
147                        }
148                        break;
149                    }
150                files.add(files.get(files.size() - 1).getParentFile());
151                compressUtils.deleteFiles(files);
152                LOG.debug("Got Files in here : " + files);
153            } catch (Exception e) {
154                LOG.error("Invalid Request : " + e.getMessage(), e);
155                response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid Request : " + e.getMessage());
156            }
157            LOG.info("Processing in Multipart : END");
158        } else {
159            LOG.debug("isMultipart-->" + isMultipart);
160            docAction = request.getParameter("docAction");
161            LOG.debug("docAction-->" + docAction);
162            String uuid = request.getParameter("uuid");
163            String docFormat = request.getParameter("docFormat");
164            LOG.debug("docFormat=" + docFormat);
165            if (null != uuid && uuid.length() > 0 && (null == docAction || "".equalsIgnoreCase(docAction))) {
166                checkOut(request, response);
167            } else if ("checkOut".equalsIgnoreCase(docAction)) {
168                checkOut(request, response);
169            } else if ("checkIn".equalsIgnoreCase(docAction)) {
170                if (isUpdateEnabled) {
171                    Request dsRequest = new RequestHandler().toObject(request.getParameter("stringContent"));
172                    String checkInResponse = checkIn(dsRequest, null);
173                    response.setContentType("text/xml");
174                    response.getWriter().println(checkInResponse);
175                } else {
176                    sendUnavailableResponseString(response);
177                }
178            } else if ("link".equalsIgnoreCase(docAction)) {
179                if (isUpdateEnabled) {
180                    link(request, response);
181                } else {
182                    sendUnavailableResponseString(response);
183                }
184            } else if ("ingestContent".equalsIgnoreCase(docAction)) {
185                if (isUpdateEnabled) {
186                    ingestStringContent(request, response);
187                } else {
188                    sendUnavailableResponseString(response);
189                }
190            } else if (docAction.contains("delete")) {
191                Response dsResponse = null;
192                if (isUpdateEnabled) {
193                    Request dsRequest = null;
194                    String identifierType = request.getParameter("identifierType");
195                    LOG.info("identifierType->" + identifierType);
196                    String ids = request.getParameter("requestContent");
197                    if ((ids != null) && (!StringUtils.isBlank(ids))) {
198                        LOG.info("requestContent-->" + ids);
199                        dsRequest = buildRequest(ids, identifierType, docAction);
200                        //New Refactored code starts here
201                        try {
202                            dsRequest = buildRequestForDelete(ids, identifierType, docAction);
203                            dsResponse = BeanLocator.getDocstoreFactory().getDocumentService().process(dsRequest);
204                        } catch (Exception e) {
205                            LOG.error("", e);
206                            Response response1 = new Response();
207                            response1.setMessage(e.getMessage());
208                            response1.setOperation("delete");
209                            response1.setStatus("Failed");
210                            response.setContentType("text/xml");
211                            response.getWriter().println(new ResponseHandler().toXML(response1));
212                        }
213                        //New Refactored code ends here
214                    }
215//                    dsResponse = processDeleteRequest(dsRequest);
216//                    response.setContentType("text/xml");
217                    response.getWriter().println(new ResponseHandler().toXML(dsResponse));
218                } else {
219                    sendUnavailableResponseString(response);
220                }
221            } else if (docAction.contains("cleanRepository")) {
222                if (isUpdateEnabled) {
223                    cleanRepository(request, response);
224                } else {
225                    sendUnavailableResponseString(response);
226                }
227            } else if (docAction.contains("transferInstances")) {
228                LOG.debug("In if transferInstances");
229                String operation = request.getParameter("docAction");
230                String requestXML = request.getParameter("stringContent");
231                LOG.debug("In if transferInstances requestXML " + requestXML);
232                Request dsRequest = new RequestHandler().toObject(requestXML);
233                try {
234                    BeanLocator.getDocstoreFactory().getDocumentService().process(dsRequest);
235                } catch (Exception e) {
236                    LOG.error(e.getMessage(), e);
237                }
238            } else if (docAction.contains("transferItems")) {
239                LOG.debug("In if transferItems");
240                String operation = request.getParameter("docAction");
241                String requestXML = request.getParameter("stringContent");
242                LOG.debug("In if transferItems requestXML " + requestXML);
243                Request dsRequest = new RequestHandler().toObject(requestXML);
244                try {
245                    Response transferItemResponse = BeanLocator.getDocstoreFactory().getDocumentService().process(dsRequest);
246                    LOG.debug("Document Servlet transferItemResponse " + new ResponseHandler().toXML(transferItemResponse));
247                    response.getWriter().println(new ResponseHandler().toXML(transferItemResponse));
248
249                } catch (Exception e) {
250                    LOG.error(e.getMessage(), e);
251                }
252            } else if (docAction.equals("instanceDetails")) {
253                String bibUUIDs = request.getParameter("bibIds");
254                String format = request.getParameter("format");
255                List<String> bibUUIDList = getBibIdList(bibUUIDs);
256                OleDocstoreDataRetrieveService oleDocstoreDataRetrieveService = new OleDocstoreDataRetrieveService();
257                String instanceResponse = oleDocstoreDataRetrieveService.getInstanceDetails(bibUUIDList, format);
258
259                if (instanceResponse == null || instanceResponse.isEmpty()) {
260                    response.setStatus(HttpServletResponse.SC_NOT_FOUND);
261                    if (bibUUIDList.size() == 1)
262                        response.getWriter().println("<html><body><b>No record found for the given id </b></body></html>" + bibUUIDList.get(0));
263                    else if (bibUUIDList.size() > 1)
264                        response.getWriter().println("<html><body><b>No record found for the given id's </b></body></html>");
265                } else {
266                    if (null == format) {
267                        response.setContentType("text/xml");
268                    } else if (format.equalsIgnoreCase("xml")) {
269                        response.setContentType("text/xml");
270                    } else if (format.equalsIgnoreCase("json")) {
271                        response.setContentType("application/json");
272                    }
273                    response.getWriter().println(instanceResponse);
274                }
275            } else if (docAction.equals("docstoreDBDump")) {
276                String requestXML = request.getParameter("requestContent");
277                OleDocstoreDumpService oleDocstoreDumpService = new OleDocstoreDumpService();
278                try {
279                    String instanceResponse = oleDocstoreDumpService.exportDocstoreData(requestXML);
280                    response.setContentType("text/xml");
281                    response.getWriter().println(instanceResponse);
282                } catch (Exception e) {
283                    LOG.error(e.getMessage(), e);
284                }
285
286            } else {
287                response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid docAction.");
288            }
289        }
290
291
292    }
293
294//    public void buildRequestForTransfer(String requestXML,String operation){
295//       Request dsRequest = new RequestHandler().toObject(requestXML);
296//    }
297
298
299    /**
300     * Prepare Request Pojo Object from the given uuids.
301     *
302     * @param ids
303     * @param identifierType
304     * @param operation
305     * @return
306     */
307    private Request buildRequestForDelete(String ids, String identifierType, String operation) throws Exception {
308        String[] Id = ids.split(",");
309        List<String> idList = new ArrayList<String>();
310        List<String> uuidList = new ArrayList<String>();
311        Request request = null;
312        for (int i = 0; i < Id.length; i++) {
313            idList.add(Id[i]);
314            LOG.debug("adding -->" + idList);
315        }
316        if ((!StringUtils.isBlank(identifierType)) && (identifierType.equalsIgnoreCase("SCN") || identifierType
317                .equalsIgnoreCase("ISBN"))) {
318            uuidList = ServiceLocator.getQueryService().getUUIDList(idList, identifierType);
319        } else {
320            uuidList = idList;
321        }
322        request = identifyDeleteableDocuments(uuidList, operation);
323        return request;
324    }
325
326    /**
327     * Identifies which uuids exists in the OLE from the given uuids. uuids which exists in OLE are not deleted.
328     *
329     * @param uuidsList
330     * @param operation
331     * @return
332     * @throws Exception
333     */
334    public Request identifyDeleteableDocuments(List<String> uuidsList, String operation) throws Exception {
335        Request dsRequest = new Request();
336        dsRequest.setUser("ole-khuntley");
337        dsRequest.setOperation(operation);
338
339        List<RequestDocument> requestDocuments = null;
340        Response response = null;
341        String uuidsNotInOle = null;
342        String serviceURL = null;
343        StringBuilder uuidsSB = null;
344        // Build a csv of UUIDs of the documents to be deleted.
345        uuidsSB = new StringBuilder();
346        for (String uuid : uuidsList) {
347            uuidsSB.append(uuid).append(",");
348        }
349        serviceURL = ConfigContext.getCurrentContextConfig().getProperty("uuidCheckServiceURL");
350        LOG.info(" uuidCheckServiceURL --------> " + serviceURL);
351        //        uuidsNotInOle = uuidsSB.substring(0, uuidsSB.length() - 1);
352
353        OleWebServiceProvider oleWebServiceProvider = new OleWebServiceProviderImpl();
354
355        OleUuidCheckWebService oleUuidCheckWebService = (OleUuidCheckWebService) oleWebServiceProvider
356                .getService("org.kuali.ole.service.OleUuidCheckWebService", "oleUuidCheckWebService", serviceURL);
357
358        uuidsNotInOle = oleUuidCheckWebService.checkUuidExsistence(uuidsSB.substring(0, uuidsSB.length() - 1));
359        LOG.info("response uuids from OLE " + uuidsNotInOle);
360        // If the UUIDs do not exist in OLE, delete them from docstore.
361        if ((uuidsNotInOle != null) && (uuidsNotInOle.length() > 0)) {
362            String[] uuids = StringUtils.split(uuidsNotInOle, ",");
363            requestDocuments = new ArrayList<RequestDocument>();
364            for (String id : uuids) {
365                RequestDocument requestDocument = new RequestDocument();
366                requestDocument.setCategory(DocCategory.WORK.getCode());
367                requestDocument.setFormat(DocFormat.MARC.getCode());
368                requestDocument.setType(DocType.BIB.getDescription());
369                requestDocument.setUuid(id);
370                requestDocument.setOperation(dsRequest.getOperation());
371                requestDocuments.add(requestDocument);
372            }
373            dsRequest.setRequestDocuments(requestDocuments);
374        }
375        return dsRequest;
376    }
377
378    /**
379     * @param ids
380     * @param identifierType
381     * @param operation
382     * @return
383     */
384    private Request buildRequest(String ids, String identifierType, String operation) {
385        String[] Id = ids.split(",");
386        List<String> idList = new ArrayList<String>();
387        List<String> uuidList = new ArrayList<String>();
388        Request request = new Request();
389        for (int i = 0; i < Id.length; i++) {
390            idList.add(Id[i]);
391            LOG.debug("adding -->" + idList);
392        }
393        if ((!StringUtils.isBlank(identifierType)) && (identifierType.equalsIgnoreCase("SCN") || identifierType.equalsIgnoreCase("ISBN"))) {
394            uuidList = ServiceLocator.getQueryService().getUUIDList(idList, identifierType);
395        } else {
396            uuidList = idList;
397        }
398
399        request = buildRequest(uuidList, operation);
400        return request;
401    }
402
403    /**
404     * @param uuidList
405     * @param operation
406     * @return
407     */
408
409    private Request buildRequest(List<String> uuidList, String operation) {
410        Request request = new Request();
411        List<RequestDocument> requestDocumentList = new ArrayList<RequestDocument>();
412        request.setUser("ole-khuntley");
413        request.setOperation(operation);
414        for (int i = 0; i < uuidList.size(); i++) {
415            RequestDocument requestDocument = new RequestDocument();
416            //requestDocument.setId(uuidList.get(i));
417            requestDocument.setUuid(uuidList.get(i));
418            requestDocumentList.add(requestDocument);
419        }
420        request.setRequestDocuments(requestDocumentList);
421        return request;
422    }
423
424    @Override
425    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
426        // TODO Auto-generated method stub
427        // checkOut(request, response);
428        doPost(request, response);
429
430    }
431
432    private void cleanRepository(HttpServletRequest request, HttpServletResponse response) {
433        DeleteManager deleteManager = new DeleteManager();
434        try {
435
436            deleteManager.cleanUpDocStoreData();
437        } catch (Exception e) {
438            LOG.error("Error while cleaning Repository process", e);
439        }
440
441    }
442
443    protected void checkOut(HttpServletRequest request, HttpServletResponse response) throws IOException {
444        String uuid = request.getParameter("uuid");
445        LOG.info("check out request uuid-->" + uuid);
446        String action = request.getParameter("docAction");
447        String requestType = request.getParameter("dataType");
448        String docFormat = request.getParameter("docFormat");
449        LOG.debug("docFormat-->" + docFormat);
450        String userId = getUserId(request);
451        PrintWriter out = null;
452        String checkoutResponse = null;
453        String setContentType = null;
454        Request req = null;
455        try {
456            if (!DocumentUniqueIDPrefix.hasPrefix(uuid)) {
457                uuid = "wbm-" + uuid;
458            }
459            if (DocumentUniqueIDPrefix.hasPrefix(uuid)) {
460                Map<String, String> categoryTypeFormat = DocumentUniqueIDPrefix.getCategoryTypeFormat(uuid);
461                String category = categoryTypeFormat.get("category");
462                String type = categoryTypeFormat.get("type");
463                String format = categoryTypeFormat.get("format");
464                req = new Request();
465                RequestDocument requestDocument = buildRequestDocument(category, type, format, uuid);
466                List<RequestDocument> requestDocuments = new ArrayList<RequestDocument>();
467                requestDocuments.add(requestDocument);
468                req.setOperation("checkOut");
469                req.setUser("checkOutUser");
470                req.setRequestDocuments(requestDocuments);
471            }
472            if (req == null) {
473                req = getRequest(uuid, userId, action, docFormat);
474            }
475            if (docFormat == null || "".equalsIgnoreCase(docFormat)) {
476                if (req != null && req.getRequestDocuments() != null && req.getRequestDocuments().size() > 0) {
477                    docFormat = req.getRequestDocuments().get(0).getFormat();
478                }
479            }
480
481            if (docFormat != null && docFormat.equalsIgnoreCase(DocFormat.PDF.getCode())) {
482                setContentType = "application/pdf";
483                checkoutBinary(response, setContentType, req);
484                //                checkoutBinary(response, uuid, action, docFormat, userId, checkoutResponse, setContentType);
485            } else if (docFormat != null && docFormat.equalsIgnoreCase(DocFormat.DOC.getCode())) {
486                setContentType = "application/msword";
487                checkoutBinary(response, setContentType, req);
488                //                checkoutBinary(response, uuid, action, docFormat, userId, checkoutResponse, setContentType);
489            } else {
490
491                response.setContentType("text/xml");
492                response.setCharacterEncoding("UTF-8");
493                out = response.getWriter();
494//                checkoutResponse = documentStoreManager.checkOut(uuid, userId, action);
495                Response dsResponse = BeanLocator.getDocstoreFactory().getDocumentService().process(req);
496                if (dsResponse != null) {
497                    for (ResponseDocument responseDocument : dsResponse.getDocuments()) {
498                        if (responseDocument != null && responseDocument.getContent() != null) {
499                            checkoutResponse = responseDocument.getContent().getContent();
500                        }
501                        checkoutResponse = checkoutResponse + "\n";
502                    }
503                }
504
505                //                if (((null == requestType || !requestType.equals("raw")) && checkoutResponse != null)) {
506                //                    checkoutResponse = checkoutResponse.replaceAll("&", "&amp;");
507                //                    checkoutResponse = checkoutResponse.replaceAll("< ", "&lt; ");
508                //                    checkoutResponse = checkoutResponse.replace("&apos;", "\'");
509                //                }
510
511                out.println(new ResponseHandler().toXML(dsResponse));
512            }
513        } catch (Exception ex) {
514            LOG.error("Error while performing checkout process", ex);
515            checkoutResponse = printResponse(null, "Check-out", "Failure", "Checkout failed",
516                    "Error while performing checkout process");
517            out.println(checkoutResponse);
518        }
519
520    }
521
522    private void checkoutBinary(HttpServletResponse response, String uuid, String action, String docFormat,
523                                String userId, String checkOutResponse, String setContentType) throws IOException {
524        HashMap<String, String> checkOutMap = null;
525        checkOutMap = new HashMap<String, String>();
526        checkOutMap.put("uuid", uuid);
527        checkOutResponse = documentStoreManager.checkOutBinary(uuid, userId, action, docFormat);
528        LOG.info("checkOutResponse-->" + checkOutResponse);
529        File file = new File(checkOutResponse);
530        String fileName = checkOutResponse
531                .substring(checkOutResponse.lastIndexOf(File.separator), checkOutResponse.length());
532        LOG.info("fileName-->" + fileName);
533        response.setContentType(setContentType);
534        response.addHeader("Content-Disposition", "inline; filename=" + fileName);
535        response.setHeader("Pragma", "No-cache");
536        FileInputStream fileInputStream = new FileInputStream(file);
537        OutputStream responseOutputStream = response.getOutputStream();
538        int bytes;
539        while ((bytes = fileInputStream.read()) != -1) {
540            responseOutputStream.write(bytes);
541        }
542    }
543
544    private Request getRequest(String uuid, String userId, String action, String docFormat)
545            throws OleDocStoreException, OleException {
546
547        Node nodeByUUID = null;
548        Session session = null;
549        Request req = new Request();
550        if (action == null || "".equalsIgnoreCase(action)) {
551            action = "checkOut";
552        }
553        if (userId == null || "".equalsIgnoreCase(action)) {
554            userId = "checkOutUser";
555        }
556        try {
557            session = RepositoryManager.getRepositoryManager().getSession(userId, action);
558        } catch (Exception e) {
559            LOG.error("Excaption while creating a session" + e.getMessage(), e);
560            throw new OleDocStoreException(e.getMessage(), e);
561        }
562        String cat = null;
563        String type = null;
564        String format = null;
565        try {
566            NodeHandler nodeHandler = new NodeHandler();
567            nodeByUUID = nodeHandler.getNodeByUUID(session, uuid);
568            String nodePath = nodeByUUID.getPath();
569            String[] splitLine = nodePath.split("/");
570
571            if (splitLine != null && splitLine.length >= 4) {
572                cat = splitLine[1];
573                type = splitLine[2];
574                format = splitLine[3];
575            } else {
576                throw new OleDocStoreException(" This is not a valid UUID ");
577            }
578            if (docFormat == null || "".equalsIgnoreCase(docFormat)) {
579                docFormat = format;
580            }
581            req.setUser(userId);
582            req.setOperation(action);
583            List<RequestDocument> reqDocList = new ArrayList<RequestDocument>();
584            RequestDocument reqDoc = buildRequestDocument(cat, type, format, uuid);
585            reqDocList.add(reqDoc);
586            req.setRequestDocuments(reqDocList);
587        } catch (Exception e) {
588            LOG.info(e.getMessage(), e);
589            throw new OleDocStoreException(e);
590        } finally {
591            session.logout();
592        }
593        return req;
594    }
595
596    private RequestDocument buildRequestDocument(String cat, String type, String format, String uuid) {
597        RequestDocument reqDoc = new RequestDocument();
598        reqDoc.setCategory(cat);
599        reqDoc.setType(type);
600        reqDoc.setFormat(format);
601        reqDoc.setUuid(uuid);
602        return reqDoc;
603
604    }
605
606    private void checkoutBinary(HttpServletResponse response, String setContentType, Request req)
607            throws IOException, OleDocStoreException, RepositoryException, OleException {
608        Response dsResponse = BeanLocator.getDocstoreFactory().getDocumentService().process(req);
609
610        if (dsResponse != null) {
611            for (ResponseDocument responseDocument : dsResponse.getDocuments()) {
612                if (responseDocument != null && responseDocument.getContent() != null) {
613                    String responseContent = responseDocument.getContent().getContent();
614                    //TODO  multiple response documents content.
615                    if (responseContent != null) {
616                        LOG.info("checkOutResponse-->" + responseContent);
617                        File file = new File(responseContent);
618                        String fileName = responseContent
619                                .substring(responseContent.lastIndexOf(File.separator), responseContent.length());
620                        LOG.info("fileName-->" + fileName);
621                        response.setContentType(setContentType);
622                        response.addHeader("Content-Disposition", "inline; filename=" + fileName);
623                        response.setHeader("Pragma", "No-cache");
624                        FileInputStream fileInputStream = new FileInputStream(file);
625                        OutputStream responseOutputStream = response.getOutputStream();
626                        int bytes;
627                        while ((bytes = fileInputStream.read()) != -1) {
628                            responseOutputStream.write(bytes);
629                        }
630                    }
631                }
632            }
633        }
634    }
635
636    protected String checkIn(Request dsRequest, Response dsResponse) {
637        if (dsResponse == null) {
638            dsResponse = new Response();
639        }
640        String checkInResponse = null;
641        List<String> latestVersion = new ArrayList<String>();
642        /*try {
643            dsResponse.setOperation(dsRequest.getOperation());
644            dsResponse.setUser(dsRequest.getUser());
645            for (int i = 0; i < dsRequest.getRequestDocuments().size(); i++) {
646                RequestDocument requestDocument = dsRequest.getRequestDocuments().get(i);
647                requestDocument.setOperation(dsRequest.getOperation());
648                latestVersion.add(documentStoreManager.updateRecord(requestDocument));
649                ResponseDocument responseDocument = new ResponseDocument();
650                responseDocument.setUuid(requestDocument.getUuid());
651                responseDocument.setVersion(latestVersion.get(i));
652                responseDocument.setId(requestDocument.getId());
653                responseDocument.setCategory(requestDocument.getCategory());
654                responseDocument.setType(requestDocument.getType());
655                responseDocument.setFormat(requestDocument.getFormat());
656                dsResponse.getDocuments().add(responseDocument);
657            }
658            Response response = ingestNIndexHandlerService.buildResponse(dsRequest);
659            checkInResponse = printResponse(response, dsRequest.getOperation(), "Success", "Documents checked in",
660                    "Successfully checked in ");
661        }*/
662        try {
663            dsResponse = BeanLocator.getDocstoreFactory().getDocumentService().process(dsRequest);
664            checkInResponse = (new ResponseHandler().toXML(dsResponse));
665        } catch (Exception ex) {
666            Response response = ingestNIndexHandlerService.buildResponse(dsRequest);
667            String failOverMessage = ex.getMessage();
668            failOverMessage = failOverMessage.replace("javax.jcr.ItemNotFoundException", "Document Not Found for uuid");
669            checkInResponse = printResponse(response, dsRequest.getOperation(), "Failure", "Checkin failed",
670                    failOverMessage);
671        }
672        return checkInResponse;
673    }
674
675    private String printResponse(Response response, String operation, String status, String message,
676                                 String statusMessage) {
677        String resp = null;
678        if (response == null) {
679            response = new Response();
680        }
681        response.setOperation(operation);
682        response.setStatus(status);
683        response.setMessage(message);
684        response.setStatusMessage(statusMessage);
685        resp = new ResponseHandler().toXML(response);
686        return resp;
687    }
688
689    protected void link(HttpServletRequest request, HttpServletResponse response) {
690        String uuidFile1 = request.getParameter("uuid1");
691        String uuidFile2 = request.getParameter("uuid2");
692        String userId = getUserId(request);
693        String action = request.getParameter("docAction");
694        String result = null;
695        PrintWriter out = null;
696        HashMap<String, String> linkMap = null;
697        String linkResponse = null;
698        try {
699            response.setContentType("text/xml");
700            out = response.getWriter();
701            linkMap = new HashMap<String, String>();
702            linkMap.put("uuid1", uuidFile1);
703            linkMap.put("uuid2", uuidFile2);
704            documentStoreManager.addReference(uuidFile1, uuidFile2, userId, action);
705
706            result = uuidFile2 + " has been successfully linked to  " + uuidFile1;
707            //            linkResponse = printResponse("Link", linkMap, responseListName, responseListData, result, "Success");
708            linkResponse = printResponse(null, "Link", "Success", "Linked successfully", result);
709            out.println(linkResponse);
710        } catch (Exception e) {
711            LOG.error("addReference( " + uuidFile1 + ", " + uuidFile2 + ") failed", e);
712            result = "addReference( " + uuidFile1 + ", " + uuidFile2 + ") failed";
713            //            linkResponse = printResponse("Link", linkMap, responseListName, responseListData, result, "Failure");
714            linkResponse = printResponse(null, "Link", "Failure", "Linking failed", result);
715            out.println(linkResponse);
716        }
717    }
718
719
720    protected void ingestStringContent(HttpServletRequest request, HttpServletResponse response) throws IOException {
721        String stringContent = request.getParameter("stringContent");
722        response.setContentType("text/xml");
723        PrintWriter out = response.getWriter();
724        RequestHandler requestHandler = new RequestHandler();
725        Response dsResponse = new Response();
726        //Request dsRequest = requestHandler.toObject(stringContent);
727
728        try {
729            Request dsRequest = requestHandler.toObject(stringContent);
730//            String xmlResponse = ingestNIndexHandlerService.ingestNIndexRequestDocuments(stringContent);
731//            out.print(xmlResponse);
732            dsResponse = BeanLocator.getDocstoreFactory().getDocumentService().process(dsRequest);
733            out.println(new ResponseHandler().toXML(dsResponse));
734        } catch (Exception e) {
735            dsResponse.setStatus("Failure");
736            dsResponse.setMessage("Ingest string content failed.");
737            dsResponse.setStatusMessage("Ingest string content failed due to invalid input file." + e.getMessage());
738            out.println(new ResponseHandler().toXML(dsResponse));
739            LOG.error("Ingest string content failed", e);
740            //response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
741            //        "Ingest string content failed : " + e.getMessage());
742        } finally {
743            out.close();
744        }
745    }
746
747    /**
748     * Deletes documents from docstore and discovery.
749     * Verifies the existence of the documents in OLE by calling a web service.
750     * If the documents exist in OLE, this operation fails.
751     * Else, the documents are deleted from docstore and discovery.
752     *
753     * @param dsRequest
754     * @return
755     * @throws IOException
756     */
757    protected Response processDeleteRequest(Request dsRequest) throws IOException {
758        DeleteManager deleteManager = new DeleteManager();
759        List<RequestDocument> requestDocuments = new ArrayList<RequestDocument>();
760        requestDocuments = dsRequest.getRequestDocuments();
761        Response response = null;
762        String uuidsNotInOle = null;
763        String serviceURL = null;
764        StringBuilder uuidsSB = null;
765        try {
766            if ((requestDocuments == null) || (requestDocuments.size() == 0)) {
767                response = deleteManager.getResponse(dsRequest, requestDocuments, "Failed",
768                        "Deletion failed: No documents specified for deletion.");
769            } else {
770                // Build a csv of UUIDs of the documents to be deleted.
771                uuidsSB = new StringBuilder();
772                for (RequestDocument requestDocument : requestDocuments) {
773                    //uuidsSB.append(requestDocument.getId()).append(",");
774                    uuidsSB.append(requestDocument.getUuid()).append(",");
775                }
776                serviceURL = ConfigContext.getCurrentContextConfig().getProperty("uuidCheckServiceURL");
777                LOG.info(" uuidCheckServiceURL --------> " + serviceURL);
778                boolean verifiedWithOLE = true;
779                try {
780                    // Use OLE web service to verify the existence of the UUIDs in OLE.
781                    OleWebServiceProvider oleWebServiceProvider = new OleWebServiceProviderImpl();
782
783                    OleUuidCheckWebService oleUuidCheckWebService = (OleUuidCheckWebService) oleWebServiceProvider
784                            .getService("org.kuali.ole.service.OleUuidCheckWebService", "oleUuidCheckWebService",
785                                    serviceURL);
786
787                    uuidsNotInOle = oleUuidCheckWebService
788                            .checkUuidExsistence(uuidsSB.substring(0, uuidsSB.length() - 1));
789                } catch (Exception e) {
790                    verifiedWithOLE = false;
791                    LOG.error("Check uuid call to OLE failed:", e);
792                    response = deleteManager.getResponse(dsRequest, requestDocuments, "Failure",
793                            "Deletion failed: Exception while connecting to OLE service to verify the existence of documents."
794                                    + e.getMessage());
795
796                }
797                if (verifiedWithOLE) {
798                    LOG.info("response uuids from OLE " + uuidsNotInOle);
799                    // If the UUIDs do not exist in OLE, delete them from docstore.
800                    if ((uuidsNotInOle != null) && (uuidsNotInOle.length() > 0)) {
801                        String[] uuids = StringUtils.split(uuidsNotInOle, ",");
802                        requestDocuments = new ArrayList<RequestDocument>();
803                        for (String id : uuids) {
804                            RequestDocument requestDocument = new RequestDocument();
805                            //requestDocument.setId(id);
806                            requestDocument.setUuid(id);
807                            requestDocuments.add(requestDocument);
808                        }
809                        dsRequest.setRequestDocuments(requestDocuments);
810                        try {
811                            response = deleteManager.deleteDocs(dsRequest);
812                        } catch (Exception e) {
813                            response = deleteManager.getResponse(dsRequest, requestDocuments, "Failure",
814                                    "Deletion failed: Exception while deleting from docstore. "
815                                            + e.getMessage());
816                        }
817                    } else {
818                        response = deleteManager.getResponse(dsRequest, requestDocuments, "Failure",
819                                "Deletion failed: Documents exist in OLE database and cannot be deleted.");
820                    }
821                }
822            }
823        } catch (Exception e) {
824            LOG.error("delete operation failed:", e);
825            response = deleteManager.getResponse(dsRequest, requestDocuments, "Failure", "Failed : " + e.getMessage());
826        }
827        return response;
828    }
829
830    /*public String printResponse(String action, HashMap<String, String> paramMap, String responseListName, List<String> responseListData,
831            String resMessage, String statusMessage) {
832        String xmlString = null;
833        try {
834            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
835            DocumentBuilder docBuilder = builderFactory.newDocumentBuilder();
836            Document xmlDocument = docBuilder.newDocument();
837            Element root = xmlDocument.createElement("OLEDocstore-call");
838            xmlDocument.appendChild(root);
839
840            Element requestRoot = xmlDocument.createElement("request");
841            root.appendChild(requestRoot);
842            Element command = xmlDocument.createElement("command");
843            requestRoot.appendChild(command);
844            Text text = xmlDocument.createTextNode(action);
845            command.appendChild(text);
846            Element params = xmlDocument.createElement("params");
847            requestRoot.appendChild(params);
848            if (paramMap != null) {
849                Iterator<String> iterator = paramMap.keySet().iterator();
850                while (iterator.hasNext()) {
851                    String key = iterator.next();
852                    String value = paramMap.get(key);
853                    Element categoryParam = xmlDocument.createElement("param");
854                    params.appendChild(categoryParam);
855                    categoryParam.setAttribute("name", key);
856                    categoryParam.setAttribute("value", value);
857                }
858            }
859
860            Element responseRoot = xmlDocument.createElement("response");
861            root.appendChild(responseRoot);
862            Element status = xmlDocument.createElement("status");
863            responseRoot.appendChild(status);
864            Text statusText = xmlDocument.createTextNode(statusMessage);
865            status.appendChild(statusText);
866            Element message = xmlDocument.createElement("message");
867            responseRoot.appendChild(message);
868            Text messageText = xmlDocument.createTextNode(resMessage);
869            message.appendChild(messageText);
870            if (statusMessage.equalsIgnoreCase("Success")) {
871                if (responseListName != null) {
872                    Element uuidRoot = xmlDocument.createElement("list");
873                    responseRoot.appendChild(uuidRoot);
874                    uuidRoot.setAttribute("name", responseListName);
875                    if (responseListData != null && responseListData.size() > 0) {
876                        for (int i = 0; i < responseListData.size(); i++) {
877                            Element uuid = xmlDocument.createElement("item");
878                            uuidRoot.appendChild(uuid);
879                            Text uuidVal = xmlDocument.createTextNode(responseListData.get(i));
880                            uuid.appendChild(uuidVal);
881                        }
882                    }
883                }
884            }
885            TransformerFactory factory = TransformerFactory.newInstance();
886            Transformer transformer = factory.newTransformer();
887            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
888            StringWriter sw = new StringWriter();
889            StreamResult result = new StreamResult(sw);
890            DOMSource source = new DOMSource(xmlDocument);
891            transformer.transform(source, result);
892            xmlString = sw.toString();
893        } catch (Exception ex) {
894            LOG.error("printResponse() failed:", ex);
895            StringBuffer exceptionMsg = new StringBuffer();
896            String DOUBLE_QUOTE = "\"";
897            exceptionMsg.append("<?xml version=" + DOUBLE_QUOTE + "1.0" + DOUBLE_QUOTE + " encoding=" + DOUBLE_QUOTE + "UTF-8" + DOUBLE_QUOTE + "?>");
898            exceptionMsg.append("<OLEDocstore-call>");
899            exceptionMsg.append("<response>");
900            exceptionMsg.append("<status>");
901            exceptionMsg.append(statusMessage);
902            exceptionMsg.append("</status>");
903            exceptionMsg.append("<message>");
904            exceptionMsg.append(resMessage);
905            exceptionMsg.append("</message>");
906            exceptionMsg.append("</response>");
907            exceptionMsg.append("</OLEDocstore-call>");
908            return exceptionMsg.toString();
909        }
910        return xmlString;
911    }*/
912
913    /**
914     * @param request
915     * @param response
916     * @return docAction (add or delete)
917     * @throws ServletException
918     */
919    protected List<FileItem> getMultiPartFileItems(HttpServletRequest request, HttpServletResponse response)
920            throws ServletException {
921        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
922        List<FileItem> items = null;
923        try {
924            if (isMultipart) {
925                DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();
926                ServletFileUpload uploadHandler = new ServletFileUpload(fileItemFactory);
927                items = uploadHandler.parseRequest(request);
928            }
929        } catch (Exception ex) {
930            LOG.error("Error in getting the Reading the File:", ex);
931        }
932        return items;
933    }
934
935    /**
936     * @param reqParam
937     * @param items
938     * @param request
939     * @return docAction (delete)
940     */
941    protected String getParameter(String reqParam, List<FileItem> items, HttpServletRequest request) {
942        String paramValue = null;
943        if (items != null && items.size() > 0) {
944            Iterator<FileItem> itr = items.iterator();
945            while (itr.hasNext()) {
946                FileItem item = (FileItem) itr.next();
947                if (item.isFormField()) {
948                    String name = item.getFieldName();
949                    String value = item.getString();
950                    if (reqParam.equals(name)) {
951                        paramValue = value;
952                    }
953                }
954            }
955        } else {
956            paramValue = request.getParameter(reqParam);
957        }
958        return paramValue;
959    }
960
961    protected String getUserId(HttpServletRequest request) {
962        String userId = request.getParameter("userId");
963        if (userId == null) {
964            userId = "defaultUser";
965        }
966        return userId;
967    }
968
969    private ArrayList<File> extractBagFilesFromRequest(HttpServletRequest req, HttpServletResponse res)
970            throws Exception {
971        File targetDir = null;
972        try {
973            File file = null;
974            DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();
975            fileItemFactory.setSizeThreshold(1 * 1024 * 1024); // 1 MB
976            Iterator items = new ServletFileUpload(fileItemFactory).parseRequest(req).iterator();
977            while (items.hasNext()) {
978                FileItem item = (FileItem) items.next();
979                file = new File(FileUtils.getTempDirectory(), item.getName());
980                item.write(file);
981            }
982            targetDir = compressUtils.extractZippedBagFile(file.getAbsolutePath(), null);
983            LOG.info("extractedBagFileLocation " + targetDir);
984        } catch (IOException e) {
985            LOG.error("IOException", e);
986            sendResponseBag(res, e.getMessage(), "failure");
987        } catch (FormatHelper.UnknownFormatException unknownFormatException) {
988            LOG.error("unknownFormatException", unknownFormatException);
989            sendResponseBag(res, unknownFormatException.getMessage(), "failure");
990        }
991        return compressUtils.getAllFilesList(targetDir);
992    }
993
994    /**
995     * Method to send response for a request in a zipped bag.
996     *
997     * @param res
998     * @param message
999     * @param status
1000     * @return
1001     */
1002    private void sendResponseBag(HttpServletResponse res, String message, String status) {
1003        Response response = new Response();
1004        response.setMessage(message);
1005        response.setStatus(status);
1006        sendResponseBag(res, response);
1007    }
1008
1009    private void sendResponseBag(HttpServletResponse res, Response docStoreResponse) {
1010        String responseXML = new ResponseHandler().toXML(docStoreResponse);
1011        try {
1012            File output = File.createTempFile("checkout.", ".output");
1013            FileUtils.deleteQuietly(output);
1014            output.mkdirs();
1015            File file = new File(output + File.separator + "response.xml");
1016            Writer writer = null;
1017            writer = new BufferedWriter(new FileWriter(file));
1018            writer.write(responseXML);
1019            writer.close();
1020            File zipFile = compressUtils.createZippedBagFile(output);
1021            res.setContentType("application/zip");
1022            sendResponseAsFile(res, zipFile);
1023            zipFile.delete();
1024        } catch (IOException e) {
1025            LOG.error("IOException", e);
1026        }
1027    }
1028
1029    /**
1030     * Method sends the response generated for the given request
1031     *
1032     * @param res
1033     * @param file
1034     * @throws IOException
1035     */
1036    private void sendResponseAsFile(HttpServletResponse res, File file) throws IOException {
1037        ServletOutputStream stream = res.getOutputStream();
1038        FileInputStream fos = new FileInputStream(file.getAbsolutePath());
1039        BufferedInputStream buf = new BufferedInputStream(fos);
1040        int readBytes = 0;
1041        while ((readBytes = buf.read()) != -1) {
1042            stream.write(readBytes);
1043        }
1044        if (stream != null) {
1045            stream.close();
1046        }
1047        if (buf != null) {
1048            buf.close();
1049        }
1050        res.flushBuffer();
1051    }
1052
1053    private void sendUnavailableResponseString(HttpServletResponse response) {
1054        try {
1055            PrintWriter out = response.getWriter();
1056            out.println("The Requested Operation is not available");
1057        } catch (IOException e) {
1058            LOG.error("IOException", e);
1059        }
1060    }
1061
1062    private List<String> getBibIdList(String bibUUIDs) {
1063        List<String> bibIdsList = new ArrayList<String>();
1064        String[] queueArray = bibUUIDs.split(",");
1065        for (int i = 0; i < queueArray.length; i++) {
1066            bibIdsList.add(queueArray[i]);
1067        }
1068        return bibIdsList;
1069    }
1070
1071}