Java tutorial
/* * CargaMasivaServlet.java * Copyright (c) Oct 21, 2012, The Just DO! All rights reserved * * This software is the confidential and propietary information of The Just DO!. * You shall not disclose such Confidential Information and shall use it only * in accordance with the terms of the license agreement you entered into with * The Just DO!. */ package com.thejustdo.servlet; import com.lowagie.text.DocumentException; import com.thejustdo.dao.BuyerQueries; import com.thejustdo.dao.DreamBoxQueries; import com.thejustdo.dao.ParametersQueries; import com.thejustdo.model.Beneficiary; import com.thejustdo.model.Buyer; import com.thejustdo.model.DreamBox; import com.thejustdo.resources.Constants; import com.thejustdo.servlet.security.SecureValidator; import com.thejustdo.util.Utils; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.util.ArrayList; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.ResourceBundle; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.Resource; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.PersistenceUnit; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.transaction.UserTransaction; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.xhtmlrenderer.pdf.ITextRenderer; /** * It's job is mainly a creation in loop for opens. * * @author Edison F Mendez C [efmcuiti] */ public class CargaMasivaServlet extends HttpServlet { /** * Manages all the persistence operations. */ @Resource private UserTransaction utx; /** * Injects the persistent context. */ @PersistenceUnit private EntityManagerFactory emf; /** * Allows us to print messages on the console. */ private static final Logger log = Logger.getLogger(CargaMasivaServlet.class.getName()); /** * Processes requests for both HTTP * <code>GET</code> and * <code>POST</code> methods. * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { log.info(String.format("Welcome to the MULTI-PART!!!")); ResourceBundle messages = ResourceBundle.getBundle("com.thejustdo.resources.messages"); // 0. If no user logged, nothing can be done. if (!SecureValidator.checkUserLogged(request, response)) { return; } // 1. Check that we have a file upload request. boolean isMultipart = ServletFileUpload.isMultipartContent(request); log.info(String.format("Is multipart?: %s", isMultipart)); // 2. Getting all the parameters. String social_reason = request.getParameter("razon_social"); String nit = request.getParameter("nit"); String name = request.getParameter("name"); String phone = request.getParameter("phone"); String email = request.getParameter("email"); String office = (String) request.getSession().getAttribute("actualOffice"); String open_amount = (String) request.getParameter("valor_tarjeta"); String open_user = (String) request.getSession().getAttribute("actualUser"); List<String> errors = new ArrayList<String>(); // 6. Create a factory for disk-based file items DiskFileItemFactory factory = new DiskFileItemFactory(); // 7. Configure a repository (to ensure a secure temp location is used) ServletContext servletContext = this.getServletConfig().getServletContext(); File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir"); log.info(String.format("Temporal repository: %s", repository.getAbsolutePath())); factory.setRepository(repository); // 8. Create a new file upload handler ServletFileUpload upload = new ServletFileUpload(factory); try { utx.begin(); EntityManager em = emf.createEntityManager(); // Parse the request List<FileItem> items = upload.parseRequest(request); // 8.0 A set of generated box codes must be maintained. Map<String, String> matrix = new HashMap<String, String>(); // ADDED: Validation 'o file extension. String filename = null; // Runing through the parameters. for (FileItem fi : items) { if (fi.isFormField()) { if ("razon_social".equalsIgnoreCase(fi.getFieldName())) { social_reason = fi.getString(); continue; } if ("nit".equalsIgnoreCase(fi.getFieldName())) { nit = fi.getString(); continue; } if ("name".equalsIgnoreCase(fi.getFieldName())) { name = fi.getString(); continue; } if ("phone".equalsIgnoreCase(fi.getFieldName())) { phone = fi.getString(); continue; } if ("email".equalsIgnoreCase(fi.getFieldName())) { email = fi.getString(); continue; } if ("valor_tarjeta".equalsIgnoreCase(fi.getFieldName())) { open_amount = fi.getString(); continue; } } else { filename = fi.getName(); } } // 3. If we got no file, then a error is generated and re-directed to the exact same page. if (!isMultipart) { errors.add(messages.getString("error.massive.no_file")); log.log(Level.SEVERE, errors.toString()); } // 4. If any of the others paramaeters are missing, then a error must be issued. if ((social_reason == null) || ("".equalsIgnoreCase(social_reason.trim()))) { errors.add(messages.getString("error.massive.no_social_reason")); log.log(Level.SEVERE, errors.toString()); } if ((nit == null) || ("".equalsIgnoreCase(nit.trim()))) { errors.add(messages.getString("error.massive.no_nit")); log.log(Level.SEVERE, errors.toString()); } if ((name == null) || ("".equalsIgnoreCase(name.trim()))) { errors.add(messages.getString("error.massive.no_name")); log.log(Level.SEVERE, errors.toString()); } if ((phone == null) || ("".equalsIgnoreCase(phone.trim()))) { errors.add(messages.getString("error.massive.no_phone")); log.log(Level.SEVERE, errors.toString()); } if ((email == null) || ("".equalsIgnoreCase(email.trim()))) { errors.add(messages.getString("error.massive.no_email")); log.log(Level.SEVERE, errors.toString()); } // If no filename or incorrect extension. if ((filename == null) || (!(filename.endsWith(Constants.MASSIVE_EXT.toLowerCase(Locale.FRENCH))) && !(filename.endsWith(Constants.MASSIVE_EXT.toUpperCase())))) { errors.add(messages.getString("error.massive.invalid_ext")); log.log(Level.SEVERE, errors.toString()); } // 5. If any errors found, we must break the flow. if (errors.size() > 0) { request.setAttribute(Constants.ERROR, errors); //Redirect the response request.getRequestDispatcher("/WEB-INF/jsp/carga_masiva.jsp").forward(request, response); } for (FileItem fi : items) { if (!fi.isFormField()) { // 8.1 Processing the file and building the Beneficiaries. List<Beneficiary> beneficiaries = processFile(fi); log.info(String.format("Beneficiaries built: %d", beneficiaries.size())); // 8.2 If any beneficiaries, then an error is generated. if ((beneficiaries == null) || (beneficiaries.size() < 0)) { errors.add(messages.getString("error.massive.empty_file")); log.log(Level.SEVERE, errors.toString()); request.setAttribute(Constants.ERROR, errors); //Redirect the response request.getRequestDispatcher("/WEB-INF/jsp/carga_masiva.jsp").forward(request, response); } // 8.3 Building main parts. Buyer b = buildGeneralBuyer(em, social_reason, nit, name, phone, email); // 8.3.1 The DreamBox has to be re-newed per beneficiary. DreamBox db; for (Beneficiary _b : beneficiaries) { // 8.3.2 Completing each beneficiary. log.info(String.format("Completying the beneficiary: %d", _b.getIdNumber())); db = buildDreamBox(em, b, office, open_amount, open_user); matrix.put(db.getNumber() + "", _b.getGivenNames() + " " + _b.getLastName()); _b.setOwner(b); _b.setBox(db); em.merge(_b); } } } // 8.4 Commiting to persistence layer. utx.commit(); // 8.5 Re-directing to the right jsp. request.getSession().setAttribute("boxes", matrix); request.getSession().setAttribute("boxamount", open_amount + ""); //Redirect the response generateZIP(request, response); } catch (Exception ex) { errors.add(messages.getString("error.massive.couldnot_process")); log.log(Level.SEVERE, errors.toString()); request.setAttribute(Constants.ERROR, errors); request.getRequestDispatcher("/WEB-INF/jsp/carga_masiva.jsp").forward(request, response); } } // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code."> /** * Handles the HTTP * <code>GET</code> method. * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Handles the HTTP * <code>POST</code> method. * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Returns a short description of the servlet. * * @return a String containing servlet description */ @Override public String getServletInfo() { return "Short description"; }// </editor-fold> /** * Given a stream containing the file to process, it builds all the info * related to the beneficiaries for dream boxes * * @param fi Contains the info related to the file to be processed. <br /> * <strong>File structure</strong> <ul> <li>0: Identification number.</li> * <li>1: Identification type.</li> <li>2: Age.</li> <li>3: Given * box.</li> <li>4: Last name.</li> <li>5: Second last name.</li> </ul> * @return The list of beneficiaries. */ private List<Beneficiary> processFile(FileItem fi) throws IOException { List<Beneficiary> answer = new ArrayList<Beneficiary>(); // 1. Getting the input stream with the file. InputStream stream = fi.getInputStream(); InputStreamReader isr = new InputStreamReader(stream, "ISO-8859-1"); BufferedReader reader = new BufferedReader(isr); // 2. Parsing line by line. String line; String parts[]; Beneficiary b; while (reader.ready()) { line = reader.readLine(); // Building the beneficiaries. if ((line == null) || ("".equalsIgnoreCase(line.trim()))) { continue; } // 2.1 Spliting parts. log.info(String.format("Found line: %s", line)); parts = line.split(","); // 2.2 Building the new elemento of response. b = new Beneficiary(); //b.setIdNumber(Long.parseLong(parts[0])); //b.setDocumentType(parts[1]); //b.setAge(Integer.parseInt(parts[2])); b.setGivenNames(parts[0]); b.setLastName(parts[1]); //b.setSecondLastName(parts[2]); // 2.3 Adding the element to the answer. answer.add(b); } // n. Clossing the stream. stream.close(); return answer; } /** * Builds an object with the owner that at future will be the owner of all * the dream boxes created under the broad approach of massive load. * * @param args Set of properties for the buyer as follows: <ul> <li> 0: * Social reason. </li> <li> 1: NIT number. </li> <li> 2: Name. </li> <li> * 3: Phone. </li> <li> 4: Email. </li> </ul> * @return The built object ready to be persisted and linked. */ private Buyer buildGeneralBuyer(EntityManager em, String... args) { // 0. Parsing parameters. long idNumber = Long.parseLong(args[1]); String buyer_name = args[0]; String buyer_last_name = args[2]; String buyer_email = args[4]; String buyer_cellphone = args[3]; // 1. If the buyer already exist, we update the info. log.info(String.format("Working on buyer with NIT: %d", idNumber)); Buyer buyer = BuyerQueries.findBuyerById(idNumber, em); buyer = (buyer == null) ? new Buyer(idNumber) : buyer; buyer.setGivenNames(buyer_name); buyer.setLastName(buyer_last_name); buyer.setSecondLastName("N/A"); buyer.setDocumentType("NIT"); buyer.setPaymentMethod("Cargo a cuenta"); buyer.setEmail(buyer_email); buyer.setCellPhone(buyer_cellphone); buyer.setStatus(true); em.merge(buyer); return buyer; } /** * Builds a new dream box based on the initial info. * * @param em Manages the persistence layer. * @param b Buyer owner of this box. * @param args Set of properties for the buyer as follows: <ul> <li> 0: * Office. </li> <li> 1: Open amount. </li> <li> 2: Open user. </li> </ul> * @return The built dream box. */ private DreamBox buildDreamBox(EntityManager em, Buyer b, String... args) { // 0. Parsing parameters. String batch = ParametersQueries.getParameterValueByKey(ParametersQueries.BATCH, em); long boxCode = DreamBoxQueries.getNextBoxCode(em); String office = args[0]; Double open_amount = Double.parseDouble(args[1]); String open_user = args[2]; // 1 Building the dream box. DreamBox box = new DreamBox(boxCode); box.setOpenOffice(office); box.setOpenAmount(open_amount); box.setOpenDate(GregorianCalendar.getInstance().getTime()); box.setOpenUser(open_user); box.setState("activo"); box.setBoxBatch(batch); box.setOwner(b); // 2. Sending it to the persistence layer. em.merge(box); return box; } /** * Builds a ZIP file with all the title-value to be generated with the boxes * configuration. * * @param request Contains all the important data to be used. * @param response Allows us to write the content. */ private void generateZIP(HttpServletRequest request, HttpServletResponse response) throws IOException { // 1. Getting the content of the plain xhtml file. ServletContext sc = this.getServletConfig().getServletContext(); File tempDir = (File) sc.getAttribute("javax.servlet.context.tempdir"); File basePath = Utils.preparePDFDirs(tempDir, sc); File tmpName = new File(basePath, Constants.PDF_TMP_NAME); File d = new File(tempDir, Constants.TMP_TITLES); String _xhtml = Utils.getPlainTextFileFromContext(Constants.MASSIVE_LOCATION, sc); // 1.1 Cleaning the temporary directory. Utils.cleanDirectory(d); // log.info(String.format("Prev XHTML content: %s", _xhtml)); // 2. Getting parameters to configure the PDF content. Map<String, String> matrix = (Map<String, String>) request.getSession().getAttribute("boxes"); String amount = (String) request.getSession().getAttribute("boxamount"); // 3. Generating the new xhtml per entry. String xhtml; String name; OutputStream os; File _new; Set<String> keys = matrix.keySet(); int i = 1; try { for (String k : keys) { name = matrix.get(k); xhtml = String.format(_xhtml, name, k, amount); Utils.createTMPFile(xhtml, tmpName); // 2. Creating the PDF output. _new = new File(d, String.format("title%d.pdf", i)); os = new FileOutputStream(_new); // 3. Creating the gross part. ITextRenderer renderer = new ITextRenderer(); renderer.setDocument(tmpName); //renderer.setDocumentFromString(xhtml); renderer.layout(); renderer.createPDF(os); os.flush(); os.close(); i++; } // log.info(String.format("New XHTML content: %s", xhtml)); // File f = Utils.createNewFileInsideContext( // Constants.PDF_LOCATION, sc, xhtml, Constants.PDF_TMP); // 4. Creating the ZIP file. File zip = new File(tempDir, Constants.ZIP_NAME); Utils.zipDirectory(d, zip); response.setHeader("Content-Type", "application/zip"); response.setHeader("Content-Disposition", "attachment;filename=\"titulos.zip\""); // 3. Writing the file to the output. // The csv parameter contains the path to the temp file to be writen. FileInputStream fis = new FileInputStream(zip); os = response.getOutputStream(); byte buffer[] = new byte[256]; int bytesRead; while ((bytesRead = fis.read(buffer)) != -1) { os.write(buffer, 0, bytesRead); } os.flush(); os.close(); } catch (DocumentException ex) { ex.printStackTrace(); log.log(Level.SEVERE, null, ex); } } }