Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package Server; import Classes.Product; import Classes.Sale; import Classes.User; import com.itextpdf.text.BaseColor; import com.itextpdf.text.Document; import com.itextpdf.text.Font; import com.itextpdf.text.Font.FontFamily; import com.itextpdf.text.Paragraph; import com.itextpdf.text.pdf.PdfPTable; import com.itextpdf.text.pdf.PdfWriter; import java.util.Properties; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import com.opencsv.CSVReader; import com.opencsv.CSVWriter; import java.io.BufferedReader; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.net.Socket; import java.util.logging.Level; import java.util.logging.Logger; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javax.mail.Authenticator; import javax.mail.PasswordAuthentication; /** * * @author gbouz_000 */ public class Server extends Thread { public Socket s; public Server() { } public Server(Socket s) { this.s = s; } /** * Registra novo usurio no sistema, passado como uma string por parmetro. Essa string passada por parmetro contm o cadastro no formato csv. * @param str * @throws IOException */ public void addNewUser(String str) throws IOException { String[] toWrite = str.split(","); CSVWriter writer = new CSVWriter(new FileWriter("users.csv", true)); writer.writeNext(toWrite); writer.close(); } /** * Registra no arquivo de produtos o produto p. * @param p * @throws Exception */ public void addNewProduct(Product p) throws Exception { CSVWriter writer = new CSVWriter(new FileWriter("products.csv", true)); String str = p.getName() + "," + p.getPrice() + "," + p.getValidate() + "," + p.getProvider() + "," + p.getQtd(); String[] toWrite = str.split(","); writer.writeNext(toWrite); writer.close(); } /** * Registra uma nova venda no sistema, caso a quantidade do produto em * questo seja vlida. Retorna um valor boolean que informa se a venda * foi registrada com sucesso. * @param s * @param qtd * @return * @throws Exception */ public boolean addNewSale(Sale s, int qtd) throws Exception { if (qtd == 0 || qtd < Integer.parseInt(s.getQtd())) return false; CSVWriter writer = new CSVWriter(new FileWriter("sales.csv", true)); String str = s.getUserID() + "," + s.getProductName() + "," + s.getDate() + "," + s.getQtd() + "," + s.getTotalCost(); String[] toWrite = str.split(","); writer.writeNext(toWrite); writer.close(); updateProductQtd(s.getProductName(), qtd - Integer.parseInt(s.getQtd())); return true; } /** * Pesquisa no arquivo de produtos todos os produtos existentes. * Estes so retornados em uma lista (list). * @return * @throws Exception */ public ObservableList<Product> searchAllProducts() throws Exception { CSVReader reader = new CSVReader(new FileReader("products.csv"), ','); ObservableList<Product> list = FXCollections.observableArrayList(); String[] readen; while ((readen = reader.readNext()) != null) { Product p = new Product(); p.setName(readen[0]); p.setPrice(readen[1]); p.setValidate(readen[2]); p.setProvider(readen[3]); p.setQtd(readen[4]); list.add(p); } list.stream().map(Product::getQtd).sorted(); reader.close(); return list; } /** * Pesquisa no arquivo de usurios todos os usurios existentes. * Estes so retornados na lista list. * @return * @throws Exception */ public ObservableList<User> searchAllUsers() throws Exception { CSVReader reader = new CSVReader(new FileReader("users.csv"), ','); ObservableList<User> list = FXCollections.observableArrayList(); String[] readen; while ((readen = reader.readNext()) != null) { User u = new User(); u.setName(readen[0]); u.setAddress(readen[1]); u.setPhone(readen[2]); u.setEmail(readen[3]); u.setId(readen[4]); u.setPassword(readen[5]); u.setNotification(readen[6]); list.add(u); } reader.close(); return list; } /** * Retorna em uma lista todas as vendas realizadas no dia passado * por parmetro. * @param day * @return * @throws Exception */ public ObservableList<Sale> searchSalesByDay(String day) throws Exception { CSVReader reader = new CSVReader(new FileReader("sales.csv"), ','); ObservableList<Sale> list = FXCollections.observableArrayList(); String[] readen; while ((readen = reader.readNext()) != null) { if (readen[2].equals(day)) { Sale sl = new Sale(); sl.setUserID(readen[0]); sl.setProductName(readen[1]); sl.setDate(readen[2]); sl.setQtd(readen[3]); sl.setTotalCost(readen[4]); list.add(sl); } } reader.close(); return list; } /** * Retorna em uma lista todas as vendas realizadas em um ms de determinado * ano, onde ambos os valores de ms e ano so passados por parmetro. * As vendas encontradas so retornadas. * @param month * @param year * @return * @throws Exception */ public ObservableList<Sale> searchSalesByMonth(String month, String year) throws Exception { CSVReader reader = new CSVReader(new FileReader("sales.csv"), ','); ObservableList<Sale> list = FXCollections.observableArrayList(); String[] readen; while ((readen = reader.readNext()) != null) { String[] parts = readen[2].split("-"); System.out.println(readen[2] + parts[1] + parts[0]); if (parts[1].equals(month) && parts[0].equals(year)) { Sale sl = new Sale(); sl.setUserID(readen[0]); sl.setProductName(readen[1]); sl.setDate(readen[2]); sl.setQtd(readen[3]); sl.setTotalCost(readen[4]); list.add(sl); } } reader.close(); return list; } /** * Procura todos os usurios que desejassem receber notificao da atualizao * no estoque de produtos. Os achados so adicionados em uma lista, * e com o e-mail de cada um, uma mensagem enviada a cada usu[ario da lista. * @param itemUpdated * @return * @throws Exception */ public ObservableList<User> sendEmailToNotificatedUsers(String itemUpdated) throws Exception { CSVReader reader = new CSVReader(new FileReader("users.csv"), ','); ObservableList<User> list = FXCollections.observableArrayList(); String[] readen; while ((readen = reader.readNext()) != null) { if (Boolean.parseBoolean(readen[6])) { User u = new User(); u.setName(readen[0]); u.setAddress(readen[1]); u.setPhone(readen[2]); u.setEmail(readen[3]); u.setId(readen[4]); u.setPassword(readen[5]); u.setNotification(readen[6]); list.add(u); } } reader.close(); for (User u : list) { sendEmail(u.getEmail(), itemUpdated); } return list; } /** * Realiza a busca de todos os produtos do sistema, com a finalidade de passar * para a aplicao cliente estes dados. * @param pw * @throws IOException */ public void recoverAllProducts(PrintWriter pw) throws IOException { CSVReader reader = new CSVReader(new FileReader("products.csv"), ','); String[] readen = null; while ((readen = reader.readNext()) != null) { String p = readen[0] + "," + readen[1] + "," + readen[2] + "," + readen[3] + "," + readen[4]; pw.println(p); } pw.println("fim"); reader.close(); } /** * Verifica se os campos de login e senha existem e coincidem um mesmo usurio. * Retorna um valor boolean, que informa se existe ou no usurio com esses * parmetros. * @param id * @param password * @return * @throws Exception */ public boolean verifyLogin(String id, String password) throws Exception { CSVReader reader = new CSVReader(new FileReader("users.csv"), ','); String[] readen = null; while ((readen = reader.readNext()) != null) { if (readen[4].equals(id) && readen[5].equals(password)) return true; } reader.close(); return false; } /** * Atualiza o interesse de um usurio com UserID id em receber notificaes * de produtos em falta com o valor boolean value. * @param id * @param value * @throws Exception */ public void updateNotificationField(String id, boolean value) throws Exception { ObservableList<User> list = searchAllUsers(); for (User u : list) { if (u.getId().equals(id)) u.setNotification(Boolean.toString(value)); } CSVWriter writer = new CSVWriter(new FileWriter("users.csv", false)); for (User u : list) { String str = u.getName() + "," + u.getAddress() + "," + u.getPhone() + "," + u.getEmail() + "," + u.getId() + "," + u.getPassword() + "," + u.getNotification(); String[] toWrite = str.split(","); writer.writeNext(toWrite); } writer.close(); } /** * Atualiza a quantidade de um produto com nome name com a quantidade newQtd. * @param name * @param newQtd * @throws Exception */ public void updateProductQtd(String name, int newQtd) throws Exception { ObservableList<Product> list = searchAllProducts(); for (Product p : list) { if (p.getName().equals(name)) p.setQtd(Integer.toString(newQtd)); } CSVWriter writer = new CSVWriter(new FileWriter("products.csv", false)); for (Product p : list) { String str = p.getName() + "," + p.getPrice() + "," + p.getValidate() + "," + p.getProvider() + "," + p.getQtd(); String[] toWrite = str.split(","); writer.writeNext(toWrite); } writer.close(); } /** * Dado um email destinyEmail e o item atualizado itemUpdated, envia esse email * uma mensagem informando a atualizao de estoque. * @param destinyEmail * @param itemUpdated */ public void sendEmail(String destinyEmail, String itemUpdated) { Properties props = new Properties(); props.put("mail.smtp.auth", true); props.put("mail.smtp.starttls.enable", true); props.put("mail.smtp.host", "smtp.gmail.com"); props.put("mail.smtp.port", "587"); Session session = Session.getDefaultInstance(props, new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication("t4poo2015@gmail.com", "t4poo1234"); } }); String msgBody = "The product: \n\n--> " + itemUpdated + " <--\nhas been updated!\n\n" + "Carro&4 Supermarket."; try { Message msg = new MimeMessage(session); msg.setFrom(new InternetAddress("t4poo2015@gmail.com")); msg.addRecipients(Message.RecipientType.TO, InternetAddress.parse(destinyEmail)); msg.setSubject("Carro&4: Item updated!"); msg.setText(msgBody); Transport.send(msg); } catch (AddressException e) { System.out.println("Email address error!"); } catch (MessagingException e) { System.out.println("Error!"); } } /** * Dado o parmetro day, cria um relatrio de vendas do sistema nesse dia. * @param day * @throws Exception */ public void generateDayReport(String day) throws Exception { ObservableList<Sale> list = searchSalesByDay(day); Document dayReport = new Document(); PdfWriter.getInstance(dayReport, new FileOutputStream(day + " report. C4 Supermarket.pdf")); PdfPTable table = new PdfPTable(5); table.addCell("User ID"); table.addCell("Product Name"); table.addCell("Sale Date"); table.addCell("Qtd"); table.addCell("Sale Total Cost"); for (Sale sl : list) { table.addCell(sl.getUserID()); table.addCell(sl.getProductName()); table.addCell(sl.getDate()); table.addCell(sl.getQtd()); table.addCell(sl.getTotalCost()); } dayReport.open(); Paragraph header = new Paragraph("\t\tCARRO&4 SUPERMARKET\n" + day + " sales report.\n\n\n", new Font(FontFamily.COURIER, 30, Font.BOLD, new BaseColor(0, 0, 255))); dayReport.add(header); dayReport.add(table); dayReport.close(); } /** * Dados os parmetros month e year, cria uma relatrio de vendas realizadas * no ms do ano informado. * @param month * @param year * @throws Exception */ public void generateMonthReport(String month, String year) throws Exception { ObservableList<Sale> list = searchSalesByMonth(month, year); String date = month + "-" + year; Document dayReport = new Document(); PdfWriter.getInstance(dayReport, new FileOutputStream(date + " report. C4 Supermarket.pdf")); PdfPTable table = new PdfPTable(5); table.addCell("User ID"); table.addCell("Product Name"); table.addCell("Sale Date"); table.addCell("Qtd"); table.addCell("Sale Total Cost"); for (Sale sl : list) { table.addCell(sl.getUserID()); table.addCell(sl.getProductName()); table.addCell(sl.getDate()); table.addCell(sl.getQtd()); table.addCell(sl.getTotalCost()); } dayReport.open(); Paragraph header = new Paragraph("\t\tCARRO&4 SUPERMARKET\n" + date + " sales report.\n\n\n", new Font(FontFamily.COURIER, 30, Font.BOLD, new BaseColor(0, 0, 255))); dayReport.add(header); dayReport.add(table); dayReport.close(); } /** * Thread que aguarda constantemente dados enviados do cliente. * Uma vez que o cliente envia dados ao servidor, este filtra a mensagem e * executa o comando desejado. */ @Override public void run() { String toRead; String[] parts; while (true) { try { BufferedReader br = new BufferedReader(new InputStreamReader(this.s.getInputStream())); PrintWriter pw = new PrintWriter(this.s.getOutputStream(), true); toRead = br.readLine(); switch (toRead) { case "Register": String client = br.readLine(); this.addNewUser(client); break; case "Search": recoverAllProducts(pw); break; case "Login": String data = br.readLine(); parts = data.split(","); boolean answer = this.verifyLogin(parts[0], parts[1]); pw.println(Boolean.toString(answer)); break; case "Notification": String id = br.readLine(); String newValue = br.readLine(); this.updateNotificationField(id, Boolean.parseBoolean(newValue)); break; case "Buy": String sale = br.readLine(); parts = sale.split(","); Sale sl = new Sale(parts[0], parts[1], parts[2], parts[3], parts[5]); pw.println(Boolean.toString(this.addNewSale(sl, Integer.parseInt(parts[4])))); break; } } catch (IOException ex) { } catch (Exception ex) { Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex); } } } }