From 7a6f7d3ae84e07ad2327c2a68935dbb526b1bc32 Mon Sep 17 00:00:00 2001 From: gcesario203 <37389862+gcesario203@users.noreply.github.com> Date: Sat, 18 Jan 2025 16:05:23 -0300 Subject: [PATCH 1/2] =?UTF-8?q?docs=20-=20Adi=C3=A7=C3=A3o=20de=20arquivos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 31 + src/main/java/dominio/Address.java | 188 ++++ src/main/java/dominio/Author.java | 136 +++ src/main/java/dominio/Book.java | 401 ++++++++ src/main/java/dominio/CCTransaction.java | 172 ++++ src/main/java/dominio/Cart.java | 248 +++++ src/main/java/dominio/CartLine.java | 108 ++ src/main/java/dominio/Country.java | 146 +++ src/main/java/dominio/Customer.java | 443 ++++++++ src/main/java/dominio/Order.java | 255 +++++ src/main/java/dominio/OrderLine.java | 127 +++ src/main/java/dominio/Stock.java | 93 ++ src/main/java/servico/Bookmarket.java | 975 ++++++++++++++++++ src/main/java/servico/Bookstore.java | 1170 ++++++++++++++++++++++ src/main/java/util/TPCW_Util.java | 230 +++++ src/test/java/servico/BookstoreTest.java | 418 ++++++++ 16 files changed, 5141 insertions(+) create mode 100644 pom.xml create mode 100644 src/main/java/dominio/Address.java create mode 100644 src/main/java/dominio/Author.java create mode 100644 src/main/java/dominio/Book.java create mode 100644 src/main/java/dominio/CCTransaction.java create mode 100644 src/main/java/dominio/Cart.java create mode 100644 src/main/java/dominio/CartLine.java create mode 100644 src/main/java/dominio/Country.java create mode 100644 src/main/java/dominio/Customer.java create mode 100644 src/main/java/dominio/Order.java create mode 100644 src/main/java/dominio/OrderLine.java create mode 100644 src/main/java/dominio/Stock.java create mode 100644 src/main/java/servico/Bookmarket.java create mode 100644 src/main/java/servico/Bookstore.java create mode 100644 src/main/java/util/TPCW_Util.java create mode 100644 src/test/java/servico/BookstoreTest.java diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..f7497ff --- /dev/null +++ b/pom.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + br.unicamp.ic + bookMarketCore + inf329-grupo00 + jar + bookMarket + + + + org.apache.mahout + mahout-mr + 0.13.0 + + + junit + junit + 4.10 + test + + + + + UTF-8 + 1.8 + 1.8 + + + + diff --git a/src/main/java/dominio/Address.java b/src/main/java/dominio/Address.java new file mode 100644 index 0000000..05ce0db --- /dev/null +++ b/src/main/java/dominio/Address.java @@ -0,0 +1,188 @@ +package dominio; + +/* + * Address.java - Stores an address. + * + ************************************************************************ + * + * This is part of the the Java TPC-W distribution, + * written by Harold Cain, Tim Heil, Milo Martin, Eric Weglarz, and Todd + * Bezenek. University of Wisconsin - Madison, Computer Sciences + * Dept. and Dept. of Electrical and Computer Engineering, as a part of + * Prof. Mikko Lipasti's Fall 1999 ECE 902 course. + * + * Copyright (C) 1999, 2000 by Harold Cain, Timothy Heil, Milo Martin, + * Eric Weglarz, Todd Bezenek. + * Copyright © 2008 Gustavo Maciel Dias Vieira + * + * This source code is distributed "as is" in the hope that it will be + * useful. It comes with no warranty, and no author or distributor + * accepts any responsibility for the consequences of its use. + * + * Everyone is granted permission to copy, modify and redistribute + * this code under the following conditions: + * + * This code is distributed for non-commercial use only. + * Please contact the maintainer for restrictions applying to + * commercial use of these tools. + * + * Permission is granted to anyone to make or distribute copies + * of this code, either as received or modified, in any + * medium, provided that all copyright notices, permission and + * nonwarranty notices are preserved, and that the distributor + * grants the recipient permission for further redistribution as + * permitted by this document. + * + * Permission is granted to distribute this code in compiled + * or executable form under the same conditions that apply for + * source code, provided that either: + * + * A. it is accompanied by the corresponding machine-readable + * source code, + * B. it is accompanied by a written offer, with no time limit, + * to give anyone a machine-readable copy of the corresponding + * source code in return for reimbursement of the cost of + * distribution. This written offer must permit verbatim + * duplication by anyone, or + * C. it is distributed by someone who received only the + * executable form, and is accompanied by a copy of the + * written offer of source code that they received concurrently. + * + * In other words, you are welcome to use, share and improve this codes. + * You are forbidden to forbid anyone else to use, share and improve what + * you give them. + * + ************************************************************************/ +import java.io.Serializable; + +/** + * *Address + *
code + */ +public class Address implements Serializable { + + private static final long serialVersionUID = 3980790290181121772L; + + private final int id; + private final String street1; + private final String street2; + private final String city; + private final String state; + private final String zip; + private final Country country; + + /** + * + * @param id - + * @param street1 - + * @param street2 - + * @param city - + * @param state - + * @param zip - + * @param country - + */ + public Address(int id, String street1, String street2, String city, + String state, String zip, Country country) { + this.id = id; + this.street1 = street1; + this.street2 = street2; + this.city = city; + this.state = state; + this.zip = zip; + this.country = country; + } + + /** + * Recupera o ID do classe. + * + * @return retorna o ID que representa o endereço + */ + public int getId() { + return id; + } + + /** + * Recupera a primeira rua cadastrada. + * + * @return String street1 Primeira rua cadastrada + */ + public String getStreet1() { + return street1; + } + + /** + *Recupera a segunda rua cadastrada. + * + * @return String street2 Segunda rua cadastrada + */ + public String getStreet2() { + return street2; + } + + /** + * Recupera a cidade cadastrada. + * + * @return String city Cidade cadastrada + */ + public String getCity() { + return city; + } + + /** + * Recupera o estado cadastrado. + * + * @return String state Estado cadastrado + */ + public String getState() { + return state; + } + + /** + * REcupera o código postal. + * + * @return String zip código postal + */ + public String getZip() { + return zip; + } + + /** + * Recupera o país cadastrado. + * + * @return Country country País cadastrado + */ + public Country getCountry() { + return country; + } + + /** + * Verifica se um objeto é igual ao outro. + * + * @param o Objeto a ser comparado + * @return Verdade se e somente se o objeto for o mesmo. + */ + @Override + public boolean equals(Object o) { + if (o instanceof Address) { + Address address = (Address) o; + return street1.equals(address.street1) + && street2.equals(address.street2) + && city.equals(address.city) + && state.equals(address.state) + && zip.equals(address.zip) + && country.equals(address.country); + } + return false; + } + + /** + * Utilizado em auxílio com o equals para identificar um objeto igual. + * + * @return hash de identificação da classe. + */ + @Override + public int hashCode() { + return street1.hashCode() + street2.hashCode() + city.hashCode() + + state.hashCode() + zip.hashCode() + country.hashCode(); + } +} diff --git a/src/main/java/dominio/Author.java b/src/main/java/dominio/Author.java new file mode 100644 index 0000000..1dea250 --- /dev/null +++ b/src/main/java/dominio/Author.java @@ -0,0 +1,136 @@ +package dominio; + +/* + * Author.java - Data about an author. + * + ************************************************************************ + * + * This is part of the the Java TPC-W distribution, + * written by Harold Cain, Tim Heil, Milo Martin, Eric Weglarz, and Todd + * Bezenek. University of Wisconsin - Madison, Computer Sciences + * Dept. and Dept. of Electrical and Computer Engineering, as a part of + * Prof. Mikko Lipasti's Fall 1999 ECE 902 course. + * + * Copyright (C) 1999, 2000 by Harold Cain, Timothy Heil, Milo Martin, + * Eric Weglarz, Todd Bezenek. + * Copyright © 2008 Gustavo Maciel Dias Vieira + * + * This source code is distributed "as is" in the hope that it will be + * useful. It comes with no warranty, and no author or distributor + * accepts any responsibility for the consequences of its use. + * + * Everyone is granted permission to copy, modify and redistribute + * this code under the following conditions: + * + * This code is distributed for non-commercial use only. + * Please contact the maintainer for restrictions applying to + * commercial use of these tools. + * + * Permission is granted to anyone to make or distribute copies + * of this code, either as received or modified, in any + * medium, provided that all copyright notices, permission and + * nonwarranty notices are preserved, and that the distributor + * grants the recipient permission for further redistribution as + * permitted by this document. + * + * Permission is granted to distribute this code in compiled + * or executable form under the same conditions that apply for + * source code, provided that either: + * + * A. it is accompanied by the corresponding machine-readable + * source code, + * B. it is accompanied by a written offer, with no time limit, + * to give anyone a machine-readable copy of the corresponding + * source code in return for reimbursement of the cost of + * distribution. This written offer must permit verbatim + * duplication by anyone, or + * C. it is distributed by someone who received only the + * executable form, and is accompanied by a copy of the + * written offer of source code that they received concurrently. + * + * In other words, you are welcome to use, share and improve this codes. + * You are forbidden to forbid anyone else to use, share and improve what + * you give them. + * + ************************************************************************/ +import java.io.Serializable; +import java.util.Date; + +/** + * *Author + *
code + */ +public class Author implements Serializable { + + private static final long serialVersionUID = 8882043540800200706L; + + private final String fname; + private final String mname; + private final String lname; + private final Date birthdate; + private final String bio; + + /** + * Método construtor da classe Author. + * + * @param fname Primeiro nome do autor. + * @param mname Nome do meio do autor. + * @param lname Último nome do autor. + * @param birthdate Data de aniversário do autor. + * @param bio Biografia do autor. + */ + public Author(String fname, String mname, String lname, Date birthdate, + String bio) { + this.fname = fname; + this.mname = mname; + this.lname = lname; + this.birthdate = birthdate; + this.bio = bio; + } + + /** + * Método que recupera o primeiro nome do autor. + * + * @return Primeiro nome do autor. + */ + public String getFname() { + return fname; + } + + /** + * Método que recupera o último nome do autor. + * + * @return Último nome do autor. + */ + public String getLname() { + return lname; + } + + /** + * Método que recupera o nome do meio do autor. + * + * @return Nome do meio do autor. + */ + public String getMname() { + return mname; + } + + /** + * Método que recupera a data de aniversário do autor. + * + * @return Date birthdate Data de aniversário do autor. + */ + public Date getBirthdate() { + return birthdate; + } + + /** + * Método que recupera a biografia do autor. + * + * @return Biografia do autor. + */ + public String getBio() { + return bio; + } + +} diff --git a/src/main/java/dominio/Book.java b/src/main/java/dominio/Book.java new file mode 100644 index 0000000..e6dc742 --- /dev/null +++ b/src/main/java/dominio/Book.java @@ -0,0 +1,401 @@ +package dominio; + +/* + * Book.java - Class used to store all of the data associated with a single + * book. + * + ************************************************************************ + * + * This is part of the the Java TPC-W distribution, + * written by Harold Cain, Tim Heil, Milo Martin, Eric Weglarz, and Todd + * Bezenek. University of Wisconsin - Madison, Computer Sciences + * Dept. and Dept. of Electrical and Computer Engineering, as a part of + * Prof. Mikko Lipasti's Fall 1999 ECE 902 course. + * + * Copyright (C) 1999, 2000 by Harold Cain, Timothy Heil, Milo Martin, + * Eric Weglarz, Todd Bezenek. + * Copyright © 2008 Gustavo Maciel Dias Vieira + * + * This source code is distributed "as is" in the hope that it will be + * useful. It comes with no warranty, and no author or distributor + * accepts any responsibility for the consequences of its use. + * + * Everyone is granted permission to copy, modify and redistribute + * this code under the following conditions: + * + * This code is distributed for non-commercial use only. + * Please contact the maintainer for restrictions applying to + * commercial use of these tools. + * + * Permission is granted to anyone to make or distribute copies + * of this code, either as received or modified, in any + * medium, provided that all copyright notices, permission and + * nonwarranty notices are preserved, and that the distributor + * grants the recipient permission for further redistribution as + * permitted by this document. + * + * Permission is granted to distribute this code in compiled + * or executable form under the same conditions that apply for + * source code, provided that either: + * + * A. it is accompanied by the corresponding machine-readable + * source code, + * B. it is accompanied by a written offer, with no time limit, + * to give anyone a machine-readable copy of the corresponding + * source code in return for reimbursement of the cost of + * distribution. This written offer must permit verbatim + * duplication by anyone, or + * C. it is distributed by someone who received only the + * executable form, and is accompanied by a copy of the + * written offer of source code that they received concurrently. + * + * In other words, you are welcome to use, share and improve this codes. + * You are forbidden to forbid anyone else to use, share and improve what + * you give them. + * + ************************************************************************/ +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * *Book + *
code + */ +public class Book implements Serializable { + + private static final long serialVersionUID = 6505830715531808617L; + + private final int id; + private final String title; + private Date pubDate; + private final String publisher; + private final String subject; + private final String desc; + private Book related1; + private Book related2; + private Book related3; + private Book related4; + private Book related5; + private String thumbnail; + private String image; + private final double srp; + private final Date avail; + private final String isbn; + private final int page; + private final String backing; + private final String dimensions; + private final Author author; + + /** + * + * @param id - o id da instância de Book + * @param title - o título + * @param pubDate - a data da publicação + * @param publisher - o responsável pela publicação + * @param subject - o assunto + * @param desc - a descrição + * @param thumbnail - uma imagem reduzida para listagens + * @param image - uma imagem em alta resolução + * @param srp - o preço conforme o Sistema de Registro de Preços + * @param avail - a data de disponibilidade + * @param isbn - o código ISBN + * @param page - a quantidade de páginas + * @param backing - as informações sobre apoiadores + * @param dimensions - as dimensões + * @param author - o autor + */ + public Book(int id, String title, Date pubDate, String publisher, + String subject, String desc, String thumbnail, + String image, double srp, Date avail, String isbn, + int page, String backing, String dimensions, Author author + ) { + this.id = id; + this.title = title; + this.pubDate = pubDate; + this.publisher = publisher; + this.subject = subject; + this.desc = desc; + this.related1 = null; + this.related2 = null; + this.related3 = null; + this.related4 = null; + this.related5 = null; + this.thumbnail = thumbnail; + this.image = image; + this.srp = srp; + this.avail = avail; + this.isbn = isbn; + this.page = page; + this.backing = backing; + this.dimensions = dimensions; + this.author = author; + } + + /** + * + * @return getter que recupera o título + */ + public String getTitle() { + return title; + } + + /** + * + * @return getter que recupera uma imagem reduzida para listagens + */ + public String getThumbnail() { + return thumbnail; + } + + /** + * + * @param thumbnail - uma imagem reduzida para listagens + */ + public void setThumbnail(String thumbnail) { + this.thumbnail = thumbnail; + } + + + /** + * + * @return getter que recupera uma imagem em alta resolução + */ + public String getImage() { + return image; + } + + /** + * + * @param image - uma imagem em alta resolução + */ + public void setImage(String image) { + this.image = image; + } + + /** + * + * @return getter que recupera o autor + */ + public Author getAuthor() { + return author; + } + + /** + * + * @return getter que recupera o preço conforme o Sistema de Registro de Preços + */ + public double getSrp() { + return srp; + } + + + /** + * + * @return getter que recupera a descrição + */ + public String getDesc() { + return desc; + } + + /** + * + * @return getter que recupera a quantidade de páginas + */ + public int getPage() { + return page; + } + + /** + * + * @return getter que recupera as informações sobre apoiadores + */ + public String getBacking() { + return backing; + } + + /** + * + * @return getter que recupera a data da publicação + */ + public Date getPubDate() { + return pubDate; + } + + /** + * + * @param pubDate - a data da publicação + */ + public void setPubDate(Date pubDate) { + this.pubDate = pubDate; + } + + /** + * + * @return getter que recupera o responsável pela publicação + */ + public String getPublisher() { + return publisher; + } + + /** + * + * @return getter que recupera o código ISBN + */ + public String getIsbn() { + return isbn; + } + + /** + * + * @return getter que recupera o id da instância de Book + */ + public int getId() { + return id; + } + + /** + * + * @return getter que recupera as dimensões + */ + public String getDimensions() { + return dimensions; + } + + /** + * + * @return getter que recupera o assunto + */ + public String getSubject() { + return subject; + } + + /** + * + * @return getter que recupera a data de disponibilidade + */ + public Date getAvail() { + return avail; + } + + /** + * + * @return getter que recupera um livro relacionado com este + */ + public Book getRelated1() { + return related1; + } + + /** + * + * @return getter que recupera um livro relacionado com este + */ + public Book getRelated2() { + return related2; + } + + /** + * + * @return getter que recupera um livro relacionado com este + */ + public Book getRelated3() { + return related3; + } + + /** + * + * @return getter que recupera um livro relacionado com este + */ + public Book getRelated4() { + return related4; + } + + /** + * + * @return getter que recupera um livro relacionado com este + */ + public Book getRelated5() { + return related5; + } + + /** + * + * @param related1 - um livro relacionado com este + */ + public void setRelated1(Book related1) { + this.related1 = related1; + } + + /** + * + * @param related2 - um livro relacionado com este + */ + public void setRelated2(Book related2) { + this.related2 = related2; + } + + /** + * + * @param related3 - um livro relacionado com este + */ + public void setRelated3(Book related3) { + this.related3 = related3; + } + + /** + * + * @param related4 - um livro relacionado com este + */ + public void setRelated4(Book related4) { + this.related4 = related4; + } + + /** + * + * @param related5 - um livro relacionado com este + */ + public void setRelated5(Book related5) { + this.related5 = related5; + } + + /** + * + * @return uma lista de todos os livros relacionados + */ + public List getAllRelated() { + List related = new ArrayList<>(); + + related.add(this.getRelated1()); + related.add(this.getRelated2()); + related.add(this.getRelated3()); + related.add(this.getRelated4()); + related.add(this.getRelated5()); + + return related; + } + + /** + * + * @param o - a instância de Book a ser comparada + * @return um boolean que representa a igualdade entre esta instância e a representada por o + */ + @Override + public boolean equals(Object o) { + if (o instanceof Book) { + Book book = (Book) o; + return id == book.id; + } + return false; + } + + /** + * + * @return um int representando o hash code desta instância de Book + */ + @Override + public int hashCode() { + return id; + } + + } diff --git a/src/main/java/dominio/CCTransaction.java b/src/main/java/dominio/CCTransaction.java new file mode 100644 index 0000000..972c560 --- /dev/null +++ b/src/main/java/dominio/CCTransaction.java @@ -0,0 +1,172 @@ +package dominio; + +/* + * CCTransaction.java - Class holds data for a single credit card + * transaction. + * + ************************************************************************ + * + * This is part of the the Java TPC-W distribution, + * written by Harold Cain, Tim Heil, Milo Martin, Eric Weglarz, and Todd + * Bezenek. University of Wisconsin - Madison, Computer Sciences + * Dept. and Dept. of Electrical and Computer Engineering, as a part of + * Prof. Mikko Lipasti's Fall 1999 ECE 902 course. + * + * Copyright (C) 1999, 2000 by Harold Cain, Timothy Heil, Milo Martin, + * Eric Weglarz, Todd Bezenek. + * Copyright © 2008 Gustavo Maciel Dias Vieira + * + * This source code is distributed "as is" in the hope that it will be + * useful. It comes with no warranty, and no author or distributor + * accepts any responsibility for the consequences of its use. + * + * Everyone is granted permission to copy, modify and redistribute + * this code under the following conditions: + * + * This code is distributed for non-commercial use only. + * Please contact the maintainer for restrictions applying to + * commercial use of these tools. + * + * Permission is granted to anyone to make or distribute copies + * of this code, either as received or modified, in any + * medium, provided that all copyright notices, permission and + * nonwarranty notices are preserved, and that the distributor + * grants the recipient permission for further redistribution as + * permitted by this document. + * + * Permission is granted to distribute this code in compiled + * or executable form under the same conditions that apply for + * source code, provided that either: + * + * A. it is accompanied by the corresponding machine-readable + * source code, + * B. it is accompanied by a written offer, with no time limit, + * to give anyone a machine-readable copy of the corresponding + * source code in return for reimbursement of the cost of + * distribution. This written offer must permit verbatim + * duplication by anyone, or + * C. it is distributed by someone who received only the + * executable form, and is accompanied by a copy of the + * written offer of source code that they received concurrently. + * + * In other words, you are welcome to use, share and improve this codes. + * You are forbidden to forbid anyone else to use, share and improve what + * you give them. + * + ************************************************************************/ +import java.io.Serializable; +import java.util.Date; + +/** + * *CCTransaction + *
code + */ +public class CCTransaction implements Serializable { + + private static final long serialVersionUID = 5470177450411822726L; + + private final String type; + private final long num; + private final String name; + private final Date expire; + private final String authId; + private final double amount; + private final Date date; + private final Country country; + + /** + * + * @param type Tipo do cartão de crédito. + * @param num Número do cartão de crédito. + * @param name Nome do cartão de crédito. + * @param expire Data de expiração do cartão de crédito. + * @param authId Id de autenticação do cartão de crédito. + * @param amount Quantidade do cartão de crédito. + * @param date Data do cartão de crédito. + * @param country País do cartão de crédito. + */ + public CCTransaction(String type, long num, String name, Date expire, + String authId, double amount, Date date, Country country) { + this.type = type; + this.num = num; + this.name = name; + this.expire = expire; + this.authId = authId; + this.amount = amount; + this.date = date; + this.country = country; + } + + /** + * Método que recupera o tipo do cartão de crédito. + * + * @return Recupera o tipo do cartão de crédito. + */ + public String getType() { + return type; + } + + /** + * Método que recupera o número do cartão de crédito. + * + * @return Recupera o número do cartão de crédito. + */ + public long getNum() { + return num; + } + + /** + * Método que recupera o nome do cartão de crédito. + * + * @return Recupera o nome do cartão de crédito. + */ + public String getName() { + return name; + } + + /** + * Método a data de expiração do cartão de crédito. + * + * @return Recupera a data de expiração do cartão de crédito. + */ + public Date getExpire() { + return expire; + } + + /** + * Método que recupera o id de autentição do cartão de crédito. + * + * @return Recupera o id de autenticação do cartão de crédito. + */ + public String getAuthId() { + return authId; + } + + /** + * Método que recupera a quantidade do cartão de crédito. + * + * @return Recupera a quantidade do cartão de crédito. + */ + public double getAmount() { + return amount; + } + + /** + * Método que recupera a data do cartão de crédito. + * + * @return Recupera a data do cartão de crédito. + */ + public Date getDate() { + return date; + } + + /** + * Método que recupera o país do cartão de crédito. + * + * @return Recupera o país do cartão de crédito. + */ + public Country getCountry() { + return country; + } + +} diff --git a/src/main/java/dominio/Cart.java b/src/main/java/dominio/Cart.java new file mode 100644 index 0000000..8a64bfa --- /dev/null +++ b/src/main/java/dominio/Cart.java @@ -0,0 +1,248 @@ +package dominio; + +/* + * Cart.java - Class stores the necessary components of a shopping cart. + * + ************************************************************************ + * + * This is part of the the Java TPC-W distribution, + * written by Harold Cain, Tim Heil, Milo Martin, Eric Weglarz, and Todd + * Bezenek. University of Wisconsin - Madison, Computer Sciences + * Dept. and Dept. of Electrical and Computer Engineering, as a part of + * Prof. Mikko Lipasti's Fall 1999 ECE 902 course. + * + * Copyright (C) 1999, 2000 by Harold Cain, Timothy Heil, Milo Martin, + * Eric Weglarz, Todd Bezenek. + * Copyright © 2008 Gustavo Maciel Dias Vieira + * + * This source code is distributed "as is" in the hope that it will be + * useful. It comes with no warranty, and no author or distributor + * accepts any responsibility for the consequences of its use. + * + * Everyone is granted permission to copy, modify and redistribute + * this code under the following conditions: + * + * This code is distributed for non-commercial use only. + * Please contact the maintainer for restrictions applying to + * commercial use of these tools. + * + * Permission is granted to anyone to make or distribute copies + * of this code, either as received or modified, in any + * medium, provided that all copyright notices, permission and + * nonwarranty notices are preserved, and that the distributor + * grants the recipient permission for further redistribution as + * permitted by this document. + * + * Permission is granted to distribute this code in compiled + * or executable form under the same conditions that apply for + * source code, provided that either: + * + * A. it is accompanied by the corresponding machine-readable + * source code, + * B. it is accompanied by a written offer, with no time limit, + * to give anyone a machine-readable copy of the corresponding + * source code in return for reimbursement of the cost of + * distribution. This written offer must permit verbatim + * duplication by anyone, or + * C. it is distributed by someone who received only the + * executable form, and is accompanied by a copy of the + * written offer of source code that they received concurrently. + * + * In other words, you are welcome to use, share and improve this codes. + * You are forbidden to forbid anyone else to use, share and improve what + * you give them. + * + ************************************************************************/ +import java.io.Serializable; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; + +/** + * *Cart + *
code + */ +public class Cart implements Serializable { + + private static final long serialVersionUID = -4194553499937996531L; + + private final int id; + private Date time; + private HashMap linesByBookId; + private double aggregateCost; + private int aggregateQuantity; + + /** + * + * @param id Identificador do carrinho de compras. + * @param time Tempo do carrinho de compras. + */ + public Cart(int id, Date time) { + this.id = id; + this.time = time; + clear(); + } + + /** + * Método que recupera o identificador do carrinho de compras. + * + * @return Recupera o identificador do carrinho de compras. + */ + public int getId() { + return id; + } + + /** + * Método que recupera o tempo do carrinho de compras. + * + * @return Recupera o tempo do carrinho de compras. + */ + public Date getTime() { + return time; + } + + /** + * Método que define o tempo do carrinho de compras. + * + * @param time Define o tempo do carrinho de compras. + */ + public void setTime(Date time) { + this.time = time; + } + + /** + *
+	 * linesByBookId = new HashMap<Integer, CartLine>();
+	 * aggregateCost = 0;
+	 * aggregateQuantity = 0;
+	 * 
+ */ + public void clear() { + linesByBookId = new HashMap(); + aggregateCost = 0; + aggregateQuantity = 0; + } + + /** + * Método que recupera uma lista de itens do carrinho de compras. + * + * @return Recupera uma lista de itens do carrinho de compras. + */ + public Collection getLines() { + return linesByBookId.values(); + } + + /** + *
+     * CartLine line = linesByBookId.get(book.getId());
+     * if (line == null) {
+     * line = new CartLine(0, book);
+     * linesByBookId.put(book.getId(), line);
+     * }
+     * aggregateCost += book.getCost() * quantity;
+     * aggregateQuantity += quantity;
+     * line.setQty(line.getQty() + quantity);
+     * if (quantity == 0) {
+     * linesByBookId.remove(book.getId());
+     * }
+     * 
+ * + * @param stock Estoque. + * @param book Livro. + * @param quantity Quantidade. + */ + public void increaseLine(Stock stock, Book book, int quantity) { + CartLine line = linesByBookId.get(book.getId()); + if (line == null) { + line = new CartLine(0, book); + linesByBookId.put(book.getId(), line); + } + aggregateCost += stock.getCost() * quantity; + aggregateQuantity += quantity; + line.setQty(line.getQty() + quantity); + if (quantity == 0) { + linesByBookId.remove(book.getId()); + } + } + + /** + *
+     *   CartLine line = linesByBookId.get(book.getId());
+     * if (line == null) {
+     * line = new CartLine(0, book);
+     * linesByBookId.put(book.getId(), line);
+     * }
+     * aggregateCost += book.getCost() * (quantity - line.getQty());
+     * aggregateQuantity += (quantity - line.getQty());
+     * line.setQty(quantity);
+     * if (quantity == 0) {
+     * linesByBookId.remove(book.getId());
+     * }
+     * 
+ * + * @param stock Estoque. + * @param book Livro. + * @param quantity Quantidade. + */ + public void changeLine(Stock stock, Book book, int quantity) { + CartLine line = linesByBookId.get(book.getId()); + if (line == null) { + line = new CartLine(0, book); + linesByBookId.put(book.getId(), line); + } + aggregateCost += stock.getCost() * (quantity - line.getQty()); + aggregateQuantity += (quantity - line.getQty()); + line.setQty(quantity); + if (quantity == 0) { + linesByBookId.remove(book.getId()); + } + } + + /** + *
+	 * return aggregateCost * ((100 - discount) * 0.01);
+	 * 
+ * + * @param discount Desconto a se aplicado. + * @return valor do livro com desconto. + */ + public double subTotal(double discount) { + return aggregateCost * ((100 - discount) * 0.01); + } + + /** + *
+     * return subTotal(discount) * 0.0825;
+     * 
+ * + * @param discount Desconto a ser aplicado. + * @return valor do livro com desconto. + */ + public double tax(double discount) { + return subTotal(discount) * 0.0825; + } + + /** + *
+     * return 3.00 + (1.00 * aggregateQuantity);
+     * 
+ * + * @return valor do frete. + */ + public double shipCost() { + return 3.00 + (1.00 * aggregateQuantity); + } + + /** + *
+     * return subTotal(discount) + shipCost() + tax(discount);
+     * 
+ * + * @param discount Desconto a ser aplicado. + * @return valor total do livro. + */ + public double total(double discount) { + return subTotal(discount) + shipCost() + tax(discount); + } + +} diff --git a/src/main/java/dominio/CartLine.java b/src/main/java/dominio/CartLine.java new file mode 100644 index 0000000..a715959 --- /dev/null +++ b/src/main/java/dominio/CartLine.java @@ -0,0 +1,108 @@ +package dominio; + +/* + * CartLine.java - Class stores the necessary data for a single item in + * a single shopping cart. + * + ************************************************************************ + * + * This is part of the the Java TPC-W distribution, + * written by Harold Cain, Tim Heil, Milo Martin, Eric Weglarz, and Todd + * Bezenek. University of Wisconsin - Madison, Computer Sciences + * Dept. and Dept. of Electrical and Computer Engineering, as a part of + * Prof. Mikko Lipasti's Fall 1999 ECE 902 course. + * + * Copyright (C) 1999, 2000 by Harold Cain, Timothy Heil, Milo Martin, + * Eric Weglarz, Todd Bezenek. + * Copyright © 2008 Gustavo Maciel Dias Vieira + * + * This source code is distributed "as is" in the hope that it will be + * useful. It comes with no warranty, and no author or distributor + * accepts any responsibility for the consequences of its use. + * + * Everyone is granted permission to copy, modify and redistribute + * this code under the following conditions: + * + * This code is distributed for non-commercial use only. + * Please contact the maintainer for restrictions applying to + * commercial use of these tools. + * + * Permission is granted to anyone to make or distribute copies + * of this code, either as received or modified, in any + * medium, provided that all copyright notices, permission and + * nonwarranty notices are preserved, and that the distributor + * grants the recipient permission for further redistribution as + * permitted by this document. + * + * Permission is granted to distribute this code in compiled + * or executable form under the same conditions that apply for + * source code, provided that either: + * + * A. it is accompanied by the corresponding machine-readable + * source code, + * B. it is accompanied by a written offer, with no time limit, + * to give anyone a machine-readable copy of the corresponding + * source code in return for reimbursement of the cost of + * distribution. This written offer must permit verbatim + * duplication by anyone, or + * C. it is distributed by someone who received only the + * executable form, and is accompanied by a copy of the + * written offer of source code that they received concurrently. + * + * In other words, you are welcome to use, share and improve this codes. + * You are forbidden to forbid anyone else to use, share and improve what + * you give them. + * + ************************************************************************/ +import java.io.Serializable; + +/** + * *CartLine + *
code + */ +public class CartLine implements Serializable { + + private static final long serialVersionUID = 7390646727961714957L; + + private int qty; + private final Book book; + + /** + * + * @param qty Quantidade itens relacionados ao mesmo Book para o carrinho de + * compras. + * @param book Livro relacionado com o carrinho de compras. + */ + public CartLine(int qty, Book book) { + this.qty = qty; + this.book = book; + } + + /** + * Define a quantidade de itens relacionados ao mesmo Book para o carrinho + * + * @param qty quantidade de itens + */ + public void setQty(int qty) { + this.qty = qty; + } + + /** + * Recupera a quantidade de itens relacionados com o livro em um carrinho + * + * @return Quantidade de itens do carrinho para o mesmo livro + */ + public int getQty() { + return qty; + } + + /** + * Recupera o livro relacionado com o carrinho + * + * @return Um dos livros que está no carrinho + */ + public Book getBook() { + return book; + } + +} diff --git a/src/main/java/dominio/Country.java b/src/main/java/dominio/Country.java new file mode 100644 index 0000000..b46139b --- /dev/null +++ b/src/main/java/dominio/Country.java @@ -0,0 +1,146 @@ +package dominio; + +/* + * Country.java - Stores a country. + * + ************************************************************************ + * + * This is part of the the Java TPC-W distribution, + * written by Harold Cain, Tim Heil, Milo Martin, Eric Weglarz, and Todd + * Bezenek. University of Wisconsin - Madison, Computer Sciences + * Dept. and Dept. of Electrical and Computer Engineering, as a part of + * Prof. Mikko Lipasti's Fall 1999 ECE 902 course. + * + * Copyright (C) 1999, 2000 by Harold Cain, Timothy Heil, Milo Martin, + * Eric Weglarz, Todd Bezenek. + * Copyright © 2008 Gustavo Maciel Dias Vieira + * + * This source code is distributed "as is" in the hope that it will be + * useful. It comes with no warranty, and no author or distributor + * accepts any responsibility for the consequences of its use. + * + * Everyone is granted permission to copy, modify and redistribute + * this code under the following conditions: + * + * This code is distributed for non-commercial use only. + * Please contact the maintainer for restrictions applying to + * commercial use of these tools. + * + * Permission is granted to anyone to make or distribute copies + * of this code, either as received or modified, in any + * medium, provided that all copyright notices, permission and + * nonwarranty notices are preserved, and that the distributor + * grants the recipient permission for further redistribution as + * permitted by this document. + * + * Permission is granted to distribute this code in compiled + * or executable form under the same conditions that apply for + * source code, provided that either: + * + * A. it is accompanied by the corresponding machine-readable + * source code, + * B. it is accompanied by a written offer, with no time limit, + * to give anyone a machine-readable copy of the corresponding + * source code in return for reimbursement of the cost of + * distribution. This written offer must permit verbatim + * duplication by anyone, or + * C. it is distributed by someone who received only the + * executable form, and is accompanied by a copy of the + * written offer of source code that they received concurrently. + * + * In other words, you are welcome to use, share and improve this codes. + * You are forbidden to forbid anyone else to use, share and improve what + * you give them. + * + ************************************************************************/ +import java.io.Serializable; + +/** + * *Country + *
code + */ +public class Country implements Serializable { + + private static final long serialVersionUID = 5171617014956861344L; + + private final int id; + private final String name; + private final String currency; + private final double exchange; + + /** + * + * @param id Id que representa o país + * @param name Nome do país + * @param currency moeda do país + * @param exchange taxa de cambio do país + */ + public Country(int id, String name, String currency, double exchange) { + this.id = id; + this.name = name; + this.currency = currency; + this.exchange = exchange; + } + + /** + * Recupera o ID da classe de representação do país. + * + * @return id da classe que representa o país + */ + public int getId() { + return id; + } + + /** + * Recupera o nome do país. + * + * @return nome do país + */ + public String getName() { + return name; + } + + /** + * Recupera a moeda local do país + * + * @return moeda local. + */ + public String getCurrency() { + return currency; + } + + /** + * Reucpera o valor de cambio do país + * + * @return valor de cambio + */ + public double getExchange() { + return exchange; + } + + /** + * Verifica se um objeto é igual ao outro. + * + * @param o Objeto a ser comparado + * @return Verdade se e somente se o objeto for o mesmo. + */ + @Override + public boolean equals(Object o) { + if (o instanceof Country) { + Country country = (Country) o; + return name.equals(country.name); + } + return false; + } + + /** + * Utilizado em auxílio com o equals para identificar um objeto igual. + * + * @return hash de identificação da classe. + */ + @Override + public int hashCode() { + return name.hashCode(); + } + +} diff --git a/src/main/java/dominio/Customer.java b/src/main/java/dominio/Customer.java new file mode 100644 index 0000000..4149096 --- /dev/null +++ b/src/main/java/dominio/Customer.java @@ -0,0 +1,443 @@ +package dominio; + +/* + * Customer.java - stores the important information for a single customer. + * + ************************************************************************ + * + * This is part of the the Java TPC-W distribution, + * written by Harold Cain, Tim Heil, Milo Martin, Eric Weglarz, and Todd + * Bezenek. University of Wisconsin - Madison, Computer Sciences + * Dept. and Dept. of Electrical and Computer Engineering, as a part of + * Prof. Mikko Lipasti's Fall 1999 ECE 902 course. + * + * Copyright (C) 1999, 2000 by Harold Cain, Timothy Heil, Milo Martin, + * Eric Weglarz, Todd Bezenek. + * Copyright © 2008 Gustavo Maciel Dias Vieira + * + * This source code is distributed "as is" in the hope that it will be + * useful. It comes with no warranty, and no author or distributor + * accepts any responsibility for the consequences of its use. + * + * Everyone is granted permission to copy, modify and redistribute + * this code under the following conditions: + * + * This code is distributed for non-commercial use only. + * Please contact the maintainer for restrictions applying to + * commercial use of these tools. + * + * Permission is granted to anyone to make or distribute copies + * of this code, either as received or modified, in any + * medium, provided that all copyright notices, permission and + * nonwarranty notices are preserved, and that the distributor + * grants the recipient permission for further redistribution as + * permitted by this document. + * + * Permission is granted to distribute this code in compiled + * or executable form under the same conditions that apply for + * source code, provided that either: + * + * A. it is accompanied by the corresponding machine-readable + * source code, + * B. it is accompanied by a written offer, with no time limit, + * to give anyone a machine-readable copy of the corresponding + * source code in return for reimbursement of the cost of + * distribution. This written offer must permit verbatim + * duplication by anyone, or + * C. it is distributed by someone who received only the + * executable form, and is accompanied by a copy of the + * written offer of source code that they received concurrently. + * + * In other words, you are welcome to use, share and improve this codes. + * You are forbidden to forbid anyone else to use, share and improve what + * you give them. + * + ************************************************************************/ +import java.io.Serializable; +import java.util.Date; +import java.util.Objects; + +/** + * *Customer + *
code + */ +public class Customer implements Serializable { + + private static final long serialVersionUID = -7297414189618511748L; + + private final int id; + private final String uname; + private final String passwd; + private final String fname; + private final String lname; + private final String phone; + private final String email; + private final Date since; + private final Date lastVisit; + private Date login; + private Date expiration; + private final double discount; + private final double balance; + private final double ytdPmt; + private final Date birthdate; + private final String data; + private final Address address; + private Order mostRecentOrder; + + /** + * + * @param id Id que representa a classe + * @param uname Nome de identificação do Customer + * @param passwd senha do Customer + * @param fname primeiro nome do Customer + * @param lname último nome do customer + * @param phone telefone do Customer + * @param email email do customer + * @param since data de início do custoemr + * @param lastVisit última visita ao customer + * @param login data de login do customer + * @param expiration data de expiração de login + * @param discount desconto possibilitado + * @param balance balanço contábil + * @param ytdPmt ytdPmt + * @param birthdate data de nascimento do Customer + * @param data Dados do Customer + * @param address Endereço do Customer + */ + public Customer(int id, String uname, String passwd, String fname, + String lname, String phone, String email, Date since, + Date lastVisit, Date login, Date expiration, double discount, + double balance, double ytdPmt, Date birthdate, String data, + Address address) { + this.id = id; + this.uname = uname; + this.passwd = passwd; + this.fname = fname; + this.lname = lname; + this.phone = phone; + this.email = email; + this.since = since; + this.lastVisit = lastVisit; + this.login = login; + this.expiration = expiration; + this.discount = discount; + this.balance = balance; + this.ytdPmt = ytdPmt; + this.birthdate = birthdate; + this.data = data; + this.address = address; + mostRecentOrder = null; + } + + /** + * + * @param id + * @param uname + * @param toLowerCase + * @param fname + * @param lname + * @param phone + * @param email + * @param since + * @param lastVisit + */ + public Customer(int id, String uname, String toLowerCase, String fname, String lname, String phone, String email, Date since, Date lastVisit) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + /** + * Define a data de login do Customer. + * + * @param login representação do horário de login do Customer + */ + public void setLogin(Date login) { + this.login = login; + } + + /** + * Define uma data de expiração para o login do Customer. + * + * @param expiration data representando o limite para expiração do login do Customer. + */ + public void setExpiration(Date expiration) { + this.expiration = expiration; + } + + /** + * Recupera o primeiro nome do Customer + * + * @return primeiro nome do Customer + */ + public String getFname() { + return fname; + } + + /** + * Recupera o último nome do Customer + * + * @return último nome do Customer + */ + public String getLname() { + return lname; + } + + /** + * Recupera o ID da classe + * + * @return Id que representa a classe + */ + public int getId() { + return id; + } + + /** + * Recupera a senha do Customer + * + * @return senha do Customer + */ + public String getPasswd() { + return passwd; + } + + /** + * Recupera o desconto que este Customer possibilita + * + * @return desconto possibilitado pelo Customer. + */ + public double getDiscount() { + return discount; + } + + /** + * Recupera endereço do Address + * + * @return Endereço do Customer + */ + public Address getAddress() { + return address; + } + + /** + * Recupera telefone do Customer + * + * @return telefone do customer + */ + public String getPhone() { + return phone; + } + + /** + * Recupera o email do Customer + * + * @return email do Customer + */ + public String getEmail() { + return email; + } + + /** + * Recupera o nome de identificação do Customer + * + * @return nome de identificação do Customer. + */ + public String getUname() { + return uname; + } + + /** + * Insere uma nova compra no log de compra recente + * + * @param order que representa a última compra efetuada + */ + public void logOrder(Order order) { + mostRecentOrder = order; + } + + /** + * Recupera a última compra efetuada + * + * @return última compra efetuada neste Customer. + */ + public Order getMostRecentOrder() { + return mostRecentOrder; + } + + /** + * Recupera data de início do customer + * + * @return data em que o Customer iniciou as atividades + */ + public Date getSince() { + return since; + } + + /** + * Recupera última visita ao Customer + * + * @return Data da última visita ao customer + */ + public Date getLastVisit() { + return lastVisit; + } + + /** + * Recupera data de login do Customer + * + * @return Data de login + */ + public Date getLogin() { + return login; + } + + /** + * Recupera data de expiração apra o login do Customer + * + * @return data de expiração de login + */ + public Date getExpiration() { + return expiration; + } + + /** + * Recupera o balanço contábil + * + * @return balanço contábil + */ + public double getBalance() { + return balance; + } + + /** + * Recupera ytdPmt + * + * @return ytdPmt + */ + public double getYtdPmt() { + return ytdPmt; + } + + /** + * Recupera data de nascimento do Customer + * + * @return Data de nascimento do Customer + */ + public Date getBirthdate() { + return birthdate; + } + + /** + * Recupera dados do Customer + * + * @return dados do Customer + */ + public String getData() { + return data; + } + + /** + * + * @return + */ + @Override + public int hashCode() { + int hash = 5; + hash = 29 * hash + this.id; + hash = 29 * hash + Objects.hashCode(this.uname); + hash = 29 * hash + Objects.hashCode(this.passwd); + hash = 29 * hash + Objects.hashCode(this.fname); + hash = 29 * hash + Objects.hashCode(this.lname); + hash = 29 * hash + Objects.hashCode(this.phone); + hash = 29 * hash + Objects.hashCode(this.email); + hash = 29 * hash + Objects.hashCode(this.since); + hash = 29 * hash + Objects.hashCode(this.lastVisit); + hash = 29 * hash + Objects.hashCode(this.login); + hash = 29 * hash + Objects.hashCode(this.expiration); + hash = 29 * hash + (int) (Double.doubleToLongBits(this.discount) ^ (Double.doubleToLongBits(this.discount) >>> 32)); + hash = 29 * hash + (int) (Double.doubleToLongBits(this.balance) ^ (Double.doubleToLongBits(this.balance) >>> 32)); + hash = 29 * hash + (int) (Double.doubleToLongBits(this.ytdPmt) ^ (Double.doubleToLongBits(this.ytdPmt) >>> 32)); + hash = 29 * hash + Objects.hashCode(this.birthdate); + hash = 29 * hash + Objects.hashCode(this.data); + hash = 29 * hash + Objects.hashCode(this.address); + hash = 29 * hash + Objects.hashCode(this.mostRecentOrder); + return hash; + } + + /** + * + * @param obj + * @return + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Customer other = (Customer) obj; + if (this.id != other.id) { + return false; + } + if (Double.doubleToLongBits(this.discount) != Double.doubleToLongBits(other.discount)) { + return false; + } + if (Double.doubleToLongBits(this.balance) != Double.doubleToLongBits(other.balance)) { + return false; + } + if (Double.doubleToLongBits(this.ytdPmt) != Double.doubleToLongBits(other.ytdPmt)) { + return false; + } + if (!Objects.equals(this.uname, other.uname)) { + return false; + } + if (!Objects.equals(this.passwd, other.passwd)) { + return false; + } + if (!Objects.equals(this.fname, other.fname)) { + return false; + } + if (!Objects.equals(this.lname, other.lname)) { + return false; + } + if (!Objects.equals(this.phone, other.phone)) { + return false; + } + if (!Objects.equals(this.email, other.email)) { + return false; + } + if (!Objects.equals(this.data, other.data)) { + return false; + } + if (!Objects.equals(this.since, other.since)) { + return false; + } + if (!Objects.equals(this.lastVisit, other.lastVisit)) { + return false; + } + if (!Objects.equals(this.login, other.login)) { + return false; + } + if (!Objects.equals(this.expiration, other.expiration)) { + return false; + } + if (!Objects.equals(this.birthdate, other.birthdate)) { + return false; + } + if (!Objects.equals(this.address, other.address)) { + return false; + } + if (!Objects.equals(this.mostRecentOrder, other.mostRecentOrder)) { + return false; + } + return true; + } + + + + + +} diff --git a/src/main/java/dominio/Order.java b/src/main/java/dominio/Order.java new file mode 100644 index 0000000..8683238 --- /dev/null +++ b/src/main/java/dominio/Order.java @@ -0,0 +1,255 @@ +package dominio; + +/* + * Order.java - Order class stores data pertinent to a single order. + * + ************************************************************************ + * + * This is part of the the Java TPC-W distribution, + * written by Harold Cain, Tim Heil, Milo Martin, Eric Weglarz, and Todd + * Bezenek. University of Wisconsin - Madison, Computer Sciences + * Dept. and Dept. of Electrical and Computer Engineering, as a part of + * Prof. Mikko Lipasti's Fall 1999 ECE 902 course. + * + * Copyright (C) 1999, 2000 by Harold Cain, Timothy Heil, Milo Martin, + * Eric Weglarz, Todd Bezenek. + * Copyright © 2008 Gustavo Maciel Dias Vieira + * + * This source code is distributed "as is" in the hope that it will be + * useful. It comes with no warranty, and no author or distributor + * accepts any responsibility for the consequences of its use. + * + * Everyone is granted permission to copy, modify and redistribute + * this code under the following conditions: + * + * This code is distributed for non-commercial use only. + * Please contact the maintainer for restrictions applying to + * commercial use of these tools. + * + * Permission is granted to anyone to make or distribute copies + * of this code, either as received or modified, in any + * medium, provided that all copyright notices, permission and + * nonwarranty notices are preserved, and that the distributor + * grants the recipient permission for further redistribution as + * permitted by this document. + * + * Permission is granted to distribute this code in compiled + * or executable form under the same conditions that apply for + * source code, provided that either: + * + * A. it is accompanied by the corresponding machine-readable + * source code, + * B. it is accompanied by a written offer, with no time limit, + * to give anyone a machine-readable copy of the corresponding + * source code in return for reimbursement of the cost of + * distribution. This written offer must permit verbatim + * duplication by anyone, or + * C. it is distributed by someone who received only the + * executable form, and is accompanied by a copy of the + * written offer of source code that they received concurrently. + * + * In other words, you are welcome to use, share and improve this codes. + * You are forbidden to forbid anyone else to use, share and improve what + * you give them. + * + ************************************************************************/ +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Date; + +/** + * *Order + *
code + */ +public class Order implements Serializable { + + private static final long serialVersionUID = -1106285234830970111L; + + private final int id; + private final Customer customer; + private final Date date; + private final double subtotal; + private final double tax; + private final double total; + private final String shipType; + private final Date shipDate; + private final String status; + private final Address billingAddress; + private final Address shippingAddress; + private final CCTransaction cc; + private final ArrayList lines; + + /** + *
+	 * this.id = id;
+	 * this.customer = customer;
+	 * this.date = date;
+	 * subtotal = cart.subTotal(customer.getDiscount());
+	 * tax = 8.25;
+	 * total = cart.total(customer.getDiscount());
+	 * this.shipType = shipType;
+	 * this.shipDate = shipDate;
+	 * this.status = status;
+	 * this.billingAddress = billingAddress;
+	 * this.shippingAddress = shippingAddress;
+	 * this.cc = cc;
+	 * lines = new ArrayList<OrderLine>(cart.getLines().size());
+	 * for (CartLine cartLine : cart.getLines()) {
+	 * 	OrderLine line = new OrderLine(cartLine.getBook(), cartLine.getQty(), customer.getDiscount(), comment);
+	 * 	lines.add(line);
+	 * }
+	 * 
+ * + * @param id Identficador da venda. + * @param customer Cliente da venda. + * @param date Data da venda. + * @param cart Carrinho de compras da venda. + * @param comment Coementário da venda. + * @param shipType Tipo do frete da venda. + * @param shipDate Data do frete da venda. + * @param status Status da venda. + * @param billingAddress Endereço de cobrança da venda. + * @param shippingAddress Endereço de entrega da venda. + * @param cc Cartão de crédito da venda. + */ + public Order(int id, Customer customer, Date date, Cart cart, + String comment, String shipType, Date shipDate, String status, + Address billingAddress, Address shippingAddress, CCTransaction cc) { + this.id = id; + this.customer = customer; + this.date = date; + subtotal = cart.subTotal(customer.getDiscount()); + tax = 8.25; + total = cart.total(customer.getDiscount()); + this.shipType = shipType; + this.shipDate = shipDate; + this.status = status; + this.billingAddress = billingAddress; + this.shippingAddress = shippingAddress; + this.cc = cc; + lines = new ArrayList(cart.getLines().size()); + for (CartLine cartLine : cart.getLines()) { + OrderLine line = new OrderLine(cartLine.getBook(), + cartLine.getQty(), customer.getDiscount(), + comment); + lines.add(line); + } + } + + /** + * Método que recupera o identificador da venda. + * + * @return Recupera o identificador da venda. + */ + public int getId() { + return id; + } + + /** + * Método que recupera o cliente da venda. + * + * @return Recupera o cliente da venda. + */ + public Customer getCustomer() { + return customer; + } + + /** + * Método que recupera a data da venda. + * + * @return Recupera a data da venda. + */ + public Date getDate() { + return date; + } + + /** + * Método que recupera o subtotal da venda. + * + * @return Recupera o subtotal da venda. + */ + public double getSubtotal() { + return subtotal; + } + + /** + * Método que recupera a taxa da venda. + * + * @return Recupera a taxa da venda. + */ + public double getTax() { + return tax; + } + + /** + * Método que recupera o valor total da venda. + * + * @return Recupera o valor total da venda. + */ + public double getTotal() { + return total; + } + + /** + * Método que recupera o tipo de frete da venda. + * + * @return Recupera o tipo de frete da venda. + */ + public String getShipType() { + return shipType; + } + + /** + * Método que recupera a data do frete da venda. + * + * @return Recupera a data do frete da venda. + */ + public Date getShipDate() { + return shipDate; + } + + /** + * Método que recupera o status da venda. + * + * @return Recupera o status da venda. + */ + public String getStatus() { + return status; + } + + /** + * Método que recupera o endereço de cobrança da venda. + * + * @return Recupera o endereço de cobrança da venda. + */ + public Address getBillingAddress() { + return billingAddress; + } + + /** + * Método que recupera o endereço de entrega da venda. + * + * @return Recupera o endereço de entrega da venda. + */ + public Address getShippingAddress() { + return shippingAddress; + } + + /** + * Método que recupera o cartão de crédito da venda. + * + * @return Recupera o cartão de crédito da venda. + */ + public CCTransaction getCC() { + return cc; + } + + /** + * Método que recupera itens da venda. + * @return Recupera itens da venda. + */ + public ArrayList getLines() { + return lines; + } + +} diff --git a/src/main/java/dominio/OrderLine.java b/src/main/java/dominio/OrderLine.java new file mode 100644 index 0000000..eb89bd8 --- /dev/null +++ b/src/main/java/dominio/OrderLine.java @@ -0,0 +1,127 @@ +package dominio; + +/* + * OrderLine.java - Class contains the data pertinent to a single + * item in a single order. + * + ************************************************************************ + * + * This is part of the the Java TPC-W distribution, + * written by Harold Cain, Tim Heil, Milo Martin, Eric Weglarz, and Todd + * Bezenek. University of Wisconsin - Madison, Computer Sciences + * Dept. and Dept. of Electrical and Computer Engineering, as a part of + * Prof. Mikko Lipasti's Fall 1999 ECE 902 course. + * + * Copyright (C) 1999, 2000 by Harold Cain, Timothy Heil, Milo Martin, + * Eric Weglarz, Todd Bezenek. + * Copyright © 2008 Gustavo Maciel Dias Vieira + * + * This source code is distributed "as is" in the hope that it will be + * useful. It comes with no warranty, and no author or distributor + * accepts any responsibility for the consequences of its use. + * + * Everyone is granted permission to copy, modify and redistribute + * this code under the following conditions: + * + * This code is distributed for non-commercial use only. + * Please contact the maintainer for restrictions applying to + * commercial use of these tools. + * + * Permission is granted to anyone to make or distribute copies + * of this code, either as received or modified, in any + * medium, provided that all copyright notices, permission and + * nonwarranty notices are preserved, and that the distributor + * grants the recipient permission for further redistribution as + * permitted by this document. + * + * Permission is granted to distribute this code in compiled + * or executable form under the same conditions that apply for + * source code, provided that either: + * + * A. it is accompanied by the corresponding machine-readable + * source code, + * B. it is accompanied by a written offer, with no time limit, + * to give anyone a machine-readable copy of the corresponding + * source code in return for reimbursement of the cost of + * distribution. This written offer must permit verbatim + * duplication by anyone, or + * C. it is distributed by someone who received only the + * executable form, and is accompanied by a copy of the + * written offer of source code that they received concurrently. + * + * In other words, you are welcome to use, share and improve this codes. + * You are forbidden to forbid anyone else to use, share and improve what + * you give them. + * + ************************************************************************/ +import java.io.Serializable; + +/** + * *OrderLine
+ * code + * + * Esta classe existe para que seja possível criar uma representaçào da venda de + * um item na biblioteca. É importante salientar que todas as modificações que + * existem na quantidade são refletidas . Isto é feito pois cada OrderLine + * possui relação com um {@linkplain Book} + */ +public class OrderLine implements Serializable { + + private static final long serialVersionUID = -5063511252485472431L; + + private final Book book; + private final int qty; + private final double discount; + private final String comments; + + /** + * + * @param book Livro do item da venda.. + * @param qty Quantidade do item da venda.. + * @param discount Dessconto do item da venda.. + * @param comments Comentários do item da venda.. + */ + public OrderLine(Book book, int qty, double discount, String comments) { + this.book = book; + this.qty = qty; + this.discount = discount; + this.comments = comments; + } + + /** + * Método que recupera o livro do item da venda. + * + * @return Recupera o livro do item da venda. + */ + public Book getBook() { + return book; + } + + /** + * Método que recupera a quantidade do item da venda. + * + * @return Recupera a quantidade do item da venda. + */ + public int getQty() { + return qty; + } + + /** + * Método que recupera o desconto do item da venda. + * + * @return Recupera o desconto do item da venda. + */ + public double getDiscount() { + return discount; + } + + /** + * Método que recupera os comentários do item da venda. + * + * @return Recupera os comentários do item da venda. + */ + public String getComments() { + return comments; + } + +} diff --git a/src/main/java/dominio/Stock.java b/src/main/java/dominio/Stock.java new file mode 100644 index 0000000..23bb53c --- /dev/null +++ b/src/main/java/dominio/Stock.java @@ -0,0 +1,93 @@ +package dominio; + +/** + * Bookmarket
+ * code + * + */ +public class Stock { + + private final int idBookstore; + private final Book book; + private double cost; + private int qty; + + /** + * Cria uma classe que representa o stock do sistema. + * + * @param idBookstore Identificador do Bookstore do estoque. + * @param book Livro em estoque. + * @param cost Custo unitário do livro em estoque. + * @param qty Quantidade em estoque. + */ + public Stock(int idBookstore, Book book, double cost, int qty) { + this.idBookstore = idBookstore; + this.book = book; + this.cost = cost; + this.qty = qty; + } + + /** + * Método que recupera livro em estoque. + * + * @return Recupera livro em estoque. + */ + public Book getBook() { + return book; + } + + /** + * Método que adiciona quantidade em estoque. + * + * @param amount Adiciona quantidade em estoque. + */ + public void addQty(int amount) { + qty += amount; + } + + /** + * Método que recupera custo unitário do livro em estoque. + * + * @return Recupera custo em estoque. + */ + public double getCost() { + return cost; + } + + /** + * Método que define custo unitário do livro em estoque. + * + * @param cost Define custo em estoque. + */ + public void setCost(double cost) { + this.cost = cost; + } + + /** + * Método que recupera quantidade em estoque. + * + * @return Recupera quantidade em estoque. + */ + public int getQty() { + return qty; + } + + /** + * Método que define quantidade em estoque. + * + * @param qty Define quantidade em estoque. + */ + public void setQty(int qty) { + this.qty = qty; + } + + /** + * Método que recupera o identificador do Bookstore do estoque. + * + * @return Recupera o identificador do Bookstore do estoque. + */ + public int getIdBookstore() { + return idBookstore; + } + +} diff --git a/src/main/java/servico/Bookmarket.java b/src/main/java/servico/Bookmarket.java new file mode 100644 index 0000000..9751af4 --- /dev/null +++ b/src/main/java/servico/Bookmarket.java @@ -0,0 +1,975 @@ +package servico; + +import dominio.Address; +import dominio.Book; +import dominio.Cart; +import dominio.Customer; +import dominio.Order; +import dominio.Stock; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import util.TPCW_Util; + +/** + + * + * Esta classe existe com o objetivo final de representar o marketplace dentro + * do sistema. Ela é responsável por gerenciar uma lista de + * {@linkplain Bookstore} que representam as lojas existentes. Para realizar o + * controle das lojas contidas no marketplace, {@linkplain Bookmarket} utiliza + * uma máquina de estados que é acionada utilizando uma variação do padrão + * COMMAND. Cada estado desta máquina é representado por uma das lojas + * ({@linkplain Bookstore}) cadastradas. A variação do padrão COMMAND é baseada + * em cima da interface {@linkplain Action}. Todas as ações executadas pela + * máquina de estados implementam esta interface, tornando possível melhor + * entendimento e desacoplamento da lógica de ações a serem tomadas pelo sistema + * de acordo com seu estado. + * + * Cada pedaço da lógica por baixo de cada condição é separado em um manipulador + * do comando, tornando possível a criação da máquina de estados simples e pouco + * verborrágica. + * + * O mecanismo de execução criado para os estados da máquina permitem a + * modularização de comandos para praticamente todos os modelos utilizados + * dentro do sistema. Para realizar este feito, os comandos específicos dos + * modelos implementam a interface {@linkplain Action} com um método default e + * criam uma abstração chamada {@linkplain BookstoreAction}. Esta abstração + * define que o tipo de dado que é tratado em suas execuções é um stream, + * facilitando assim a manipulação de listas dentro do sistema atual. + * + */ +public class Bookmarket { + + private interface Action { + + Object executeOn(STATE sm); + } + + private static class StateMachine { + + private final List state; + + public StateMachine(final List object) { + this.state = object; + } + + Object execute(Action action) { + return action.executeOn(getStateStream()); + } + + void checkpoint() { + + } + + public Stream getStateStream() { + return state.stream(); + } + + private static StateMachine create(Bookstore... state) { + List list = new ArrayList(); + try { + list.addAll(Arrays.asList(state)); + } catch (Exception e) { + throw new UmbrellaException(e); + } + return new StateMachine(list); + } + + } + + private static class UmbrellaException extends RuntimeException { + + /** + * Default Generated SerialUID + */ + private static final long serialVersionUID = 8525983676993371110L; + + public UmbrellaException(Exception e) { + super(e); + } + + } + private static Random random; + private static StateMachine stateMachine; + + /** + * Método utilizado para inicializar o Bookmarket e criar uma lista de + * Bookstores vinculadas ao Bookmarket. + * + * @param state array de Bookstores criados para compor a máquina de estados + */ + public static void init(Bookstore... state) { + random = new Random(); + try { + stateMachine = StateMachine.create(state); + } catch (UmbrellaException e) { + throw new RuntimeException(e); + } + } + + private static Stream getBookstoreStream() { + return stateMachine.getStateStream(); + } + + /** + * Método utilizado para pegar o customer pelo uname cadastrado na + * Bookstore. + * + * @param UNAME Uname de identificação do Customer + * @return Customer Customer recuperado na lista cadastrada no sistema + */ + public static Customer getCustomer(String UNAME) { + return Bookstore.getCustomer(UNAME).get(); + } + + /** + * Método utilizado para pegar o nome completo do customer cadastrado na + * Bookstore pelo id. Retorna um array de string com o nome completo. + * + * @param c_id Id + * @return String[] Nome completo do user sendo: getName()[0] = primeiro + * nome; getName()[1] = último nome; getName()[2] = Nome de identificação; + */ + public static String[] getName(int c_id) { + + Customer customer = Bookstore.getCustomer(c_id); + + String name[] = new String[3]; + name[0] = customer.getFname(); + name[1] = customer.getLname(); + name[2] = customer.getUname(); + return name; + } + + /** + * Método utilizado para pegar o username do customer cadastrado na + * Bookstore pelo id. Retorna a string do username. + * + * @param C_ID ID + * @return String Nome de usuário do Customer + */ + public static String getUserName(int C_ID) { + return Bookstore.getCustomer(C_ID).getUname(); + } + + /** + * Método utilizado para pegar a password do customer cadastrado na + * Bookstore pelo username. Retorna a string da password. + * + * @param C_UNAME Nome de usuário + * @return String Senha do usuário especificado + */ + public static String getPassword(String C_UNAME) { + return Bookstore.getCustomer(C_UNAME).get().getPasswd(); + + } + + /** + * Método utilizado para pegar a compra mais recente do customer na + * Bookstore pelo username. Retorna o objeto da compra. + * + * @param c_uname Nome do usuário + * @return Order Compra mais recente do Customer + */ + public static Order getMostRecentOrder(String c_uname) { + return Bookstore.getCustomer(c_uname).get().getMostRecentOrder(); + } + + /** + * Método utilizado para cadastrar um novo usuário na Bookstore. O desconto + * é gerado randomicamente. É excutado o estado de CreationCustomerAction + * para a criação do customer. Se algum erro ocorre na criação, é gerado um + * RuntimeExpection. + * + * @param fname Primeiro nome do usuário + * @param lname último nome do usuário + * @param street1 Endereço 1 + * @param street2 Endereço 2 + * @param city Cidade do usuário + * @param state Estado do usuário + * @param zip Código postal + * @param countryName Nome do país + * @param phone telefone do usuário + * @param email email do usuário + * @param birthdate Data de nascimento do usuário + * @param data Dados do usuário + * @return Customer Novo Customer cadastrado na plataforma + */ + public static Customer createNewCustomer(String fname, String lname, + String street1, String street2, String city, String state, + String zip, String countryName, String phone, String email, + Date birthdate, String data) { + double discount = (int) (Math.random() * 51); + long now = System.currentTimeMillis(); + try { + return (Customer) stateMachine.execute(new CreateCustomerAction( + fname, lname, street1, street2, city, state, zip, + countryName, phone, email, discount, birthdate, data, now)); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * Método utilizado para execução da máquina de estado + * RefreshCustomerSessionAction, passando como parametros o id do customer + * cadastrado na Bookstore, e data atual em milesegundos. Esse estado + * executa o método de refresh interno do Bookstore, que irá renovar a + * sessão do usuário em duas horas. + * + * @param cId Id da sessão + */ + public static void refreshSession(int cId) { + try { + stateMachine.execute(new RefreshCustomerSessionAction(cId, + System.currentTimeMillis())); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * Método utilizado para retornar um livro específico através do id. + * + * @param i_id Id do livro desejado + * @return Livro recuperado dentro da plataforma + */ + public static Book getBook(int i_id) { + + return Bookstore.getBook(i_id).get(); + + } + + /** + * Método utilizado para retornar um livro randômico através do + * {@linkplain Bookstore}. + * + * @return Um livro qualquer cadastrado dentro da plataforma + */ + public static Book getABookAnyBook() { + return Bookstore.getABookAnyBook(random); + + } + + /** + * Método utilizado para retornar uma lista de livros filtrados através de + * um parâmetro do tipo string representando o assunto do livro. + * + * @param search_key Assunto do livro para filtrar busca + * @return Lista de livros que atendem aos critérios de filtro por assunto + */ + public static List doSubjectSearch(String search_key) { + return Bookstore.getBooksBySubject(search_key); + } + + /** + * Método utilizado para retornar uma lista de livros filtrados através de + * um parâmetro do tipo string representando o título do livro. + * + * @param search_key Título do livro para filtrar busca + * @return Lista de livros que atendem aos critérios de filtro por título + */ + public static List doTitleSearch(String search_key) { + return Bookstore.getBooksByTitle(search_key); + } + + /** + * Método utilizado para retornar uma lista de livros filtrados através de + * um parâmetro do tipo string representando o autor do livro. + * + * @param search_key Autor do livro para filtrar busca + * @return Lista de livros que atendem aos critérios de filtro por autor + */ + public static List doAuthorSearch(String search_key) { + return Bookstore.getBooksByAuthor(search_key); + } + + /** + * Método utilizado para retornar uma lista de livros cuja data de + * publicação seja da mais recente para a mais antiga, filtrados pelo + * assunto. + * + * @param subject Assunto do livro para filtrar a busca + * @return Lista de livros com data de publicação mais recente + */ + public static List getNewProducts(String subject) { + return Bookstore.getNewBooks(subject); + } + + /** + * Retorna todos os preços de um determinado livro, passado por parâmetro, + * para cada {@linkplain Bookstore} existente no {@linkplain Bookmarket}. + * + * @param book Livro que será utilizado no filtro de busca + * @return Lista com os preços de um determinado livro dentro do marketPlace + */ + public static List getCosts(Book book) { + return getBookstoreStream(). + map(store -> store.getStock(book.getId())). + map(stock -> stock.getCost()). + collect(Collectors.toList()); + } + + /** + * + * @param subject + * @return + */ + public static List getBestSellers(String subject) { + return null; + } + + /** + * + * @param c_id + * @return + */ + public static List getRecommendationByItens(int c_id) { + return Bookstore.getRecommendationByItens(c_id); + } + + /** + * A recomendação de livros para usuários do Bookmarket aproveita a + * implementação estática do mesmo método da Bookstore para recuperar os + * livros. + * + * @param c_id Id do usuário que necessita de livros recomendados pelo + * sistema + * @return Retorna uma lista de livros com limite de 5 itens recomendados + * pelo sistema. + */ + public static List getRecommendationByUsers(int c_id) { + return Bookstore.getRecommendationByUsers(c_id); + } + + /** + * Retorna a disponibilidade um livro na lista de {@linkplain Bookstore} do + * {@linkplain Bookmarket}, à partir de um parâmetro de identifição do + * livro. + * + * @param idBook ID que representa o livro a ser consultado + * @return Lista + */ + public static List getStocks(final int idBook) { + return getBookstoreStream() + .filter(store -> store.getStock(idBook) != null) + // transforma o stream de bookstore em stream de stock + .map(store -> store.getStock(idBook)) + .collect(Collectors.toList()); + } + + /** + * Retorna a disponibilidade de um livro em uma {@linkplain Bookstore} + * específica. + * + * @param idBookstore + * @param idBook + * @return + */ + public static Stock getStock(final int idBookstore, final int idBook) { + return getBookstoreStream() + .filter(store -> store.getId() == idBookstore) + // transforma o stream de bookstore em stream de stock + .map(store -> store.getStock(idBook)) + .findFirst() + .get(); + } + + /** + * Retorna uma lista de livros que sejam relacionados a um livro específico. + * + * @param i_id + * @return + */ + public static List getRelated(int i_id) { + Book book = Bookstore.getBook(i_id).get(); + ArrayList related = new ArrayList<>(5); + related.add(book.getRelated1()); + related.add(book.getRelated2()); + related.add(book.getRelated3()); + related.add(book.getRelated4()); + related.add(book.getRelated5()); + return related; + } + + /** + * Método utilizado para atualizar os dados de um livro específico. + * + * @param iId + * @param cost + * @param image + * @param thumbnail + */ + public static void adminUpdate(int iId, double cost, String image, + String thumbnail) { + try { + stateMachine.execute(new UpdateBookAction(iId, cost, image, + thumbnail, System.currentTimeMillis())); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * Cria um carrinho de compras vazio atrelado a uma determinada + * {@linkplain Bookstore}. + * + * @param storeId + * @return + */ + public static int createEmptyCart(int storeId) { + try { + return ((Cart) stateMachine.execute(new CreateCartAction(storeId, + System.currentTimeMillis()))).getId(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * Executa a atualização do carrinho de compras, se o carrinho estiver vazio + * adiciona um livro qualquer ao carrinho de compras. + * + * @param storeId + * @param SHOPPING_ID + * @param I_ID + * @param ids + * @param quantities + * @return + */ + public static Cart doCart(int storeId, int SHOPPING_ID, Integer I_ID, List ids, + List quantities) { + try { + Cart cart = (Cart) stateMachine.execute(new CartUpdateAction(storeId, + SHOPPING_ID, I_ID, ids, quantities, + System.currentTimeMillis())); + if (cart.getLines().isEmpty()) { + Book book = Bookstore.getABookAnyBook(random); + cart = (Cart) stateMachine.execute(new CartUpdateAction(storeId, + SHOPPING_ID, book.getId(), new ArrayList<>(), + new ArrayList<>(), System.currentTimeMillis())); + } + return cart; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * Retorna o carrinho de compras específico de um {@linkplain Bookstore} + * específico. + * + * @param SHOPPING_ID + * @param storeId + * @return + */ + public static Cart getCart(int storeId, int SHOPPING_ID) { + Bookstore bookstore = getBookstoreStream() + .filter(store -> store.getId() == storeId) + .findFirst() + .get(); + synchronized (bookstore) { + return bookstore.getCart(SHOPPING_ID); + } + } + + /** + * Método utilizado para execução da ação ConfirmBuyAction na máquina de + * estado para a confirmação da compra. + * + * @param storeId + * @param shopping_id + * @param customer_id + * @param cc_type + * @param cc_number + * @param cc_name + * @param cc_expiry + * @param shipping + * @return + */ + public static Order doBuyConfirm(int storeId, int shopping_id, int customer_id, + String cc_type, long cc_number, String cc_name, Date cc_expiry, + String shipping) { + long now = System.currentTimeMillis(); + try { + return (Order) stateMachine.execute(new ConfirmBuyAction(storeId, + customer_id, shopping_id, randomComment(), + cc_type, cc_number, cc_name, cc_expiry, shipping, + randomShippingDate(now), -1, now)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * Método utilizado para execução da ação ConfirmBuyAction na máquina de + * estado para a confirmação da compra. + * + * @param storeId + * @param shopping_id + * @param customer_id + * @param cc_type + * @param cc_number + * @param cc_name + * @param cc_expiry + * @param shipping + * @param street_1 + * @param street_2 + * @param city + * @param state + * @param zip + * @param country + * @return + */ + public static Order doBuyConfirm(int storeId, int shopping_id, int customer_id, + String cc_type, long cc_number, String cc_name, Date cc_expiry, + String shipping, String street_1, String street_2, String city, + String state, String zip, String country) { + Address address = Bookstore.alwaysGetAddress(street_1, street_2, + city, state, zip, country); + long now = System.currentTimeMillis(); + try { + return (Order) stateMachine.execute(new ConfirmBuyAction(storeId, + customer_id, shopping_id, randomComment(), + cc_type, cc_number, cc_name, cc_expiry, shipping, + randomShippingDate(now), address.getId(), now)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private static String randomComment() { + return TPCW_Util.getRandomString(random, 20, 100); + } + + private static Date randomShippingDate(long now) { + return new Date(now + 86400000 /* a day */ * (random.nextInt(7) + 1)); + } + + /** + * Método utilizado para execução da ação PopulateAction na máquina de + * estado para adição de dados na {@linkplain Bookstore}. + * + * @param items + * @param customers + * @param addresses + * @param authors + * @param orders + * @return + */ + public static boolean populate(int items, int customers, int addresses, + int authors, int orders) { + try { + return (Boolean) stateMachine.execute(new PopulateAction(random.nextLong(), + System.currentTimeMillis(), items, customers, addresses, + authors, orders)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * + */ + public static void checkpoint() { + try { + stateMachine.checkpoint(); + } catch (UmbrellaException e) { + throw new RuntimeException(e); + } + } + + /** + * Classe abstrata para representar os métodos padrões da implementação das + * ações na {@linkplain Bookstore}. + * + */ + protected static abstract class BookstoreAction implements Action>, + Serializable { + + /** + * Determina em qual {@linkplain Bookstore} a ação será executada. + * + * @param sm + * @return + */ + @Override + public Object executeOn(Stream sm) { + return executeOnBookstore(sm); + } + + /** + * Método abstrato que será implementado na classe concreta determinando + * qual ação será executada no {@linkplain Bookstore}. + * + * @param bookstore + * @return + */ + public abstract Object executeOnBookstore(Stream bookstore); + } + + /** + * Classe que implementa as ações relacionadas a criação de cliente. + */ + protected static class CreateCustomerAction extends BookstoreAction { + + private static final long serialVersionUID = 6039962163348790677L; + + String fname; + String lname; + String street1; + String street2; + String city; + String state; + String zip; + String countryName; + String phone; + String email; + double discount; + Date birthdate; + String data; + long now; + + /** + * Método construtor da classe. + * + * @param fname + * @param lname + * @param street1 + * @param street2 + * @param city + * @param state + * @param zip + * @param countryName + * @param phone + * @param email + * @param discount + * @param birthdate + * @param data + * @param now + */ + public CreateCustomerAction(String fname, String lname, String street1, + String street2, String city, String state, String zip, + String countryName, String phone, String email, + double discount, Date birthdate, String data, long now) { + this.fname = fname; + this.lname = lname; + this.street1 = street1; + this.street2 = street2; + this.city = city; + this.state = state; + this.zip = zip; + this.countryName = countryName; + this.phone = phone; + this.email = email; + this.discount = discount; + this.birthdate = birthdate; + this.data = data; + this.now = now; + } + + /** + * Método que injeta o cliente com suas respectivas informações dentro + * da {@linkplain Bookstore}. + * + * @param bookstore + * @return + */ + @Override + public Object executeOnBookstore(Stream bookstore) { + return Bookstore.createCustomer(fname, lname, street1, street2, + city, state, zip, countryName, phone, email, discount, + birthdate, data, now); + } + } + + /** + * Classe que implementa as ações relacionadas a sessão do cliente. + */ + protected static class RefreshCustomerSessionAction extends BookstoreAction { + + private static final long serialVersionUID = -5391031909452321478L; + + int cId; + long now; + + /** + * Método construtor da classe. + * + * @param id + * @param now + */ + public RefreshCustomerSessionAction(int id, long now) { + cId = id; + this.now = now; + } + + /** + * Executa a função do {@linkplain Bookstore} que atualiza a sessão do + * cliente. + * + * @param bookstore + * @return + */ + @Override + public Object executeOnBookstore(Stream bookstore) { + Bookstore.refreshCustomerSession(cId, now); + return null; + } + } + + /** + * Classe que implementa as ações relacionadas a atualização do livro. + */ + protected static class UpdateBookAction extends BookstoreAction { + + private static final long serialVersionUID = -745697943594643776L; + + int bId; + double cost; + String image; + String thumbnail; + long now; + + /** + * Método construtor da classe. + * + * @param id + * @param cost + * @param image + * @param thumbnail + * @param now + */ + public UpdateBookAction(int id, double cost, String image, + String thumbnail, long now) { + bId = id; + this.cost = cost; + this.image = image; + this.thumbnail = thumbnail; + this.now = now; + } + + /** + * Executa o método na {@linkplain Bookstore} que atualiza os dados de + * um livro específico. + * + * @param bookstore + * @return + */ + @Override + public Object executeOnBookstore(Stream bookstore) { + Bookstore.updateBook(bId, image, thumbnail, now); + return null; + } + } + + /** + * Classe que implementa as ações relacionadas a criação do carrinho de + * compras. + */ + protected static class CreateCartAction extends BookstoreAction { + + private static final long serialVersionUID = 8255648428785854052L; + + long now, storeId; + + /** + * Método construtor do carrinho de compras para um + * {@linkplain Bookstore} específico. + * + * @param idBookstore + * @param now + */ + public CreateCartAction(int idBookstore, long now) { + this.now = now; + this.storeId = idBookstore; + } + + /** + * Cria um carrinho de compras para um {@linkplain Bookstore} + * específico. + * + * @param bookstore + * @return + */ + @Override + public Object executeOnBookstore(Stream bookstore) { + return bookstore.filter(bs -> bs.getId() == this.storeId).findFirst().get().createCart(now); + } + } + + /** + * Classe que implementa as ações relacionadas a atualização do carrinho de + * compras. + */ + protected static class CartUpdateAction extends BookstoreAction { + + private static final long serialVersionUID = -6062032194650262105L; + + final int cId, storeId; + final Integer bId; + final List bIds; + final List quantities; + final long now; + + /** + * Método construtor da classe. + * + * @param storeId + * @param id + * @param id2 + * @param ids + * @param quantities + * @param now + */ + public CartUpdateAction(int storeId, int id, Integer id2, List ids, + List quantities, long now) { + this.storeId = storeId; + cId = id; + bId = id2; + bIds = ids; + this.quantities = quantities; + this.now = now; + } + + /** + * Atualiza um carrinho de compras em um {@linkplain Bookstore}. + * + * @param bookstore + * @return + */ + @Override + public Object executeOnBookstore(Stream bookstore) { + return bookstore.filter(bs -> bs.getId() == this.storeId).findFirst().get().cartUpdate(cId, bId, bIds, quantities, now); + } + } + + /** + * Classe que implementa as ações relacionadas a confirmação de compra. + */ + protected static class ConfirmBuyAction extends BookstoreAction { + + private static final long serialVersionUID = -6180290851118139002L; + + final int customerId, storeId, cartId; + String comment; + String ccType; + long ccNumber; + String ccName; + Date ccExpiry; + String shipping; + Date shippingDate; + int addressId; + long now; + + /** + * Método construtor da classe. + * + * @param storeId + * @param customerId + * @param cartId + * @param comment + * @param ccType + * @param ccNumber + * @param ccName + * @param ccExpiry + * @param shipping + * @param shippingDate + * @param addressId + * @param now + */ + public ConfirmBuyAction(int storeId, int customerId, int cartId, + String comment, String ccType, long ccNumber, + String ccName, Date ccExpiry, String shipping, + Date shippingDate, int addressId, long now) { + this.storeId = storeId; + this.customerId = customerId; + this.cartId = cartId; + this.comment = comment; + this.ccType = ccType; + this.ccNumber = ccNumber; + this.ccName = ccName; + this.ccExpiry = ccExpiry; + this.shipping = shipping; + this.shippingDate = shippingDate; + this.addressId = addressId; + this.now = now; + } + + /** + * Confirma a compra de um carrinho de compras de um + * {@linkplain Bookstore}. + * + * @param bookstore + * @return + */ + @Override + public Object executeOnBookstore(Stream bookstore) { + return bookstore.filter(bs -> bs.getId() == this.storeId).findFirst().get().confirmBuy(customerId, cartId, comment, ccType, + ccNumber, ccName, ccExpiry, shipping, shippingDate, + addressId, now); + } + } + + /** + * Classe que implementa as ações relacionadas a preenchimento dos dados do + * {@linkplain Bookstore}. + */ + protected static class PopulateAction extends BookstoreAction { + + private static final long serialVersionUID = -5240430799502573886L; + + long seed; + long now; + int items; + int customers; + int addresses; + int authors; + int orders; + + /** + * Método construtor da classe. + * + * @param seed + * @param now + * @param items + * @param customers + * @param addresses + * @param authors + * @param orders + */ + public PopulateAction(long seed, long now, int items, int customers, + int addresses, int authors, int orders) { + this.seed = seed; + this.now = now; + this.items = items; + this.customers = customers; + this.addresses = addresses; + this.authors = authors; + this.orders = orders; + } + + /** + * Popula os dados do {@linkplain Bookstore}. + * + * @param bookstore + * @return + */ + @Override + public Object executeOnBookstore(Stream bookstore) { + Bookstore.populate(seed, now, items, customers, addresses, authors); + Random rand = new Random(seed); + bookstore.forEach(instance -> instance.populateInstanceBookstore(orders, rand, now)); + return true; + } + } + +} diff --git a/src/main/java/servico/Bookstore.java b/src/main/java/servico/Bookstore.java new file mode 100644 index 0000000..5078993 --- /dev/null +++ b/src/main/java/servico/Bookstore.java @@ -0,0 +1,1170 @@ +package servico; + +/* + * Bookstore.java - holds all the data and operations of the bookstore. + * + */ +import dominio.Address; +import dominio.Author; +import dominio.Book; +import dominio.CCTransaction; +import dominio.Cart; +import dominio.Country; +import dominio.Customer; +import dominio.Order; +import dominio.OrderLine; +import dominio.Stock; +import util.TPCW_Util; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Random; +import java.util.regex.Pattern; + +/** + * Descrição da Arquitetura do Bookstore + * + * A classe Bookstore representa o backlog e o armazenamento da loja virtual, + * pois de acordo com a sua arquitetura, a mesma está associada a todas as + * classes de domínio e dentre seus métodos há aqueles que irão popular os + * bancos de dados dessas classes, ou senão cadastrar / adicionar novos itens a + * estas listas. Além de também proporcionar a correlação com o Bookmarket + * quanto à consulta ou aquisição de livros e demais dados. + * + * Os parâmetros que serão populados são: Autor, Livro, Endereço, Cartão de + * Crédito, Carrinho de Compras, País, Cliente, Pedido, e Estoque. Esses + * parâmetros estão interligados através do Id do consumidor ou do Livro. Dessa + * forma, quando métodos do tipo: getBestSellers, getNewBooks, getBooksByTitle + * forem chamados, será possivel adquirir todos os dados necessários referente + * ao que foi solicitado. + * + * Suas demais funcionalidades permitem cadastrar itens que não estão inclusos + * nos bancos de dados atuais dos parâmetros, cadastrar novos clientes, mapear + * diversas consultas que serão utilizadas posteriormente pela classe Bookmarket + * e finalizar o pedido de compra, através da transação do cartão de crédito + * cadastrado do cliente, e em seguida criar a ordem de envio do pedido, como + * pode ser visualizado pelo método confirmBuy(). + * + * Vale lembrar que os bancos de dados são populados inicialmente por itens + * estabelecidos pelos métodos populateCountries, populateStocks, + * populateAddresses, entre outros, e depois correlacionados entre si de maneira + * randômica / aleatória, a fim de criar uma grande quantidade de diferentes + * tipos de consumidores, livros, entre outros. + * + */ +/** + * + */ +public class Bookstore implements Serializable { + + private static final long serialVersionUID = -3099048826035606338L; + + private static boolean populated; + private static final List countryById; + private static final Map countryByName; + private static final List
addressById; + private static final Map addressByAll; + private static final List customersById; + private static final Map customersByUsername; + private static final List authorsById; + private static final List booksById; + + private final Map stockByBook; + private final List cartsById; + private final List ordersById; + private final LinkedList ordersByCreation; + private final int id; + + /** + * Bloco static que executa a inicialização dos atriutos estáticos da + * Bookstore + */ + static { + countryById = new ArrayList<>(); + countryByName = new HashMap<>(); + addressById = new ArrayList<>(); + addressByAll = new HashMap<>(); + customersById = new ArrayList<>(); + customersByUsername = new HashMap<>(); + authorsById = new ArrayList<>(); + booksById = new ArrayList<>(); + + } + + /** + * Construtor da classe Bookstore.Recebe como parâmetro o id da Bookstore. + * Faz a inicialização dos atributos da instância (objeto) da Bookstore. + * + * @param id - o código da Bookstore + */ + public Bookstore(final int id) { + this.id = id; + cartsById = new ArrayList<>(); + ordersById = new ArrayList<>(); + ordersByCreation = new LinkedList<>(); + stockByBook = new HashMap<>(); + } + + /** + * + * @return + */ + public int getId() { + return id; + } + + /** + + * + * @return + */ + public boolean isPopulated() { + return populated; + } + + /** + * Busca por um objeto Country com o nome passado no seu argumento, se nao + * encontrar, o Country eh criado sem currency (moeda) e sem com coeficiente + * de equivalencia (exchange) igual a zero, e assim, sempre retornara o + * Country buscado. + * + * @param name - o nome do país + * @return um país com o nome definido por name + */ + private static Country alwaysGetCountry(String name) { + Country country = countryByName.get(name); + if (country == null) { + country = createCountry(name, "", 0); + } + return country; + } + + /** + * Busca por um objeto Country baseando-se num gerador de aleatorios do tipo + * Random que deve ser instanciado pelo desenvolvedor que quiser utilizar o + * metodo. + + * @param random Dado randômico / aleatório + * @return countryById País do Id escolhido + */ + private static Country getACountryAnyCountry(Random random) { + return countryById.get(random.nextInt(countryById.size())); + } + + /** + * Cria e torna um Country, a partir do nome, moeda (currency) e taxa de + * cambio (exchange), com o Id crescente em relacao ao conjunto de Country's + * ja existentes. + * + * + * @param name Nome do país + * @param currency Moeda corrente do país + * @param exchange Taxa de câmbio + * @return country país + */ + private static Country createCountry(String name, String currency, double exchange) { + int id = countryById.size(); + Country country = new Country(id, name, currency, exchange); + countryById.add(country); + countryByName.put(name, country); + return country; + } + + /** + * Busca por um objeto Address (endereco) a partir de todos os argumentos + * fornecidos, porem utilzia id = 0 par ao objeto, se nao o encontrar, o + * mesmo eh criado e entao retornado. + + * + * @param street1 Rua/Avenida do endereço + * @param street2 Rua/Avenida do endereço (complemento) + * @param city Cidade do endereço + * @param state Estado + * @param zip Código postal + * @param countryName Nome do País + * @return address Endereço + */ + public static Address alwaysGetAddress(String street1, String street2, + String city, String state, String zip, String countryName) { + Country country = alwaysGetCountry(countryName); + Address key = new Address(0, street1, street2, city, state, zip, country); + Address address = addressByAll.get(key); + if (address == null) { + address = createAddress(street1, street2, city, state, zip, + country); + } + return address; + } + + /** + * Busca aleatoriamente por um objeto Address (endereco) a partir de um + * objeto do tipo Random como gerador de aleatorios. + * + * @param random Dado randômico / aleatório + * @return addressById Endereço do Id escolhido + */ + private static Address getAnAddressAnyAddress(Random random) { + return addressById.get(random.nextInt(addressById.size())); + } + + /** + * Este método cria um endereço novo através dos parâmetros: Rua/Avenida, + * cidade, estado, código postal e país. + * + * @param street1 Rua/Avenida do endereço + * @param street2 Rua/Avenida do endereço (complemento) + * @param city Cidade do endereço + * @param state Estado + * @param zip Código postal + * @param country País + * @return address Endereço + */ + private static Address createAddress(String street1, String street2, + String city, String state, String zip, Country country) { + int id = addressById.size(); + Address address = new Address(id, street1, street2, city, state, zip, + country); + addressById.add(address); + addressByAll.put(address, address); + return address; + } + + /** + * Este método lê e retorna um consumidor. + * + * @param cId ID do Consumidor + * @return customerById ID do Consumidor + */ + public static Customer getCustomer(int cId) { + return customersById.get(cId); + } + + /** + * + * @param username Nome do Usuário + * @return customersByUsername Consumidor do Nome de Usuário + */ + public static Optional getCustomer(String username) { + return Optional.ofNullable(customersByUsername.get(username)); + } + + /** + * Este método retorna um consumidor de maneira randômica. + * + * @param random Dado randômico / aleatório + * @return customersById Consumidor do Id escolhido + */ + private Customer getACustomerAnyCustomer(Random random) { + return customersById.get(random.nextInt(customersById.size())); + } + + /** + *
+     * Address address = alwaysGetAddress(street1, street2, city, state, zip,
+     * countryName);
+     * return createCustomer(fname, lname, address, phone, email,
+     * new Date(now), new Date(now), new Date(now),
+     * new Date(now + 7200000 ), discount, birthdate,
+     * data);
+     * 
+ * + * Este método irá retornar o método de criação do controle do consumidor em + * relação a data de cadastro, último acesso, login e tempo de expiração da + * sessão. + * + * @param fname Primeiro nome do consumidor + * @param lname Sobrenome / Último nome do consumidor + * @param street1 Rua/Avenida do endereço + * @param street2 Rua/Avenida do endereço (complemento) + * @param city Cidade do endereço + * @param state Estado + * @param zip Código postal + * @param countryName Nome do País + * @param phone Telefone + * @param email E-mail + * @param discount Desconto + * @param birthdate Data de Nascimento + * @param data Dado referente ao Consumidor + * @param now Hora Atual + * @return O método createCustomer com os parâmetros: fname, lname, address, + * phone, email, since, lastVisit, login, expiration, discount, birthdate, + * data) + */ + public static Customer createCustomer(String fname, String lname, String street1, + String street2, String city, String state, String zip, + String countryName, String phone, String email, double discount, + Date birthdate, String data, long now) { + Address address = alwaysGetAddress(street1, street2, city, state, zip, + countryName); + return createCustomer(fname, lname, address, phone, email, + new Date(now), new Date(now), new Date(now), + new Date(now + 7200000 /* 2 hours */), discount, birthdate, + data); + } + + /** + * Create a customer and inser it on customer Id list and customer username + * map. + *
+     *  int id = customersById.size();
+     * String uname = TPCW_Util.DigSyl(id, 0);
+     * Customer customer = new Customer(id, uname, uname.toLowerCase(), fname,
+     * lname, phone, email, since, lastVisit, login, expiration,
+     * discount, 0, 0, birthdate, data, address);
+     * customersById.add(customer);
+     * customersByUsername.put(uname, customer);
+     * return customer;
+     * 
+ * + * @param fname Primeiro nome do Consumidor + * @param lname Sobrenome / Último nome do consumidor + * @param address Endereço do consumidor + * @param phone Telefone + * @param email Email + * @param since Data de Cadastro + * @param lastVisit Data do último acesso + * @param login Data de acesso ao login da sessão + * @param expiration Data de expiração da sessão + * @param discount Desconto + * @param birthdate Data de Nascimento + * @param data Dado referente ao Consumidor + * @return customer Consumidor + */ + private static Customer createCustomer(String fname, String lname, Address address, + String phone, String email, Date since, Date lastVisit, + Date login, Date expiration, double discount, Date birthdate, + String data) { + int id = customersById.size(); + String uname = TPCW_Util.DigSyl(id, 0); + Customer customer = new Customer(id, uname, uname.toLowerCase(), fname, + lname, phone, email, since, lastVisit, login, expiration, + discount, 0, 0, birthdate, data, address); + customersById.add(customer); + customersByUsername.put(uname, customer); + return customer; + } + + /** + * Updates the customer login expiring date aka refresh session. + *
+     * Customer customer = getCustomer(cId);
+     * if (customer != null) {
+     * customer.setLogin(new Date(now));
+     * customer.setExpiration(new Date(now + 7200000 ));
+     * }
+     * 
+ * + * @param cId Id do Consumidor + * @param now Tempo / hora atual + */ + public static void refreshCustomerSession(int cId, long now) { + Customer customer = getCustomer(cId); + if (customer != null) { + customer.setLogin(new Date(now)); + customer.setExpiration(new Date(now + 7200000 /* 2 hours */)); + } + } + + /** + * Este método retorna um autor de maneira randômica. + * + * @param random Dado randômico / aleatório + * @return authorsById Autor do Id escolhido + */ + private static Author getAnAuthorAnyAuthor(Random random) { + return authorsById.get(random.nextInt(authorsById.size())); + } + + /** + * Este método cria um autor através dos parâmetros: nome completo (primeiro + * nome, nome do meio, e último nome / sobrenome), data de nascimento, e + * biografia do autor. + * + * @param fname Primeiro nome do Autor + * @param mname Nome do meio do Autor + * @param lname Sobrenome / Último nome do Autor + * @param birthdate Data de Nascimento + * @param bio Biografia do Autor + * @return author Autor + */ + private static Author createAuthor(String fname, String mname, String lname, + Date birthdate, String bio) { + Author author = new Author(fname, mname, lname, birthdate, bio); + authorsById.add(author); + return author; + } + + /** + * Este método é utilizado para recuperar um livro com base em seu índice de + * inserção + * + * @param bId id que representa o índice do book no sistema + * @return retorna optional do livro correspondente ao índice + */ + public static Optional getBook(int bId) { + return Optional.ofNullable(booksById.get(bId)); + } + + /** + * Returns a list of recommeded books based on Users + * + * @param c_id Customer id + * @return Não implementado, Null + */ + public static List getRecommendationByItens(int c_id) { + return null; + } + + /** + * + * @param c_id + * @return + */ + public static List getRecommendationByUsers(int c_id) { + return null; + } + + /** + * Randomly rturns a book based on a Random object as the random engine + * + * @param random - um valor random + * @return uma instância de Book + */ + public static Book getABookAnyBook(Random random) { + return booksById.get(random.nextInt(booksById.size())); + } + + /** + *
+     * ArrayList<Book> books = new ArrayList<>();
+     * for (Book book : booksById) {
+     * if (subject.equals(book.getSubject())) {
+     * books.add(book);
+     * if (books.size() > 50) {
+     * break;
+     * }
+     * }
+     * }
+     * Collections.sort(books, (Book a, Book b) -> a.getTitle().compareTo(b.getTitle()));
+     * return books;
+     * 
+ * + * @param subject - o assunto do livro + * @return uma lista de livros + */ + public static List getBooksBySubject(String subject) { + ArrayList books = new ArrayList<>(); + for (Book book : booksById) { + if (subject.equals(book.getSubject())) { + books.add(book); + if (books.size() > 50) { + break; + } + } + } + Collections.sort(books, (Book a, Book b) -> a.getTitle().compareTo(b.getTitle())); + return books; + } + + /** + * Returns a sorted list of Books which contains the title argument as its + * own title or a subpart of the title with a maximum size of 51 Books. + * + * @param title - o título do livro + * @return uma lista de livros + */ + public static List getBooksByTitle(String title) { + Pattern regex = Pattern.compile("^" + title); + ArrayList books = new ArrayList<>(); + for (Book book : booksById) { + if (regex.matcher(book.getTitle()).matches()) { + books.add(book); + if (books.size() > 50) { + break; + } + } + } + Collections.sort(books, (Book a, Book b) -> a.getTitle().compareTo(b.getTitle())); + return books; + } + + /** + * Returns a list of books that were written by an specific author. + * + * @param author - o autor do livro + * @return uma lista de livros + */ + public static List getBooksByAuthor(String author) { + Pattern regex = Pattern.compile("^" + author); + ArrayList books = new ArrayList<>(); + for (Book book : booksById) { + if (regex.matcher(book.getAuthor().getLname()).matches()) { + books.add(book); + if (books.size() > 50) { + break; + } + } + } + Collections.sort(books, (Book a, Book b) -> a.getTitle().compareTo(b.getTitle())); + return books; + } + + /** + * Retorna os 50 livros mais recentes (PubDate) por assunto + * + * @param subject - o assunto do livro + * @return uma lista de livros + */ + public static List getNewBooks(String subject) { + ArrayList books = new ArrayList<>(); + for (Book book : booksById) { + if (subject.equals(book.getSubject())) { + books.add(book); + } + } + Collections.sort(books, new Comparator() { + public int compare(Book a, Book b) { + int result = b.getPubDate().compareTo(a.getPubDate()); + if (result == 0) { + result = a.getTitle().compareTo(b.getTitle()); + } + return result; + } + }); + return books.subList(0, books.size() >= 50 ? 50 : books.size()); + } + + + + /** + * Counter Object to help on counting books processes. + * + */ + protected static class Counter { + + /** + * + */ + public Book book; + + /** + * + */ + public int count; + } + + /** + * Para realizar a busca por bestSellers o sistema aproveita do + * relacionamento de {@linkplain OrderLine} com {@linkplain Book}. É + * assumido que cada OrderLine possui apenas 01 {@linkplain Book}, neste + * caso a quantidade de vendas é identificada por esta relação. Sempre que + * acontece a criação de uma orderLine, é assumido que uma compra foi feita. + * + * É utilizado um limite de 100 livros para o resultado da pesquisa para + * evitar desperdício de memória no retorno do método. Este limite é + * estipulado por + * + * Com isto, é importante salientar que este método utiliza as vendas desta + * instância para recuperar os livros vendidos. + * + * @param subject Assunto que será utilizado para filtro de pesquisa por + * melhores vendedores + * @return Retorna uma lista dos livros mais vendidos desta + * {@linkplain Bookstore} com tamanho limitado em 100 + */ + public List getBestSellers(String subject) { + return null; + } + + /** + * Returns a list of Orders. + * + * @return a list of Orders + */ + public List getOrdersById() { + return ordersById; + } + + /** + * + * @param subject + * @return + */ + + + private static Book createBook(String title, Date pubDate, String publisher, + String subject, String desc, String thumbnail, + String image, double srp, Date avail, String isbn, + int page, String backing, String dimensions, Author author) { + int id = booksById.size(); + Book book = new Book(id, title, pubDate, publisher, subject, desc, + thumbnail, image, srp, avail, isbn, page, backing, + dimensions, author); + booksById.add(book); + return book; + } + + /** + * Updates Book image path and Thumbnail path of a Book + * + * @param bId - Book Id + * @param image - Image path + * @param thumbnail - thumbnail + * @param now - Publication Date. + */ + public static void updateBook(int bId, String image, + String thumbnail, long now) { + Book book = getBook(bId).get(); + book.setImage(image); + book.setThumbnail(thumbnail); + book.setPubDate(new Date(now)); + //updateRelatedBooks(book); + } + + /** + * Upadtes the stock of a Book based on Book Id and updates its cost. + * + * @param bId - Book Id + * @param cost - o custo + */ + public void updateStock(int bId, double cost) { + Book book = getBook(bId).get(); + if (!stockByBook.containsKey(book)) { + int stock = TPCW_Util.getRandomInt(rand, 10, 30); + stockByBook.put(book, new Stock(this.id, book, cost, stock)); + } + stockByBook.get(book).setCost(cost); + } + + /** + * Returns the stock of a Book based on Book Id. + * + * @param bId - Book Id + * @return uma instância de Stock + */ + public Stock getStock(int bId) { + final Book book = getBook(bId).get(); + final Stock stock = stockByBook.get(book); + return stock; + } + + /** + * For all the clients that bought this book in the last 10000 orders, what + * are the five most sold books except this one. + * + * @param targetBook - O livro que terá os relacionados atualizados + * + */ + private void updateRelatedBooks(Book targetBook) { + HashSet clientIds = new HashSet<>(); + int j = 0; + Iterator i = ordersByCreation.iterator(); + while (i.hasNext() && j <= 10000) { + Order order = i.next(); + for (OrderLine line : order.getLines()) { + Book book = line.getBook(); + if (targetBook.getId() == book.getId()) { + clientIds.add(order.getCustomer().getId()); + break; + } + } + j++; + } + HashMap counters = new HashMap<>(); + i = ordersByCreation.iterator(); + while (i.hasNext()) { + Order order = i.next(); + if (clientIds.contains(order.getCustomer().getId())) { + order.getLines().forEach((line) -> { + Book book = line.getBook(); + if (targetBook.getId() != book.getId()) { + Counter counter = counters.get(book.getId()); + if (counter == null) { + counter = new Counter(); + counter.book = book; + counter.count = 0; + counters.put(book.getId(), counter); + } + counter.count += line.getQty(); + } + }); + } + } + Counter[] sorted = counters.values().toArray(new Counter[]{}); + Arrays.sort(sorted, (Counter a, Counter b) -> { + if (b.count > a.count) { + return 1; + } + return b.count < a.count ? -1 : 0; + }); + Book[] related = new Book[]{targetBook, targetBook, targetBook, + targetBook, targetBook}; + for (j = 0; j < 5 && j < sorted.length; j++) { + related[j] = sorted[j].book; + } + targetBook.setRelated1(related[0]); + targetBook.setRelated2(related[1]); + targetBook.setRelated3(related[2]); + targetBook.setRelated4(related[3]); + targetBook.setRelated5(related[4]); + } + + /** + * Returns the Shopping cart. + * + * @param id - Cart Id. + * @return uma instância de Cart + */ + public Cart getCart(int id) { + return cartsById.get(id); + } + + /** + * Creates a Shopping cart + * + * @param now - Date from now. + * @return uma instância de Cart + */ + public Cart createCart(long now) { + int idCart = cartsById.size(); + Cart cart = new Cart(idCart, new Date(now)); + cartsById.add(cart); + return cart; + } + + /** + * Update shopping cart for one book or many books. + * + * @param cId - cart Id + * @param bId - book Id + * @param bIds - books Id + * @param quantities - quantities if many books. + * @param now - Date from now. + * @return uma instância de Cart + */ + public Cart cartUpdate(int cId, Integer bId, List bIds, + List quantities, long now) { + Cart cart = getCart(cId); + + if (bId != null) { + cart.increaseLine(stockByBook.get(getBook(bId).get()), getBook(bId).get(), 1); + } + + for (int i = 0; i < bIds.size(); i++) { + cart.changeLine(stockByBook.get(getBook(bId).get()), booksById.get(bIds.get(i)), quantities.get(i)); + } + + cart.setTime(new Date(now)); + + return cart; + } + + /** + * Este método irá finalizar a ordem do pedido de compra através dos + * parâmetros: consumidor, dados do carrinho de compras, do cartão de + * crédito e do envio do produto. + * + * O método irá finalizar o pedido, enviar a transferência do cartão de + * crédito e criar uma ordem para que o produto seja enviado. + * + * @param customerId ID do Consumidor + * @param cartId ID do Carrinho de Compras + * @param comment Comentário + * @param ccType Tipo de Cartão de Crédito + * @param ccNumber Número do Cartão de Crédito + * @param ccName Name do titular do Cartão de Crédito + * @param ccExpiry Data de Expiração do Cartão de Crédito + * @param shipping Remessa do Pedido + * @param shippingDate Data de Envio + * @param addressId Endereço do Consumidor + * @param now Tempo / hora atual + * @return O método createOrder com os parâmetros: Consumidor, Data atual, + * carrinho de compras, comentários, dados para envio da ordem, e a + * transação do cartão. + */ + public Order confirmBuy(int customerId, int cartId, String comment, + String ccType, long ccNumber, String ccName, Date ccExpiry, + String shipping, Date shippingDate, int addressId, long now) { + Customer customer = getCustomer(customerId); + Cart cart = getCart(cartId); + Address shippingAddress = customer.getAddress(); + if (addressId != -1) { + shippingAddress = addressById.get(addressId); + } + cart.getLines().stream().map((cartLine) -> { + Book book = cartLine.getBook(); + stockByBook.get(book).addQty(-cartLine.getQty()); + return book; + }).filter((book) -> (stockByBook.get(book).getQty() < 10)).forEachOrdered((book) -> { + stockByBook.get(book).addQty(21); + }); + CCTransaction ccTransact = new CCTransaction(ccType, ccNumber, ccName, + ccExpiry, "", cart.total(customer.getDiscount()), + new Date(now), shippingAddress.getCountry()); + return createOrder(customer, new Date(now), cart, comment, shipping, + shippingDate, "Pending", customer.getAddress(), + shippingAddress, ccTransact); + } + + private Order createOrder(Customer customer, Date date, Cart cart, + String comment, String shipType, Date shipDate, + String status, Address billingAddress, Address shippingAddress, + CCTransaction cc) { + int idOrder = ordersById.size(); + Order order = new Order(idOrder, customer, date, cart, comment, shipType, + shipDate, status, billingAddress, shippingAddress, cc); + ordersById.add(order); + ordersByCreation.addFirst(order); + customer.logOrder(order); + cart.clear(); + return order; + } + + + + private static Random rand; + + /** + * Randomly populates Addresses, Customers, Authors and Books lists. + * + * @param seed - um valor random + * @param now - data e hora atual + * @param items - a quantidde de itens + * @param customers - a quantidade de clientes + * @param addresses - a quantidade de enderços + * @param authors - a quantidade de autores + * @return true always + */ + public static boolean populate(long seed, long now, int items, int customers, + int addresses, int authors) { + if (populated) { + return false; + } + System.out.println("Beginning TPCW population."); + rand = new Random(seed); + populateCountries(); + populateAddresses(addresses, rand); + populateCustomers(customers, rand, now); + populateAuthorTable(authors, rand); + populateBooks(items, rand); + populateEvaluation(rand); + populated = true; + System.out.println("Finished TPCW population."); + return true; + } + + /** + * Este método irá popular inicialmente quais países, taxas de câmbio, e + * moedas correntes são possíveis de serem buscados e cadastrados junto ao + * consumidor. + */ + private static void populateCountries() { + String[] countries = {"United States", "United Kingdom", "Canada", + "Germany", "France", "Japan", "Netherlands", + "Italy", "Switzerland", "Australia", "Algeria", + "Argentina", "Armenia", "Austria", "Azerbaijan", + "Bahamas", "Bahrain", "Bangla Desh", "Barbados", + "Belarus", "Belgium", "Bermuda", "Bolivia", + "Botswana", "Brazil", "Bulgaria", "Cayman Islands", + "Chad", "Chile", "China", "Christmas Island", + "Colombia", "Croatia", "Cuba", "Cyprus", + "Czech Republic", "Denmark", "Dominican Republic", + "Eastern Caribbean", "Ecuador", "Egypt", + "El Salvador", "Estonia", "Ethiopia", + "Falkland Island", "Faroe Island", "Fiji", + "Finland", "Gabon", "Gibraltar", "Greece", "Guam", + "Hong Kong", "Hungary", "Iceland", "India", + "Indonesia", "Iran", "Iraq", "Ireland", "Israel", + "Jamaica", "Jordan", "Kazakhstan", "Kuwait", + "Lebanon", "Luxembourg", "Malaysia", "Mexico", + "Mauritius", "New Zealand", "Norway", "Pakistan", + "Philippines", "Poland", "Portugal", "Romania", + "Russia", "Saudi Arabia", "Singapore", "Slovakia", + "South Africa", "South Korea", "Spain", "Sudan", + "Sweden", "Taiwan", "Thailand", "Trinidad", + "Turkey", "Venezuela", "Zambia"}; + + double[] exchanges = {1, .625461, 1.46712, 1.86125, 6.24238, 121.907, + 2.09715, 1842.64, 1.51645, 1.54208, 65.3851, + 0.998, 540.92, 13.0949, 3977, 1, .3757, + 48.65, 2, 248000, 38.3892, 1, 5.74, 4.7304, + 1.71, 1846, .8282, 627.1999, 494.2, 8.278, + 1.5391, 1677, 7.3044, 23, .543, 36.0127, + 7.0707, 15.8, 2.7, 9600, 3.33771, 8.7, + 14.9912, 7.7, .6255, 7.124, 1.9724, 5.65822, + 627.1999, .6255, 309.214, 1, 7.75473, 237.23, + 74.147, 42.75, 8100, 3000, .3083, .749481, + 4.12, 37.4, 0.708, 150, .3062, 1502, 38.3892, + 3.8, 9.6287, 25.245, 1.87539, 7.83101, + 52, 37.8501, 3.9525, 190.788, 15180.2, + 24.43, 3.7501, 1.72929, 43.9642, 6.25845, + 1190.15, 158.34, 5.282, 8.54477, 32.77, 37.1414, + 6.1764, 401500, 596, 2447.7}; + + String[] currencies = {"Dollars", "Pounds", "Dollars", "Deutsche Marks", + "Francs", "Yen", "Guilders", "Lira", "Francs", + "Dollars", "Dinars", "Pesos", "Dram", + "Schillings", "Manat", "Dollars", "Dinar", "Taka", + "Dollars", "Rouble", "Francs", "Dollars", + "Boliviano", "Pula", "Real", "Lev", "Dollars", + "Franc", "Pesos", "Yuan Renmimbi", "Dollars", + "Pesos", "Kuna", "Pesos", "Pounds", "Koruna", + "Kroner", "Pesos", "Dollars", "Sucre", "Pounds", + "Colon", "Kroon", "Birr", "Pound", "Krone", + "Dollars", "Markka", "Franc", "Pound", "Drachmas", + "Dollars", "Dollars", "Forint", "Krona", "Rupees", + "Rupiah", "Rial", "Dinar", "Punt", "Shekels", + "Dollars", "Dinar", "Tenge", "Dinar", "Pounds", + "Francs", "Ringgit", "Pesos", "Rupees", "Dollars", + "Kroner", "Rupees", "Pesos", "Zloty", "Escudo", + "Leu", "Rubles", "Riyal", "Dollars", "Koruna", + "Rand", "Won", "Pesetas", "Dinar", "Krona", + "Dollars", "Baht", "Dollars", "Lira", "Bolivar", + "Kwacha"}; + + System.out.print("Creating " + countries.length + " countries..."); + + for (int i = 0; i < countries.length; i++) { + createCountry(countries[i], currencies[i], exchanges[i]); + } + + System.out.println(" Done"); + } + + private static void populateAddresses(int number, Random rand) { + System.out.print("Creating " + number + " addresses..."); + + for (int i = 0; i < number; i++) { + if (i % 10000 == 0) { + System.out.print("."); + } + Country country = getACountryAnyCountry(rand); + createAddress( + TPCW_Util.getRandomString(rand, 15, 40), + TPCW_Util.getRandomString(rand, 15, 40), + TPCW_Util.getRandomString(rand, 4, 30), + TPCW_Util.getRandomString(rand, 2, 20), + TPCW_Util.getRandomString(rand, 5, 10), + country); + } + + System.out.println(" Done"); + } + + private static void populateCustomers(int number, Random rand, long now) { + System.out.print("Creating " + number + " customers..."); + + for (int i = 0; i < number; i++) { + if (i % 10000 == 0) { + System.out.print("."); + } + Address address = getAnAddressAnyAddress(rand); + long since = now - TPCW_Util.getRandomInt(rand, 1, 730) * 86400000 /* a day */; + long lastLogin = since + TPCW_Util.getRandomInt(rand, 0, 60) * 86400000 /* a day */; + createCustomer( + TPCW_Util.getRandomString(rand, 8, 15), + TPCW_Util.getRandomString(rand, 8, 15), + address, + TPCW_Util.getRandomString(rand, 9, 16), + TPCW_Util.getRandomString(rand, 2, 9) + "@" + + TPCW_Util.getRandomString(rand, 2, 9) + ".com", + new Date(since), + new Date(lastLogin), + new Date(now), + new Date(now + 7200000 /* 2 hours */), + rand.nextInt(51), + TPCW_Util.getRandomBirthdate(rand), + TPCW_Util.getRandomString(rand, 100, 500)); + } + + System.out.println(" Done"); + } + + private static void populateAuthorTable(int number, Random rand) { + System.out.print("Creating " + number + " authors..."); + + for (int i = 0; i < number; i++) { + if (i % 10000 == 0) { + System.out.print("."); + } + createAuthor( + TPCW_Util.getRandomString(rand, 3, 20), + TPCW_Util.getRandomString(rand, 1, 20), + TPCW_Util.getRandomLname(rand), + TPCW_Util.getRandomBirthdate(rand), + TPCW_Util.getRandomString(rand, 125, 500)); + } + + System.out.println(" Done"); + } + + /** + * Este método irá popular quais assuntos são possíveis de serem buscados + * pelo consumidor. + */ + private static final String[] SUBJECTS = {"ARTS", "BIOGRAPHIES", "BUSINESS", "CHILDREN", + "COMPUTERS", "COOKING", "HEALTH", "HISTORY", + "HOME", "HUMOR", "LITERATURE", "MYSTERY", + "NON-FICTION", "PARENTING", "POLITICS", + "REFERENCE", "RELIGION", "ROMANCE", + "SELF-HELP", "SCIENCE-NATURE", "SCIENCE_FICTION", + "SPORTS", "YOUTH", "TRAVEL"}; + private static final String[] BACKINGS = {"HARDBACK", "PAPERBACK", "USED", "AUDIO", + "LIMITED-EDITION"}; + + private static void populateBooks(int number, Random rand) { + + System.out.print("Creating " + number + " books..."); + + for (int i = 0; i < number; i++) { + if (i % 10000 == 0) { + System.out.print("."); + } + Author author = getAnAuthorAnyAuthor(rand); + Date pubdate = TPCW_Util.getRandomPublishdate(rand); + double srp = TPCW_Util.getRandomInt(rand, 100, 99999) / 100.0; + String subject = SUBJECTS[rand.nextInt(SUBJECTS.length)]; + String title = subject + " " + TPCW_Util.getRandomString(rand, 14, 60); + createBook( + title, + pubdate, + TPCW_Util.getRandomString(rand, 14, 60), + SUBJECTS[rand.nextInt(SUBJECTS.length)], + TPCW_Util.getRandomString(rand, 100, 500), + "img" + i % 100 + "/thumb_" + i + ".gif", + "img" + i % 100 + "/image_" + i + ".gif", + srp, + new Date(pubdate.getTime() + + TPCW_Util.getRandomInt(rand, 1, 30) * 86400000 /* a day */), + TPCW_Util.getRandomString(rand, 13, 13), + TPCW_Util.getRandomInt(rand, 20, 9999), + BACKINGS[rand.nextInt(BACKINGS.length)], + (TPCW_Util.getRandomInt(rand, 1, 9999) / 100.0) + "x" + + (TPCW_Util.getRandomInt(rand, 1, 9999) / 100.0) + "x" + + (TPCW_Util.getRandomInt(rand, 1, 9999) / 100.0), + author); + } + + for (int i = 0; i < number; i++) { + Book book = booksById.get(i); + HashSet related = new HashSet<>(); + while (related.size() < 5) { + Book relatedBook = getABookAnyBook(rand); + if (relatedBook.getId() != i) { + related.add(relatedBook); + } + } + Book[] relatedArray = new Book[]{booksById.get(TPCW_Util.getRandomInt(rand, 0, number - 1)), + booksById.get(TPCW_Util.getRandomInt(rand, 0, number - 1)), + booksById.get(TPCW_Util.getRandomInt(rand, 0, number - 1)), + booksById.get(TPCW_Util.getRandomInt(rand, 0, number - 1)), + booksById.get(TPCW_Util.getRandomInt(rand, 0, number - 1))}; + relatedArray = related.toArray(relatedArray); + book.setRelated1(relatedArray[0]); + book.setRelated2(relatedArray[1]); + book.setRelated3(relatedArray[2]); + book.setRelated4(relatedArray[3]); + book.setRelated5(relatedArray[4]); + } + + System.out.println(" Done"); + } + + void populateInstanceBookstore(int number, Random rand, long now) { + populateOrders(number, rand, now); + populateStocks(number, rand, now); + + } + + private void populateStocks(int number, Random rand, long now) { + System.out.print("Creating " + number + " stocks..."); + for (int i = 0; i < number; i++) { + if (i % 10000 == 0) { + System.out.print("."); + } + int nBooks = TPCW_Util.getRandomInt(rand, 1, 5); + for (int j = 0; j < nBooks; j++) { + Book book = getABookAnyBook(rand); + if (!stockByBook.containsKey(book)) { + double cost = TPCW_Util.getRandomInt(rand, 50, 100) / 100.0; + int quantity = TPCW_Util.getRandomInt(rand, 300, 400); + stockByBook.put(book, new Stock(this.id, book, cost, quantity)); + } + } + } + System.out.println(" Done"); + } + + private void populateOrders(int number, Random rand, long now) { + String[] credit_cards = {"VISA", "MASTERCARD", "DISCOVER", + "AMEX", "DINERS"}; + String[] ship_types = {"AIR", "UPS", "FEDEX", "SHIP", "COURIER", + "MAIL"}; + String[] status_types = {"PROCESSING", "SHIPPED", "PENDING", + "DENIED"}; + + System.out.print("Creating " + number + " orders..."); + + for (int i = 0; i < number; i++) { + if (i % 10000 == 0) { + System.out.print("."); + } + int nBooks = TPCW_Util.getRandomInt(rand, 1, 5); + Cart cart = new Cart(-1, null); + String comment = TPCW_Util.getRandomString(rand, 20, 100); + for (int j = 0; j < nBooks; j++) { + Book book = getABookAnyBook(rand); + int quantity = TPCW_Util.getRandomInt(rand, 1, 300); + if (!stockByBook.containsKey(book)) { + double cost = TPCW_Util.getRandomInt(rand, 50, 100) / 100.0; + int stock = TPCW_Util.getRandomInt(rand, 300, 400); + stockByBook.put(book, new Stock(this.id, book, cost, stock)); + } + cart.changeLine(stockByBook.get(book), book, quantity); + } + + Customer customer = getACustomerAnyCustomer(rand); + CCTransaction ccTransact = new CCTransaction( + credit_cards[rand.nextInt(credit_cards.length)], + TPCW_Util.getRandomLong(rand, 1000000000000000L, 9999999999999999L), + TPCW_Util.getRandomString(rand, 14, 30), + new Date(now + TPCW_Util.getRandomInt(rand, 10, 730) * 86400000 /* a day */), + TPCW_Util.getRandomString(rand, 15, 15), + cart.total(customer.getDiscount()), + new Date(now), + getACountryAnyCountry(rand)); + long orderDate = now - TPCW_Util.getRandomInt(rand, 53, 60) * 86400000 /* a day */; + long shipDate = orderDate + TPCW_Util.getRandomInt(rand, 0, 7) * 86400000 /* a day */; + createOrder( + customer, + new Date(orderDate), + cart, comment, + ship_types[rand.nextInt(ship_types.length)], + new Date(shipDate), + status_types[rand.nextInt(status_types.length)], + getAnAddressAnyAddress(rand), + getAnAddressAnyAddress(rand), + ccTransact); + } + + System.out.println(" Done"); + } + + private static void populateEvaluation(Random rand) { + + System.out.print("Creating "); + // to do + + } + +} diff --git a/src/main/java/util/TPCW_Util.java b/src/main/java/util/TPCW_Util.java new file mode 100644 index 0000000..5780431 --- /dev/null +++ b/src/main/java/util/TPCW_Util.java @@ -0,0 +1,230 @@ +package util; + + +import java.util.*; + +/** + * *TPCW_Util + */ +public class TPCW_Util { + + private static final String[] arrayFnames = new String[]{ + "Alice", "Miguel", "Sophia", "Arthur", "Helena", "Bernardo", "Valentina", + "Heitor", "Laura", "Davi", "Isabella", "Lorenzo", "Manuela", "Théo", + "Júlia", "Pedro", "Heloísa", "Gabriel", "Luiza", "Enzo", "Maria", + "Luiza", "Matheus", "Lorena", "Lucas", "Lívia", "Benjamin", "Giovanna", + "Nicolas", "Marial", "Eduarda", "Guilherme", "Beatriz", "Rafael", "Mariali", + "Clara", "Joaquim", "Cecília", "Samuel", "Eloá", "Enzo", "Gabriel", "Lara", + "João", "Miguelito", "Maria", "Júlia", "Henrique", "Isadora", "Gustavo", + "Mariana", "Murilo", "Emanuelly", "Pedrosa", "Henrique", "Anana", "Júlia", + "Pietro", "Anani", "Luiza", "Lucca", "Anane", "Clara", "Felipe", "Melissa", + "João", "Pedrono", "Yasmin", "Isaac", "Mariari", "Alicy", "Benício", "Isabelly", + "Daniel", "Lavínia", "Anthony", "Esther", "Leonardo", "Sarah", "Davi", + "Lucca", "Sandro", "Elisa", "Bryan", "Antonella", "Eduardo", "Rafaela", + "João", "Lucas", "Marianna", "Cecília", "Victor", "Liz", "João", "Marina", + "Cauã", "Nicole", "Antônio", "Maitê", "Vicente", "Isis", "Caleb", "Alícia", + "Gael", "Luna", "Bento", "Rebeca", "Caio", "Agatha", "Emanuel", "Letícia", + "Vinícius", "Maria-Flor", "João", "Guilherme", "Gabriela", "Davi", "Lucas", + "Anna", "Laura", "Noah", "Catarina", "João", "Gabriel", "Clara", "João", + "Victor", "Ania", "Beatriz", "Luiz", "Miguela", "Vitória", "Francisco", + "Olívia", "Kaique", "Marianne", "Fernanda", "Otávio", "Emilly", "Augusto", + "Mariano", "Valentina", "Levi", "Milena", "Yuri", "Marianni", "Helena", "Enrico", + "Bianca", "Thiago", "Larissa", "Ian", "Mirella", "Victor", "Hugo", "Marianno", + "Flor", "Thomas", "Allana", "Henry", "Ania", "Sofia", "Luiz", "Felipe", "Clarice", + "Ryan", "Pietra", "Artur", "Miguelly", "Mariaty", "Vitória", "Davi", "Luiz", + "Maya", "Nathan", "Laís", "Pedrone", "Lucas", "Ayla", "Davi", "Miguelle", "Anne", + "Lívia", "Raul", "Eduarda", "Pedroso", "Miguelli", "Mariah", "Luiz", "Henrique", + "Stella", "Luan", "Anai", "Erick", "Gabrielly", "Martin", "Sophie", "Bruno", + "Carolina", "Rodrigo", "Mariallia", "Laura", "Luiz", "Gustavo", "Mariati", "Heloísa", + "Art", "Gabriel", "Mariami", "Soffia", "Breno", "Fernanda", "Kauê", "Malu", "Enzo", + "Miguelo", "Analu", "Fernando", "Amanda", "Arthuro", "Henrique", "Aurora", "Luiz", + "Otávio", "Mariassol", "Isis", "Carlos", "Eduardo", "Louise", "Tomás", "Heloise", + "Lucas", "Gabriel", "Ana", "Vitória", "André", "Ana", "Cecília", "José", "Anae", + "Liz", "Yago", "Joana", "Danilo", "Luana", "Anthony", "Gabriel", "Antônia", + "Ruan", "Isabel", "Miguelitto", "Henrique", "Bruna", "Oliver" + }; + private static final String[] arrayLnames = new String[]{ + "Ferreira", + "Braga", + "da Silva", + "Della Coletta", + "Zampirolli", + "Fernandes", + "Alves", + "Costalonga", + "Botteon", + "Caliman", + "de Oliveira", + "Zanette", + "Salvador", + "Silva", + "Zandonadi", + "Pesca", + "Falqueto", + "Tosi", + "da Costa", + "de Souza", + "Gomes", + "Calmon", + "Pereira", + "Sossai detto Pegorer", + "de Almeida", + "de Jesus", + "Martins", + "Balarini", + "Rodrigues", + "Gonçalves", + "Pizzol", + "Moreira", + "Vieira", + "Venturim", + "Bazoni", + "Filete", + "Almeida", + "Oliveira", + "dos Santos", + "Falchetto", + "Barbosa", + "Breda", + "Scaramussa", + "de Barros", + "Marques"}; + + /** + * + * @param rand + * @return + */ + public static String getRandomLname(Random rand) { + final int index = getRandomInt(rand, 0, arrayLnames.length -1); + return arrayLnames[index]; + } + + /** + * + * @param rand + * @param min + * @param max + * @return + */ + public static String getRandomString(Random rand, int min, int max) { + StringBuilder newstring = new StringBuilder(); + final char[] chars = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', + 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', + 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '!', '@', '#', + '$', '%', '^', '&', '*', '(', ')', '_', '-', '=', '+', + '{', '}', '[', ']', '|', ':', ';', ',', '.', '?', '/', + '~', ' '}; //79 characters + int strlen = getRandomInt(rand, min, max); + for (int i = 0; i < strlen; i++) { + newstring.append(chars[rand.nextInt(chars.length)]); + } + return newstring.toString(); + } + + /** + * + * @param rand + * @param lower + * @param upper + * @return + */ + public static int getRandomInt(Random rand, int lower, int upper) { + return rand.nextInt(upper - lower + 1) + lower; + } + + /** + * + * @param rand + * @param lower + * @param upper + * @return + */ + public static long getRandomLong(Random rand, long lower, long upper) { + return (long) (rand.nextDouble() * (upper - lower + 1) + lower); + } + + /** + * + * @param rand + * @return + */ + public static Date getRandomBirthdate(Random rand) { + return new GregorianCalendar( + TPCW_Util.getRandomInt(rand, 1880, 2000), + TPCW_Util.getRandomInt(rand, 0, 11), + TPCW_Util.getRandomInt(rand, 1, 30)).getTime(); + } + + /** + * + * @param rand + * @return + */ + public static Date getRandomPublishdate(Random rand) { + return new GregorianCalendar( + TPCW_Util.getRandomInt(rand, 1930, 2000), + TPCW_Util.getRandomInt(rand, 0, 11), + TPCW_Util.getRandomInt(rand, 1, 30)).getTime(); + } + + /** + * + * @param d + * @param n + * @return + */ + public static String DigSyl(int d, int n) { + StringBuilder resultString = new StringBuilder(); + String digits = Integer.toString(d); + + if (n > digits.length()) { + int padding = n - digits.length(); + for (int i = 0; i < padding; i++) { + resultString = resultString.append("BA"); + } + } + + for (int i = 0; i < digits.length(); i++) { + switch (digits.charAt(i)) { + case '0': + resultString = resultString.append("BA"); + break; + case '1': + resultString = resultString.append("OG"); + break; + case '2': + resultString = resultString.append("AL"); + break; + case '3': + resultString = resultString.append("RI"); + break; + case '4': + resultString = resultString.append("RE"); + break; + case '5': + resultString = resultString.append("SE"); + break; + case '6': + resultString = resultString.append("AT"); + break; + case '7': + resultString = resultString.append("UL"); + break; + case '8': + resultString = resultString.append("IN"); + break; + case '9': + resultString = resultString.append("NG"); + break; + default: + break; + } + } + + return resultString.toString(); + } + +} diff --git a/src/test/java/servico/BookstoreTest.java b/src/test/java/servico/BookstoreTest.java new file mode 100644 index 0000000..8ce09e9 --- /dev/null +++ b/src/test/java/servico/BookstoreTest.java @@ -0,0 +1,418 @@ +package servico; + +import dominio.Address; +import dominio.Author; +import dominio.Book; +import dominio.Cart; +import dominio.Customer; +import dominio.Order; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Random; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author INF329 + */ +public class BookstoreTest { + + public BookstoreTest() { + } + + static Bookstore instance; + + @BeforeClass + public static void setUpClass() { + + long seed = 0; + long now = System.currentTimeMillis(); + int items = 10000; + int customers = 1000; + int addresses = 1000; + int authors = 100; + int orders = 10000; + Random rand = new Random(seed); + Bookstore.populate(seed, now, items, customers, addresses, authors); + instance = new Bookstore(0); + instance.populateInstanceBookstore(orders, rand, now); + } + + @AfterClass + public static void tearDownClass() { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + /** + * Test of isPopulated method, of class Bookstore. + */ + @Test + public void testIsPopulated() { + System.out.println("isPopulated"); + boolean expResult = true; + boolean result = instance.isPopulated(); + assertEquals(expResult, result); + } + + /** + * Test of alwaysGetAddress method, of class Bookstore. + */ + @Test + public void testAlwaysGetAddress() { + System.out.println("alwaysGetAddress"); + String street1 = ""; + String street2 = ""; + String city = ""; + String state = ""; + String zip = ""; + String countryName = ""; + Address result = instance.alwaysGetAddress(street1, street2, city, state, zip, countryName); + Address expResult = new Address(0, street1, street2, city, state, zip, result.getCountry()); + assertEquals(expResult, result); + + } + + /** + * Test of getCustomer method, of class Bookstore. + */ + @Test + public void testGetCustomer_int() { + System.out.println("getCustomer"); + int cId = 0; + Customer result = instance.getCustomer(cId); + assertEquals(cId, result.getId()); + } + + /** + * Test of getCustomer method, of class Bookstore. + */ + @Test + public void testGetCustomer_String() { + System.out.println("getCustomer"); + String username = instance.getCustomer(10).getUname(); + Customer result = instance.getCustomer(username).get(); + assertEquals(username, result.getUname()); + + } + + /** + * Test of createCustomer method, of class Bookstore. + */ + @Test + public void testCreateCustomer() { + System.out.println("createCustomer"); + String fname = ""; + String lname = ""; + String street1 = ""; + String street2 = ""; + String city = ""; + String state = ""; + String zip = ""; + String countryName = ""; + String phone = ""; + String email = ""; + double discount = 0.0; + Date birthdate = null; + String data = ""; + long now = 0L; + + Customer result = instance.createCustomer(fname, lname, street1, street2, city, state, zip, countryName, phone, email, discount, birthdate, data, now); + int id = result.getId(); + String uname = result.getUname(); + Date since = result.getSince(); + Date lastVisit = result.getLastVisit(); + Date login = result.getLogin(); + Date expiration = result.getExpiration(); + Address address = result.getAddress(); + Customer expResult = new Customer(id, uname, uname.toLowerCase(), fname, + lname, phone, email, since, lastVisit, login, expiration, + discount, 0, 0, birthdate, data, address); + assertEquals(expResult, result); + + } + + /** + * Test of refreshCustomerSession method, of class Bookstore. + */ + @Test + public void testRefreshCustomerSession() { + System.out.println("refreshCustomerSession"); + int cId = 0; + long now = 0L; + instance.refreshCustomerSession(cId, now); + } + + /** + * Test of getBook method, of class Bookstore. + */ + @Test + public void testGetBook() { + System.out.println("getBook"); + int bId = 0; + Book result = instance.getBook(bId).get(); + assertEquals(bId, result.getId()); + + } + + /** + * Test of getBooksBySubject method, of class Bookstore. + */ + @Test + public void testGetBooksBySubject() { + System.out.println("getBooksBySubject"); + String subject = "ARTS"; + List result = instance.getBooksBySubject(subject); + assertEquals(result.size(), result.stream().filter(book -> book.getSubject().equals(subject)).count()); + + } + + /** + * Test of getBooksByTitle method, of class Bookstore. + */ + @Test + public void testGetBooksByTitle() { + System.out.println("getBooksByTitle"); + String title = instance.getBook(0).get().getTitle().substring(0, 4); + List result = instance.getBooksByTitle(title); + assertEquals(result.size(), result.stream().filter(book -> book.getTitle().startsWith(title)).count()); + } + + /** + * Test of getBooksByAuthor method, of class Bookstore. + */ + @Test + public void testGetBooksByAuthor() { + System.out.println("getBooksByAuthor"); + Author author = instance.getBook(0).get().getAuthor(); + List result = instance.getBooksByAuthor(author.getLname()); + assertEquals(result.size(), result.stream().filter(book -> book.getAuthor().getLname().equals(author.getLname())).count()); + + } + + /** + * Test of getNewBooks method, of class Bookstore. + */ + @Test + public void testGetNewBooks() { + System.out.println("getNewBooks"); + String subject = instance.getBook(0).get().getSubject(); + List result = instance.getNewBooks(subject); + assertEquals(result.size(), + result.stream().filter(book -> book.getSubject().equals(subject)).count()); + + } + + /** + * Test of updateBook method, of class Bookstore. + */ + @Test + public void testUpdateBook() { + System.out.println("updateBook"); + int bId = 0; + double cost = 0.0; + String image = ""; + String thumbnail = ""; + long now = 0L; + Book book = instance.getBook(bId).get(); + instance.updateBook(bId, image, thumbnail, now); + assertEquals(bId, book.getId()); + //assertEquals(cost, book.getCost(), 0.0); + assertEquals(image, book.getImage()); + assertEquals(thumbnail, book.getThumbnail()); + } + + /** + * Test of getCart method, of class Bookstore. + */ + // @Test + public void testGetCart() { + System.out.println("getCart"); + int id = 0; + + Cart expResult = null; + Cart result = instance.getCart(id); + assertEquals(expResult, result); + + } + + /** + * Test of createCart method, of class Bookstore. + */ + private void testCreateCart() { + System.out.println("createCart"); + long now = 0L; + + Cart expResult = null; + Cart result = instance.createCart(now); + assertEquals(expResult, result); + + } + + /** + * Test of cartUpdate method, of class Bookstore. + */ + // @Test + public void testCartUpdate() { + System.out.println("cartUpdate"); + testCreateCart(); + int cId = 0; + Integer bId = 1; + List bIds = Arrays.asList(10, 20); + List quantities = Arrays.asList(10, 20); + long now = 0L; + + Cart expResult = null; + Cart result = instance.cartUpdate(cId, bId, bIds, quantities, now); + assertEquals(expResult, result); + + } + + /** + * Test of confirmBuy method, of class Bookstore. + */ + // @Test + public void testConfirmBuy() { + System.out.println("confirmBuy"); + int customerId = 0; + int cartId = 0; + String comment = ""; + String ccType = ""; + long ccNumber = 0L; + String ccName = ""; + Date ccExpiry = null; + String shipping = ""; + Date shippingDate = null; + int addressId = 0; + long now = 0L; + Order expResult = null; + Order result = instance.confirmBuy(customerId, cartId, comment, ccType, ccNumber, ccName, ccExpiry, shipping, shippingDate, addressId, now); + assertEquals(expResult, result); + } + + + + + + + + + + + + + /** + * Test of getId method, of class Bookstore. + */ + //@Test + public void testGetId() { + System.out.println("getId"); + Bookstore instance = null; + int expResult = 0; + int result = instance.getId(); + assertEquals(expResult, result); + // TODO review the generated test code and remove the default call to fail. + fail("The test case is a prototype."); + } + + /** + * Test of getRecommendationByItens method, of class Bookstore. + */ + //@Test + public void testGetRecommendationByItens() { + System.out.println("getRecommendationByItens"); + int c_id = 0; + List expResult = null; + List result = Bookstore.getRecommendationByItens(c_id); + assertEquals(expResult, result); + // TODO review the generated test code and remove the default call to fail. + fail("The test case is a prototype."); + } + + /** + * Test of getRecommendationByUsers method, of class Bookstore. + */ + //@Test + public void testGetRecommendationByUsers() { + System.out.println("getRecommendationByUsers"); + int c_id = 0; + List expResult = null; + List result = Bookstore.getRecommendationByUsers(c_id); + assertEquals(expResult, result); + // TODO review the generated test code and remove the default call to fail. + fail("The test case is a prototype."); + } + + /** + * Test of getABookAnyBook method, of class Bookstore. + */ + //@Test + public void testGetABookAnyBook() { + System.out.println("getABookAnyBook"); + Random random = null; + Book expResult = null; + Book result = Bookstore.getABookAnyBook(random); + assertEquals(expResult, result); + // TODO review the generated test code and remove the default call to fail. + fail("The test case is a prototype."); + } + + /** + * Test of getOrdersById method, of class Bookstore. + */ + //@Test + public void testGetOrdersById() { + System.out.println("getOrdersById"); + Bookstore instance = null; + List expResult = null; + List result = instance.getOrdersById(); + assertEquals(expResult, result); + // TODO review the generated test code and remove the default call to fail. + fail("The test case is a prototype."); + } + + + + /** + * Test of updateStock method, of class Bookstore. + */ + //@Test + public void testUpdateStock() { + System.out.println("updateStock"); + int bId = 0; + double cost = 0.0; + Bookstore instance = null; + instance.updateStock(bId, cost); + // TODO review the generated test code and remove the default call to fail. + fail("The test case is a prototype."); + } + + + + /** + * Test of populateInstanceBookstore method, of class Bookstore. + */ + //@Test + public void testPopulateInstanceBookstore() { + System.out.println("populateInstanceBookstore"); + int number = 0; + Random rand = null; + long now = 0L; + Bookstore instance = null; + instance.populateInstanceBookstore(number, rand, now); + // TODO review the generated test code and remove the default call to fail. + fail("The test case is a prototype."); + } +} From 9257f0a3e821b09bb0a0be96e3bf172c3513e1f8 Mon Sep 17 00:00:00 2001 From: esoft45 - Vitor Gomes da Silva Date: Sat, 15 Feb 2025 15:06:47 -0300 Subject: [PATCH 2/2] Add Wiki HTML to the project --- wikiIndex.html | 118 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 wikiIndex.html diff --git a/wikiIndex.html b/wikiIndex.html new file mode 100644 index 0000000..e1992bf --- /dev/null +++ b/wikiIndex.html @@ -0,0 +1,118 @@ +

Wiki Grupo 07 INF329 2024
INF329g07

Coverage
+Java
+Apache Mahout
+JUnit
+JaCoCo
+Maven

+

Membros:

+ +

+

Google Meet (https://meet.google.com/vdt-aaiu-kdx)

+

KabanFlow (https://kanbanflow.com/board/4einBgC)

GitHub (https://github.com/gcesario203/Bookmarket-grupo07)

Jenkins (https://inf300.ic.unicamp.br/INF329/job/BookMarketCore07/)

+


ISSUES

+

Sempre criar o card no board antes de começar a desenvolver!

+

AD_4nXdJ_60IJYb9dx0VsU_ike9ba0XepKh-cpmm0RPIfMyXQeOmd2iR-gBna4qzJUTTHTCSJg31YIgzblCMLl6bgKwfxcabYaSBq47M2I3WVPSxPE7EgdONxl9iuBFjD07TicRKXZvdVA?key=2uhuRzrdcDxPOhK5rAFGAZhr

+

+

Exemplo de template

+

[Hash] Action - Summary

Description:
+

Descrição da Task:
Subtasks (se houver):

+

Definition of Done (DoD):

+

Test instructions (se houver):


+

Todo cartão precisa ter um responsável, se não for delegar para alguém quem criou é o responsável

+

Campo de Resolution Description: Após feito deve ter o link para o PR e/ou outros links externos 

+

Em caso de feature é recomendado adicionar um campo de Test Instructions no cartão para que o revisor consiga testar a feature criada

+

O hash pode ser obtido clicando em url e pegando a última parte do link

O cartão de exemplo foi criado para facilitar esse processo, podendo assim copiar ele e alterar os dados!

+

Padrões de Cores

+

DOC - Roxo 🟣

+

FEAT - Verde 🟢

+

REFACTOR - Amarelo 🟡

+

REMOVE - Laranja 🟠

+

SPIKE - Azul 🔵

+

BUG - Vermelho 🔴

+


+

WORFLOW

+


+

Desenvolvimento

+

+
    +
  • Arrastar o card da coluna Do Sprint para In progress
  • +
  • Dar pull na branch development
  • +
  • Criar um branch cujo o nome seja o hash do cartão + nome legível da task que está trabalhando
  • +
  • Fazer alterações e commitar ( o commit não deve conter muitas linhas e deverá conter uma mensagem descritiva do que foi realizado. Procure fazer vários commits. Não use git add . 
  • +
  • pense em quem vai revisar essa macarronada que vc vai subir)
  • +
  • Ao concluir abra um PR para branch development
  • +
  • Anexe o link do PR e outros links caso existam no campo Resolution Description do cartão
  • +
  • Mova o cartão para coluna waiting review
  • +
+

+

+

+

+

+

+

+

Revisão de atividades

+

+
    +
  • Mova o cartão para a coluna in Review
  • +
  • Revise carinhosamente todo o código modificado
  • +
  • Certifique-se de que o DoD está sendo cumprido
  • +
  • Certifique-se de que não quebrou o código, teste as funções principais do sistema com asas alterações, ainda que não tenha feito alterações nelas diretamente
  • +
  • Certifique-se de que o campo Resolution Description esteja preenchido
  • +
  • Aceite o PR para branch development
  • +
  • Acompanhe a execução dos testes na pipeline
  • +
  • Em caso positivo, mova o cartão para Done, caso negativo, volte o cartão para Do sprint
  • +
+

+

+

+

+

+

+

+

Clean Code e metodologia ágil sempre!

+

Registro sobre as Sprints

+

Um adendo sobre as Sprints do grupo 7 é que optamos por fazer em janelas de tempo menores, basicamente uma semana para cada.

+

+

[SPRINT 1]

+

+
    +
  • Fizemos as primeiras adaptações da wiki no Moodle. Também fizemos uma revisão dos requisitos do projeto assíncrona com base no PDF. Por fim, montamos o Kanban com um card template.
  • +
  • Criamos e estimamos nossos primeiros cards. Tomamos a decisão de como ficaria nossos repositórios locais e remotos, e também seus respectivos ambientes (dev, master, etc). Fizemos aprimoramentos na documentação da Wiki e primeiros cards relacionados ao código em si, que basicamente foram relacionados a refatoração, para melhor entendimento do time.
  • +
+

[SPRINT 2]

+

+
    +
  • Ambiente de CI/CD no GitHub ficou completo, fizemos uma reavaliação dos requisitos do sistema por conta de dúvidas que surgiram e fizemos alguns testes que faltavam sua implementação.
  • +
  • Melhoramento da Wiki adicionando informações das sprints e criações de métodos relacionados a BookStore e BookMarket, métodos de retorno de BestSellers, método de recomendação por itens e um teste de recomendação por usuário.
  • +
  • Planning para quebra de cards dos métodos mais importantes de recomendação: getRecommendationByUser e ByItem.
  • +
+

[SPRINT 3]

+

+
    +
  • Continuamos a fazer mais tasks de testes, relacionados ao BookStore e refatorações que serão importantes para fazer os métodos de recomendações.
  • +
  • Também viemos trazer atualizações sobre as Sprints aqui na Wiki para manter atualizado sobre o que anda acontecendo durante cada semana.
  • +
  • Implementação de GetBookPriceAverage e GetMinimumBookPrice para cálculo de preços de livros.
  • +
  • Refatoração do método updateRelatedBooks no serviço BookStore.
  • +
  • Adição de escopo de tipificação para Cliente.
  • +
  • Implementação da ligação entre Customer, Cart e BookStore.
  • +
+

[SPRINT 4]

+

+
    +
  • Fizemos a adição do GitInspector ao nosso projeto.
  • +
  • Adição das imagens dos bagdes de tecnologias usadas que estão no GitHub aqui na Wiki.
  • +
  • Implementação dos métodos getRecommendationByItens e getRecommendationByUsers
  • +

+

+

+

+

+

+

\ No newline at end of file