ПИА/К1 2021

Извор: SI Wiki
< ПИА
Датум измене: 19. новембар 2022. у 00:21; аутор: KockaAdmiralac (разговор | доприноси) (Mora ovo da ostane ipak)
(разл) ← Старија измена | Тренутна верзија (разл) | Новија измена → (разл)
Пређи на навигацију Пређи на претрагу

Први колоквијум 2021. године одржан је 26. новембра и трајао је два сата. Користила се технологија Јава Сервер Фацес са МyСQЛ базом података, доступним материјалима са предавања, додатним класама за рад са базом (DB.java) и сесијама (SessionUtils.java) као и скриптом за прављење базе. Биле су две групе.

Иако се колоквијум радио на ЈДК верзији 8, испод је дато решење коришћењем ЈДК верзије 11.

Група 1

Поставка

Поставка је доступна са странице предмета.

Направити следећу мини интернет апликацију за продавницу за кућне љубимце "Маза". Интернет апликацију реализовати користећи технологију Јава Сервер Фацес.

На почетној страни апликације, направити ХТМЛ форму, преко које могу да се пријављују корисници система, а то су купци и продавци. Корисници треба да имају могућност уношења корисничког имена и лозинке и да помоћу падајуће листе одаберу да ли се пријављују као купци или продавци. У случају исправно унетих података, кориснику треба омогућити рад са остатком система (за сваки тип корисника треба приказати посебну почетну веб страницу након пријављивања). Уколико корисник не унесе неки од података или унесе погрешне податке, потребно је исписати поруку грешке словима црвене боје, са могућношћу исправљања грешке у форми. По успешној пријави у систем, кориснику дати и опцију да се одјави. [7 поена]

Купац након успешног пријављивања, види табеларни приказ свих производа. Производе који су на промоцији обојити зеленом бојом. [5 поена] Поред сваког производа постоји поље за потврду – „штиклирање“ (цхецкбоx) и поље за унос жељене количине производа. Испод табеле са производима стоји дугме Наручи. Притиском на дугме Наручи купац прелази на другу страницу на којој је приказан садржај наруџбине, са свим штиклираним производима и њиховим количинама. Сматрати да свих производа има довољно на стању за сваку наруџбину. [5 поена] Поред сваког нарученог производа стоји дугме Уклони. Притиском на дугме Уклони тај производ се брише из наруџбине. [3 поена] Испод списка наручених производа стоји дугме Потврди, чиме се наруџбина уписује у базу података. Датум наруџбине је тренутни датум. [5 поена]

Продавац након успешног пријављивања, види своје личне податке (име, презиме, датум рођења), као и табеларни приказ свих наруџбина. У табели приказати корисничко име купца, датум наруџбине и називе наручених производа у оквиру те наруџбине. [7 поена] Испод табеле наруџбина, у сваком тренутку исписивати највернијег купца, тј. купца који има највише наруџбина. [3 поена]

Решење

Име пакета које се користи у решењу је rs.ac.bg.etf.pia.petshop2021.

Странице

index.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
    <h:head>
        <title>Dobrodošli</title>
        <h:outputStylesheet name="css/main.css"></h:outputStylesheet>
    </h:head>
    <h:body>
        <h:form>
            <p>
                <label for="username">Korisničko ime:</label>
                <h:inputText id="username" value="#{loginManagedBean.username}"></h:inputText>
            </p>
            <p>
                <label for="password">Lozinka:</label>
                <h:inputText id="password" value="#{loginManagedBean.password}"></h:inputText>
            </p>
            <p>
                <label for="tip">Tip:</label>
                <h:selectOneMenu value="#{loginManagedBean.tip}">
                    <f:selectItem itemLabel="Kupac" itemValue="kupac"></f:selectItem>
                    <f:selectItem itemLabel="Prodavac" itemValue="prodavac"></f:selectItem>
                </h:selectOneMenu>
            </p>
            <p><h:commandButton value="Prijavi se" action="#{loginManagedBean.login()}"></h:commandButton></p>
            <p><h:outputText class="error" value="#{loginManagedBean.error}"></h:outputText></p>
        </h:form>
    </h:body>
</html>
kupac.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
    <h:head>
        <title>Kupac</title>
        <h:outputStylesheet name="css/main.css"></h:outputStylesheet>
    </h:head>
    <h:body>
        <h:form>
            <h:commandLink value="Izloguj se" action="#{loginManagedBean.logout()}"></h:commandLink>
            <h:dataTable value="#{kupacManagedBean.allProducts}" var="product">
                <h:column class="#{product.promocija ? 'promocija' : ''}">
                    <f:facet name="header">Naziv</f:facet>
                    <h:outputText value="#{product.naziv}"></h:outputText>
                </h:column>
                <h:column class="#{product.promocija ? 'promocija' : ''}">
                    <f:facet name="header">Opis</f:facet>
                    <h:outputText value="#{product.opis}"></h:outputText>
                </h:column>
                <h:column class="#{product.promocija ? 'promocija' : ''}">
                    <f:facet name="header">Cena</f:facet>
                    <h:outputText value="#{product.cena}"></h:outputText>
                </h:column>
                <h:column class="#{product.promocija ? 'promocija' : ''}">
                    <f:facet name="header">Kupiti?</f:facet>
                    <h:selectBooleanCheckbox value="#{product.kupiti}"></h:selectBooleanCheckbox>
                </h:column>
                <h:column class="#{product.promocija ? 'promocija' : ''}">
                    <f:facet name="header">Koliko?</f:facet>
                    <h:inputText value="#{product.koliko}"></h:inputText>
                </h:column>
            </h:dataTable>
            <h:commandButton value="Naruči" action="narudzbina"></h:commandButton>
        </h:form>
    </h:body>
</html>
narudzbina.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
    <h:head>
        <title>Narudžbina</title>
    </h:head>
    <h:body>
        <h:form>
            <h:dataTable value="#{kupacManagedBean.allProducts}" var="product">
                <h:column>
                    <f:facet name="header">Naziv</f:facet>
                    <h:outputText value="#{product.naziv}" rendered="#{product.kupiti and product.koliko gt 0}"></h:outputText>
                </h:column>
                <h:column>
                    <f:facet name="header">Količina</f:facet>
                    <h:outputText value="#{product.koliko}" rendered="#{product.kupiti and product.koliko gt 0}"></h:outputText>
                </h:column>
                <h:column>
                    <f:facet name="header">Ukloniti?</f:facet>
                    <h:commandButton value="Ukloni" action="#{kupacManagedBean.remove(product)}" rendered="#{product.kupiti and product.koliko gt 0}"></h:commandButton>
                </h:column>
            </h:dataTable>
            <h:commandButton value="Potvrdi" action="#{kupacManagedBean.order()}"></h:commandButton>
        </h:form>
    </h:body>
</html>
prodavac.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
    <h:head>
        <title>Prodavac</title>
        <h:outputStylesheet name="css/main.css"></h:outputStylesheet>
    </h:head>
    <h:body>
        <h:form>
            <h:commandLink value="Izloguj se" action="#{loginManagedBean.logout()}"></h:commandLink>
        </h:form>
        <p>
            Dobrodošli
            <h:outputText value="#{prodavacManagedBean.name}"></h:outputText>&nbsp;<h:outputText value="#{prodavacManagedBean.surname}"></h:outputText>
            koji ste rođeni
            <h:outputText value="#{prodavacManagedBean.birthdate}"></h:outputText>.
        </p>
        <h:dataTable value="#{prodavacManagedBean.orders}" var="order">
            <h:column>
                <f:facet name="header">Kupac</f:facet>
                <h:outputText value="#{order.kupac}"></h:outputText>
            </h:column>
            <h:column>
                <f:facet name="header">Datum</f:facet>
                <h:outputText value="#{order.datumNarudzbine}"></h:outputText>
            </h:column>
            <h:column>
                <f:facet name="header">Proizvodi</f:facet>
                <h:outputText value="#{order.proizvodi}"></h:outputText>
            </h:column>
        </h:dataTable>
        <p>Najverniji kupac: <h:outputText value="#{prodavacManagedBean.najvernijiKupac}"></h:outputText></p>
    </h:body>
</html>

Зрна

LoginManagedBean
package rs.ac.bg.etf.pia.petshop2021.beans;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import jakarta.inject.Named;
import jakarta.enterprise.context.RequestScoped;
import jakarta.servlet.http.HttpSession;
import rs.ac.bg.etf.pia.petshop2021.util.DB;
import rs.ac.bg.etf.pia.petshop2021.util.SessionUtils;

@Named(value = "loginManagedBean")
@RequestScoped
public class LoginManagedBean {
    private String username;
    private String password;
    private String tip;
    private String error;

    public LoginManagedBean() {}

    public String login() {
        if (username.isEmpty() || password.isEmpty() || tip.isEmpty()) {
            error = "Niste uneli sve podatke.";
            return null;
        }
        Connection conn = DB.getInstance().getConnection();
        try (PreparedStatement stmt = conn.prepareStatement("SELECT * FROM korisnici WHERE kor_ime = ? AND lozinka = ? AND tip = ?")) {
            stmt.setString(1, username);
            stmt.setString(2, password);
            stmt.setString(3, tip);
            try (ResultSet rs = stmt.executeQuery()) {
                if (rs.next()) {
                    HttpSession session = SessionUtils.getSession();
                    session.setAttribute("kor_ime", username);
                    session.setAttribute("ime", rs.getString("ime"));
                    session.setAttribute("prezime", rs.getString("prezime"));
                    session.setAttribute("datum_rodjenja", rs.getDate("datum_rodjenja").toLocalDate());
                    return tip + ".xhtml?faces-redirect=true";
                } else {
                    error = "Nije ispravno korisničko ime, lozinka ili tip.";
                    return null;
                }
            }
        } catch (SQLException ex) {
            Logger.getLogger(LoginManagedBean.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            DB.getInstance().putConnection(conn);
        }
        error = "Nepoznata greška.";
        return null;
    }
    
    public String logout() {
        HttpSession session = SessionUtils.getSession();
        session.removeAttribute("kor_ime");
        session.removeAttribute("ime");
        session.removeAttribute("prezime");
        session.removeAttribute("datum_rodjenja");
        return "index.xhtml?faces-redirect=true";
    }
    
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getTip() {
        return tip;
    }

    public void setTip(String tip) {
        this.tip = tip;
    }

    public String getError() {
        return error;
    }

    public void setError(String error) {
        this.error = error;
    }
}
KupacManagedBean
package rs.ac.bg.etf.pia.petshop2021.beans;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.SessionScoped;
import jakarta.inject.Named;
import rs.ac.bg.etf.pia.petshop2021.entities.Product;
import rs.ac.bg.etf.pia.petshop2021.util.DB;
import rs.ac.bg.etf.pia.petshop2021.util.SessionUtils;

@Named(value = "kupacManagedBean")
@SessionScoped
public class KupacManagedBean implements Serializable {
    private List<Product> allProducts;

    public KupacManagedBean() {}

    @PostConstruct
    public void initData() {
        allProducts = new ArrayList<>();
        Connection conn = DB.getInstance().getConnection();
        try (
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT * FROM proizvodi");
        ) {
            while (rs.next()) {
                Product p = new Product();
                p.setNaziv(rs.getString("naziv"));
                p.setOpis(rs.getString("opis"));
                p.setCena(rs.getInt("cena"));
                p.setPromocija(rs.getBoolean("promocija"));
                allProducts.add(p);
            }
        } catch (SQLException ex) {
            Logger.getLogger(LoginManagedBean.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            DB.getInstance().putConnection(conn);
        }
    }

    public void remove(Product p) {
        p.setKoliko(0);
        p.setKupiti(false);
    }
    
    public String order() {
        Connection conn = DB.getInstance().getConnection();
        try (
            PreparedStatement stmt = conn.prepareStatement("INSERT INTO narudzbine (kupac, datum) VALUES (?, NOW())", Statement.RETURN_GENERATED_KEYS);
            PreparedStatement stmt2 = conn.prepareStatement("INSERT INTO narudzbinasadrzi (narudzbina, proizvod, kolicina) VALUES (?, ?, ?)");
        ) {
            stmt.setString(1, (String) SessionUtils.getSession().getAttribute("kor_ime"));
            stmt.executeUpdate();
            try (ResultSet rs = stmt.getGeneratedKeys()) {
                if (rs.next()) {
                    stmt2.setInt(1, rs.getInt(1));
                } else {
                    return null;
                }
            }
            for (Product p : allProducts) {
                if (p.getKoliko() <= 0 || !p.isKupiti()) {
                    continue;
                }
                stmt2.setString(2, p.getNaziv());
                stmt2.setInt(3, p.getKoliko());
                stmt2.executeUpdate();
                p.setKupiti(false);
                p.setKoliko(0);
            }
        } catch (SQLException ex) {
            Logger.getLogger(KupacManagedBean.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            DB.getInstance().putConnection(conn);
        }
        return "kupac?faces-redirect=true";
    }

    public List<Product> getAllProducts() {
        return allProducts;
    }

    public void setAllProducts(List<Product> allProducts) {
        this.allProducts = allProducts;
    }
}
ProdavacManagedBean
package rs.ac.bg.etf.pia.petshop2021.beans;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import jakarta.annotation.PostConstruct;
import jakarta.inject.Named;
import jakarta.enterprise.context.RequestScoped;
import jakarta.servlet.http.HttpSession;
import rs.ac.bg.etf.pia.petshop2021.entities.Order;
import rs.ac.bg.etf.pia.petshop2021.util.DB;
import rs.ac.bg.etf.pia.petshop2021.util.SessionUtils;

@Named(value = "prodavacManagedBean")
@RequestScoped
public class ProdavacManagedBean {
    private String name;
    private String surname;
    private LocalDate birthdate;
    private List<Order> orders;
    
    public ProdavacManagedBean() {}

    @PostConstruct
    public void initData() {
        HttpSession session = SessionUtils.getSession();
        name = (String) session.getAttribute("ime");
        surname = (String) session.getAttribute("prezime");
        birthdate = (LocalDate) session.getAttribute("datum_rodjenja");
        orders = new ArrayList<>();
        Connection conn = DB.getInstance().getConnection();
        try (
            Statement stmt = conn.createStatement();
            PreparedStatement stmt2 = conn.prepareStatement("SELECT * FROM narudzbinasadrzi WHERE narudzbina = ?");
            ResultSet rs = stmt.executeQuery("SELECT * FROM narudzbine");
        ) {
            while (rs.next()) {
                Order order = new Order();
                stmt2.setInt(1, rs.getInt(1));
                order.setKupac(rs.getString(2));
                order.setDatumNarudzbine(rs.getDate(3).toLocalDate());
                StringBuilder proizvodi = new StringBuilder();
                boolean first = true;
                try (ResultSet rs2 = stmt2.executeQuery()) {
                    while (rs2.next()) {
                        if (first) {
                            first = false;
                        } else {
                            proizvodi.append(", ");
                        }
                        proizvodi.append(rs2.getString(2));
                    }
                }
                order.setProizvodi(proizvodi.toString());
                orders.add(order);
            }
        } catch (SQLException ex) {
            Logger.getLogger(ProdavacManagedBean.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            DB.getInstance().putConnection(conn);
        }
    }
    
    public String getNajvernijiKupac() {
        Connection conn = DB.getInstance().getConnection();
        try (
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT kupac, COUNT(*) AS br_naruzbina FROM narudzbine GROUP BY kupac ORDER BY br_naruzbina DESC LIMIT 1");
        ) {
            if (rs.next()) {
                return rs.getString(1);
            }
        } catch (SQLException ex) {
            Logger.getLogger(ProdavacManagedBean.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            DB.getInstance().putConnection(conn);
        }
        return "Nema narudžbina?";
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public LocalDate getBirthdate() {
        return birthdate;
    }

    public void setBirthdate(LocalDate birthdate) {
        this.birthdate = birthdate;
    }

    public List<Order> getOrders() {
        return orders;
    }

    public void setOrders(List<Order> orders) {
        this.orders = orders;
    }
}

Ентитети

Order.java
package rs.ac.bg.etf.pia.petshop2021.entities;

import java.time.LocalDate;
import java.util.List;

public class Order {
    private String kupac;
    private LocalDate datumNarudzbine;
    private String proizvodi;

    public String getKupac() {
        return kupac;
    }

    public void setKupac(String kupac) {
        this.kupac = kupac;
    }

    public LocalDate getDatumNarudzbine() {
        return datumNarudzbine;
    }

    public void setDatumNarudzbine(LocalDate datumNarudzbine) {
        this.datumNarudzbine = datumNarudzbine;
    }

    public String getProizvodi() {
        return proizvodi;
    }

    public void setProizvodi(String proizvodi) {
        this.proizvodi = proizvodi;
    }
}
Product.java
package rs.ac.bg.etf.pia.petshop2021.entities;

public class Product {
    private String naziv;
    private String opis;
    private int cena;
    private boolean promocija;
    private boolean kupiti;
    private int koliko;

    public boolean isKupiti() {
        return kupiti;
    }

    public void setKupiti(boolean kupiti) {
        this.kupiti = kupiti;
    }

    public int getKoliko() {
        return koliko;
    }

    public void setKoliko(int koliko) {
        this.koliko = koliko;
    }

    public String getNaziv() {
        return naziv;
    }

    public void setNaziv(String naziv) {
        this.naziv = naziv;
    }

    public String getOpis() {
        return opis;
    }

    public void setOpis(String opis) {
        this.opis = opis;
    }

    public int getCena() {
        return cena;
    }

    public void setCena(int cena) {
        this.cena = cena;
    }

    public boolean isPromocija() {
        return promocija;
    }

    public void setPromocija(boolean promocija) {
        this.promocija = promocija;
    }
}

Остали фајлови

main.css
.error {
    color: red;
}

.promocija {
    background-color: green;
}

Група 2

Овај задатак није решен. Помозите СИ Wики тако што ћете га решити.

Поставка

Поставка је доступна са странице предмета.

Решење