Java tutorial
/* * Copyright 2010, 2011 Renaud Brub * * This file is part of PIGE. * * PIGE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * PIGE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with PIGE. If not, see <http://www.gnu.org/licenses/>. */ package ca.qc.cegepoutaouais.tge.pige.server; import ca.qc.cegepoutaouais.tge.pige.client.UserStatus; import ca.qc.cegepoutaouais.tge.pige.client.services.exceptions.PigeException; import ca.qc.cegepoutaouais.tge.pige.dao.pojos.Role; import ca.qc.cegepoutaouais.tge.pige.dao.pojos.UserDetail; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.log4j.Logger; /** * Servlet servant l'importation de comptes usagers partir de fichier de * format CSV (Comma separated value). * * @author Renaud Brub */ public class UserImportService extends HttpServlet { private static final Logger logger = LogHelper.getLogger(UserImportService.class); /** * Taille limite du fichier reu dans la requte pour qu'il soit mis en * mmoire. Au-del ce cela, il devra tre crit sur le disque. */ private static final Integer SIZE_THRESHOLD = 5 * 1024 * 1024; // 5 Mo. private PrintWriter writer = null; private Boolean hasError = Boolean.FALSE; @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { hasError = Boolean.FALSE; writer = resp.getWriter(); logger.info("Rception de la requte HTTP pour l'imporation d'usagers."); DiskFileItemFactory factory = new DiskFileItemFactory(); factory.setSizeThreshold(SIZE_THRESHOLD); ServletFileUpload uploadHandler = new ServletFileUpload(factory); try { List<FileItem> items = uploadHandler.parseRequest(req); if (items.size() == 0) { logger.error("Le message ne contient pas de fichier " + "d'importation. Le processus ne pourra donc pas " + "continuer."); writer.println("Erreur: Aucun fichier prsent dans le message"); return; } Charset cs = null; for (FileItem item : items) { if (item.getFieldName().equalsIgnoreCase("importFileEncoding-hidden")) { String encoding = item.getString(); if (encoding == null || encoding.isEmpty()) { logger.error("Le message ne contient pas l'encodage utilis " + "dans le fichier d'importation. Le processus ne pourra " + "donc pas continuer."); writer.println("Erreur: Aucun encodage trouv dans les " + "paramtres du message."); return; } cs = Charset.forName(encoding); if (cs == null) { logger.error("L'encodage spcifi n'existe pas (" + encoding + "). " + "Le processus ne pourra donc pas continuer."); writer.println("Erreur: Aucun encodage trouv portant le " + "nom '" + encoding + "'."); return; } } } for (FileItem item : items) { if (item.getFieldName().equalsIgnoreCase("usersImportFile")) { logger.info("Extraction du fichier d'importation partir " + "du message."); BufferedReader reader = new BufferedReader( new InputStreamReader(new ByteArrayInputStream(item.get()), cs)); doUsersImport(reader, req); break; } } if (!hasError) { logger.info("L'importation des usagers s'est termine avec succs."); writer.println("Importation russie!"); } else { logger.info("L'importation des usagers s'est termine avec des erreurs."); writer.println("L'importation s'est termine avec des erreurs."); } } catch (FileUploadException fuex) { fuex.printStackTrace(); logger.error(fuex); } catch (Exception ex) { ex.printStackTrace(); logger.error(ex); } } private int badLineCount = 0; private int badLineCountLimit = 10; private void doUsersImport(BufferedReader reader, HttpServletRequest req) { badLineCount = 0; logger.info("Dmarrage de l'importation des usagers..."); ManagementServiceImpl service = new ManagementServiceImpl(); List<Role> roles = service.getAllRole(); Role studentRole = null; logger.debug("Recherche d'un rle portant le nom 'tudiant'."); for (Role r : roles) { if (r.getName().equalsIgnoreCase("tudiant")) { logger.debug("Rle tudiant trouv!"); studentRole = r; break; } } if (studentRole == null) { logger.error("Impossible de trouver un rle portant le nom " + "'tudiant'. L'importation des usagers ne pourra pas continuer."); writer.println("Erreur: Rle tudiant introuvable."); return; } List<UserDetail> users = new ArrayList(); UserDetail user; logger.debug("Dcodage du fichier d'importation..."); try { String line = null; while ((line = reader.readLine()) != null) { user = decodeUserInfo(line); if (user == null) { if (badLineCount >= badLineCountLimit) { logger.error("Il y trop de ligne invalide dans le " + "fichier d'importation, le processus " + "d'importation va donc s'arrter."); writer.println("Erreur: L'importation chou car le " + "fichier d'importation contient trop de ligne " + "invalide."); hasError = Boolean.TRUE; return; } badLineCount++; logger.warn("Ligne invalide dans le fichier d'importation. " + "Cette ligne sera ignore: [" + line + "]."); continue; } user.setRoleId(studentRole.getId()); user.setStatus(UserStatus.STATUS_ACTIVE); user.setGrade(""); user.setBarCode(""); user.setFails(0); user.setMessage(""); user.setNote(""); user.setServerMessage(""); user.setSid(""); users.add(user); } logger.debug("Fin du dcodage du fichier d'importation."); if (users.size() == 0) { logger.warn("Aucun compte usager n'a pu tre cr durant " + "l'importation. Votre fichier contient peut-tre des " + "erreurs de syntaxe ou bien il est vide."); writer.println("Erreur: L'importation chou car le fichier " + "d'importation contient des erreurs ou est vide."); hasError = Boolean.TRUE; return; } logger.info("Cration des comptes usagers..."); for (UserDetail userDetail : users) { try { service.createUser(userDetail, req); } catch (PigeException pex) { logger.error(pex); } } } catch (IOException ioex) { logger.error(ioex); } } private final Integer STUDENT_NUMBER_INDEX = 0; private final Integer LASTNAME_INDEX = 1; private final Integer FIRSTNAME_INDEX = 2; private final Integer EMAIL_INDEX = 3; private final Integer PROGRAM_NAME_INDEX = 4; private final Integer LOAN_NO_INDEX = 5; private final Integer dataCount = 5; private final String CSV_SEPARATOR = ","; /** * Syntaxe du fichier CSV. * [#etudiant],[nom],[prenom],[courriel],[programme],[#emprunt (optionnel)] */ private UserDetail decodeUserInfo(String info) { String[] data = info.split(CSV_SEPARATOR); if (data.length < dataCount) { return null; } UserDetail user = new UserDetail(); user.setIdentifier(data[STUDENT_NUMBER_INDEX]); user.setPassword(data[STUDENT_NUMBER_INDEX]); user.setPasswordClear(Boolean.TRUE); user.setLastname(data[LASTNAME_INDEX]); user.setFirstname(data[FIRSTNAME_INDEX]); user.setEmail(data[EMAIL_INDEX]); user.setProgramName(data[PROGRAM_NAME_INDEX]); // Optionnel. if (data.length > dataCount) { user.setLoanNo(data[LOAN_NO_INDEX]); } return user; } }