ПИА/К1 2020

Извор: SI Wiki
Пређи на навигацију Пређи на претрагу

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

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

Група 1

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

Поставка

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

Решење

Група 2

Поставка

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

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

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

Посетилац након успешног пријављивања, види списак свих животиња које се налазе у врту. Омогућити сортирање животиња по тежини. [5 поена] Посетилац види и предлоге других корисника за долазак нових животиња у врт. Поред сваког предлога омогућити да га посетилац подржи кликом на дугме ЗА. Дугме се види само у случају да посетилац већ није гласао. Кликом на ово дугме, ажурирати број гласова за предлог у бази. [4 поена] Посетилац може и да унесе свој предлог, при чему уноси назив животиње, и коментар. [4 поена]

Радник након успешног пријављивања, види списак свих предлога за нове животиње. Предлози који имају преко 2 гласа треба да буду обојени зеленом бојом. [4 поена] Радник може да одобри неки предлог, при чему се пребацује на следећу страницу на којој се налази форма за додавање животиње, са већ унапред попуњеним пољем за назив животиње. При додавању животиње, уноси се и тежина животиње. Одобрене предлоге не треба брисати из базе, већ онемогућити поновно одобравање таквих предлога. [7 поена] Радник има могућност и да одбије неки неодобрен предлог, при чему се он тада брише из базе. [4 поена]

Решење

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

Странице

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">Username:</label>
                <h:inputText id="username" value="#{loginManagedBean.username}"></h:inputText>
            </p>
            <p>
                <label for="password">Password:</label>
                <h:inputSecret id="password" value="#{loginManagedBean.password}"></h:inputSecret>
            </p>
            <p>
                <h:selectOneRadio value="#{loginManagedBean.group}">
                    <f:selectItem itemValue="radnik" itemLabel="Radnik"></f:selectItem>
                    <f:selectItem itemValue="posetilac" itemLabel="Posetilac"></f:selectItem>
                </h:selectOneRadio>
            </p>
            <p><h:commandButton action="#{loginManagedBean.login()}" value="Login"></h:commandButton></p>
            <p><h:outputText value="#{loginManagedBean.error}" class="error"></h:outputText></p>
        </h:form>
    </h:body>
</html>
posetilac.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>Posetilac</title>
    </h:head>
    <h:body>
        <h:form>
            <h:commandButton action="#{loginManagedBean.logout()}" value="Odjavi se"></h:commandButton>
            <h2>Životinje</h2>
            <h:dataTable value="#{posetilacManagedBean.zivotinje}" var="z">
                <h:column>
                    <f:facet name="header">Životinja</f:facet>
                    #{z.naziv}
                </h:column>
                <h:column>
                    <f:facet name="header">Težina</f:facet>
                    #{z.tezina}
                </h:column>
            </h:dataTable>
            <h2>Predlozi</h2>
            <h:dataTable value="#{posetilacManagedBean.predlozi}" var="p">
                <h:column>
                    <f:facet name="header">Životinja</f:facet>
                    #{p.zivotinja}
                </h:column>
                <h:column>
                    <f:facet name="header">Posetilac</f:facet>
                    #{p.posetilac}
                </h:column>
                <h:column>
                    <f:facet name="header">Komentar</f:facet>
                    #{p.komentar}
                </h:column>
                <h:column>
                    <f:facet name="header">Glasovi</f:facet>
                    #{p.glasovi}
                </h:column>
                <h:column>
                    <f:facet name="header">Glasaj</f:facet>
                    <h:commandButton rendered="#{not p.glasao}" action="#{posetilacManagedBean.vote(p)}" value="ZA"></h:commandButton>
                </h:column>
            </h:dataTable>
            <h2>Novi predlog</h2>
            <p>
                <label for="zivotinja">Životinja:</label>
                <h:inputText value="#{posetilacManagedBean.zivotinja}" id="zivotinja"></h:inputText>
            </p>
            <p>
                <label for="komentar">Komentar:</label>
                <h:inputText value="#{posetilacManagedBean.komentar}" id="komentar"></h:inputText>
            </p>
            <p><h:commandButton action="#{posetilacManagedBean.suggest()}" value="Predloži"></h:commandButton></p>
        </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>Radnik</title>
        <h:outputStylesheet name="css/main.css"></h:outputStylesheet>
    </h:head>
    <body>
        <h:form>
            <h:commandButton action="#{loginManagedBean.logout()}" value="Odjavi se"></h:commandButton>
            <h2>Predlozi</h2>
            <h:dataTable value="#{posetilacManagedBean.predlozi}" var="p">
                <h:column class="#{(p.glasovi gt 2) ? 'green' : ''}">
                    <f:facet name="header">Životinja</f:facet>
                    #{p.zivotinja}
                </h:column>
                <h:column class="#{(p.glasovi gt 2) ? 'green' : ''}">
                    <f:facet name="header">Posetilac</f:facet>
                    #{p.posetilac}
                </h:column>
                <h:column class="#{(p.glasovi gt 2) ? 'green' : ''}">
                    <f:facet name="header">Komentar</f:facet>
                    #{p.komentar}
                </h:column>
                <h:column class="#{(p.glasovi gt 2) ? 'green' : ''}">
                    <f:facet name="header">Glasovi</f:facet>
                    #{p.glasovi}
                </h:column>
                <h:column class="#{(p.glasovi gt 2) ? 'green' : ''}">
                    <f:facet name="header">Odobri</f:facet>
                    <h:commandButton action="#{radnikManagedBean.approve(p)}" rendered="#{not p.odobren}" value="Odobri"></h:commandButton>
                </h:column>
                <h:column class="#{(p.glasovi gt 2) ? 'green' : ''}">
                    <f:facet name="header">Odbaci</f:facet>
                    <h:commandButton action="#{radnikManagedBean.reject(p)}" rendered="#{not p.odobren}" value="Odbaci"></h:commandButton>
                </h:column>
            </h:dataTable>
        </h:form>
    </body>
</html>
dodaj.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">
    <h:head>
        <title>Dodaj životinju</title>
    </h:head>
    <h:body>
        <h2>Dodaj</h2>
        <h:form>
            <p>
                <label for="naziv">Naziv:</label>
                <h:inputText value="#{radnikManagedBean.naziv}" id="naziv"></h:inputText>
            </p>
            <p>
                <label for="tezina">Težina:</label>
                <h:inputText value="#{radnikManagedBean.tezina}" id="tezina"></h:inputText></p>
            <p><h:commandButton action="#{radnikManagedBean.add()}" value="Dodaj"></h:commandButton></p>
        </h:form>
    </h:body>
</html>

Зрна

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

import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Named;
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 rs.ac.bg.etf.pia.zoo2020.util.DB;
import rs.ac.bg.etf.pia.zoo2020.util.SessionUtils;

@Named(value = "loginManagedBean")
@RequestScoped
public class LoginManagedBean {
    private String username;
    private String password;
    private String group;
    private String error;
    
    public String login() {
        if (username.isEmpty() || password.isEmpty() || group.isEmpty()) {
            error = "Niste uneli sve podatke.";
            return null;
        }
        DB inst = DB.getInstance();
        Connection db = inst.getConnection();
        try (PreparedStatement stmt = db.prepareStatement("SELECT ime, prezime FROM korisnici WHERE kor_ime = ? AND lozinka = ? AND tip = ?")) {
            stmt.setString(1, username);
            stmt.setString(2, password);
            stmt.setString(3, group);
            try (ResultSet rs = stmt.executeQuery()) {
                if (rs.next()) {
                    SessionUtils.getSession().setAttribute("kor_ime", username);
                    return group + ".xhtml?faces-redirect=true";
                } else {
                    error = "Pogrešno korisničko ime, lozinka ili grupa.";
                    return null;
                }
            }
        } catch (SQLException ex) {
            Logger.getLogger(LoginManagedBean.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            inst.putConnection(db);
        }
        return null;
    }
    
    public String logout() {
        SessionUtils.getSession().removeAttribute("kor_ime");
        return "index.xhtml?faces-redirect=true";
    }
    
    public String getError() {
        return error;
    }

    public void setError(String error) {
        this.error = error;
    }

    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 getGroup() {
        return group;
    }

    public void setGroup(String group) {
        this.group = group;
    }

}
PosetilacManagedBean
package rs.ac.bg.etf.pia.zoo2020.beans;

import rs.ac.bg.etf.pia.zoo2020.entities.Predlog;
import rs.ac.bg.etf.pia.zoo2020.entities.Zivotinja;
import jakarta.annotation.PostConstruct;
import jakarta.inject.Named;
import jakarta.enterprise.context.RequestScoped;
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 rs.ac.bg.etf.pia.zoo2020.util.DB;
import rs.ac.bg.etf.pia.zoo2020.util.SessionUtils;

@Named(value = "posetilacManagedBean")
@RequestScoped
public class PosetilacManagedBean {
    private final List<Zivotinja> zivotinje = new ArrayList<>();
    private final List<Predlog> predlozi = new ArrayList<>();
    private String zivotinja;
    private String komentar;
    
    @PostConstruct
    public void getData() {
        DB inst = DB.getInstance();
        Connection db = inst.getConnection();
        try (
            Statement stmt = db.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT * FROM zivotinje");
            Statement stmt2 = db.createStatement();
            ResultSet rs2 = stmt2.executeQuery("SELECT * FROM predlozi WHERE odobren = 0");
            PreparedStatement stmt3 = db.prepareStatement("SELECT * FROM glasovi WHERE posetilac = ? and idP = ?");
        ) {
            while (rs.next()) {
                Zivotinja z = new Zivotinja();
                z.setNaziv(rs.getString("naziv"));
                z.setTezina(rs.getInt("tezina"));
                z.setIdZ(rs.getInt("idZ"));
                zivotinje.add(z);
            }
            while (rs2.next()) {
                Predlog p = new Predlog();
                p.setGlasovi(rs2.getInt("glasovi"));
                p.setKomentar(rs2.getString("komentar"));
                p.setPosetilac(rs2.getString("posetilac"));
                p.setZivotinja(rs2.getString("zivotinja"));
                int idP = rs2.getInt("idP");
                p.setIdP(idP);
                stmt3.setString(1, SessionUtils.getSession().getAttribute("kor_ime").toString());
                stmt3.setInt(2, idP);
                try (ResultSet rs3 = stmt3.executeQuery()) {
                    p.setGlasao(rs3.next());
                }
                predlozi.add(p);
            }
        } catch (SQLException ex) {
            Logger.getLogger(PosetilacManagedBean.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            inst.putConnection(db);
        }
        zivotinje.sort((a, b) -> a.getTezina() - b.getTezina());
    }
    
    public String vote(Predlog p) {
        DB inst = DB.getInstance();
        Connection db = inst.getConnection();
        try (
            PreparedStatement stmt = db.prepareStatement("INSERT INTO glasovi (idP, posetilac) VALUES (?, ?)");
            PreparedStatement stmt2 = db.prepareStatement("UPDATE predlozi SET glasovi = glasovi + 1 WHERE idP = ?");
        ) {
            stmt.setInt(1, p.getIdP());
            stmt.setString(2, SessionUtils.getSession().getAttribute("kor_ime").toString());
            stmt.execute();
            stmt2.setInt(1, p.getIdP());
            stmt2.execute();
        } catch (SQLException ex) {
            Logger.getLogger(PosetilacManagedBean.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            inst.putConnection(db);
        }
        return "posetilac.xhtml?faces-redirect=true";
    }
    
    public String suggest() {
        DB inst = DB.getInstance();
        Connection db = inst.getConnection();
        try (
            PreparedStatement stmt = db.prepareStatement("INSERT INTO predlozi (posetilac, zivotinja, komentar, glasovi, odobren) VALUES (?, ?, ?, 0, 0)");
        ) {
            stmt.setString(1, SessionUtils.getSession().getAttribute("kor_ime").toString());
            stmt.setString(2, zivotinja);
            stmt.setString(3, komentar);
            stmt.execute();
        } catch (SQLException ex) {
            Logger.getLogger(PosetilacManagedBean.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            inst.putConnection(db);
        }
        return "posetilac.xhtml?faces-redirect=true";
    }
    
    public List<Zivotinja> getZivotinje() {
        return zivotinje;
    }

    public List<Predlog> getPredlozi() {
        return predlozi;
    }

    public String getZivotinja() {
        return zivotinja;
    }

    public void setZivotinja(String zivotinja) {
        this.zivotinja = zivotinja;
    }

    public String getKomentar() {
        return komentar;
    }

    public void setKomentar(String komentar) {
        this.komentar = komentar;
    }

}
RadnikManagedBean
package rs.ac.bg.etf.pia.zoo2020.beans;

import rs.ac.bg.etf.pia.zoo2020.entities.Predlog;
import jakarta.annotation.PostConstruct;
import jakarta.inject.Named;
import jakarta.enterprise.context.SessionScoped;
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 rs.ac.bg.etf.pia.zoo2020.util.DB;
import rs.ac.bg.etf.pia.zoo2020.util.SessionUtils;

@Named(value = "radnikManagedBean")
@SessionScoped
public class RadnikManagedBean implements Serializable {
    private List<Predlog> predlozi = new ArrayList<>();
    private String naziv;
    private String tezina;
    private int idP;
    
    @PostConstruct
    public void getData() {
        DB inst = DB.getInstance();
        Connection db = inst.getConnection();
        try (
            Statement stmt2 = db.createStatement();
            ResultSet rs2 = stmt2.executeQuery("SELECT * FROM predlozi");
            PreparedStatement stmt3 = db.prepareStatement("SELECT * FROM glasovi WHERE posetilac = ? and idP = ?");
        ) {
            while (rs2.next()) {
                Predlog p = new Predlog();
                p.setGlasovi(rs2.getInt("glasovi"));
                p.setKomentar(rs2.getString("komentar"));
                p.setPosetilac(rs2.getString("posetilac"));
                p.setZivotinja(rs2.getString("zivotinja"));
                p.setIdP(rs2.getInt("idP"));
                stmt3.setString(1, SessionUtils.getSession().getAttribute("kor_ime").toString());
                stmt3.setInt(2, rs2.getInt("idP"));
                predlozi.add(p);
            }
        } catch (SQLException ex) {
            Logger.getLogger(PosetilacManagedBean.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            inst.putConnection(db);
        }
    }
    
    public String approve(Predlog p) {
        naziv = p.getZivotinja();
        idP = p.getIdP();
        return "dodaj.xhtml?faces-redirect=true";
    }

    public String reject(Predlog p) {
        DB inst = DB.getInstance();
        Connection db = inst.getConnection();
        try (
            PreparedStatement stmt = db.prepareStatement("DELETE FROM predlozi WHERE idP = ?");
        ) {
            stmt.setInt(1, p.getIdP());
            stmt.execute();
        } catch (SQLException ex) {
            Logger.getLogger(PosetilacManagedBean.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            inst.putConnection(db);
        }
        return "radnik.xhtml?faces-redirect=true";
    }

    public String add() {
        DB inst = DB.getInstance();
        Connection db = inst.getConnection();
        try (
            PreparedStatement stmt = db.prepareStatement("INSERT INTO zivotinje (naziv, tezina) VALUES (?, ?)");
            PreparedStatement stmt2 = db.prepareStatement("UPDATE predlozi SET odobren = 1 WHERE idP = ?");
        ) {
            stmt.setString(1, naziv);
            stmt.setInt(2, Integer.parseInt(tezina));
            stmt.execute();
            stmt2.setInt(1, idP);
            stmt2.execute();
        } catch (SQLException ex) {
            Logger.getLogger(PosetilacManagedBean.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            inst.putConnection(db);
        }
        return "radnik.xhtml?faces-redirect=true";
    }
    
    public String getTezina() {
        return tezina;
    }

    public void setTezina(String tezina) {
        this.tezina = tezina;
    }

    public String getNaziv() {
        return naziv;
    }

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

    public List<Predlog> getPredlozi() {
        return predlozi;
    }

    public void setPredlozi(List<Predlog> predlozi) {
        this.predlozi = predlozi;
    }
    
}

Ентитети

Zivotinja.java
package rs.ac.bg.etf.pia.zoo2020.entities;

public class Zivotinja {
    private int idZ;
    private String naziv;
    private int tezina;

    public int getIdZ() {
        return idZ;
    }

    public void setIdZ(int idZ) {
        this.idZ = idZ;
    }

    public String getNaziv() {
        return naziv;
    }

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

    public int getTezina() {
        return tezina;
    }

    public void setTezina(int tezina) {
        this.tezina = tezina;
    }
}
Predlog.java
package rs.ac.bg.etf.pia.zoo2020.entities;

public class Predlog {
    private String posetilac;
    private String zivotinja;
    private String komentar;
    private int glasovi;
    private boolean glasao;
    private boolean odobren;
    private int idP;

    public int getIdP() {
        return idP;
    }

    public void setIdP(int idP) {
        this.idP = idP;
    }

    public boolean isOdobren() {
        return odobren;
    }

    public void setOdobren(boolean odobren) {
        this.odobren = odobren;
    }

    public String getPosetilac() {
        return posetilac;
    }

    public void setPosetilac(String posetilac) {
        this.posetilac = posetilac;
    }

    public String getZivotinja() {
        return zivotinja;
    }

    public void setZivotinja(String zivotinja) {
        this.zivotinja = zivotinja;
    }

    public String getKomentar() {
        return komentar;
    }

    public void setKomentar(String komentar) {
        this.komentar = komentar;
    }

    public int getGlasovi() {
        return glasovi;
    }

    public void setGlasovi(int glasovi) {
        this.glasovi = glasovi;
    }

    public boolean isGlasao() {
        return glasao;
    }

    public void setGlasao(boolean glasao) {
        this.glasao = glasao;
    }
}

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

main.css
.error {
    color: red;
}

.green {
    color: green;
}