Arquivo

Archive for the ‘Java’ Category

Gráficos com JSF 2 e Primefaces – Torta

Olá pessoal, tudo bem?

Espero que me perdoem a demora em postar novo material, mas estou com alguns projetos em adamento e ando um pouco sem tempo.

Neste novo post daremos início a uma série onde mostrarei como criar alguns tipos de gráficos com Primefaces. Como pontapé inicial veremos a criação de um gráfico de torta onde mostraremos a probabilidade de título do Camp. Brasileiro.

Utilizaremos em nosso projeto exemplo:

– Netbeans 7.0.1
– Primefaces 3.0M3

Obs.: Com primefaces, não há a necessidade de adicionar nenhuma lib para a criação de gráficos, a não ser, que você deseje interagir com o JFreeChart.

Para começar crie um projeto, no nosso caso ExGraficoTorta. Neste projeto construa uma estrutura de pacotes conforme exibido abaixo:

Criamos uma classe Time, outra TimeDAO e um managedbean GraficoBean. Todas estas classes serão detalhadas mais abaixo:

Veja a classe Time.java


public class Time {

    private long id;
    private String nomeTime;
    private double probabilidade;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getNomeTime() {
        return nomeTime;
    }

    public void setNomeTime(String nomeTime) {
        this.nomeTime = nomeTime;
    }

    public double getProbabilidade() {
        return probabilidade;
    }

    public void setProbabilidade(double probabilidade) {
        this.probabilidade = probabilidade;
    }
}

Utilizaremos este modelo para, através do DAO, buscar os dados que desejamos exibir no gráfico de torta. Vamos agora ver como ficará o managedbean utilizado para gerenciar a página. Abaixo confira o código:

@ManagedBean
public class GraficoBean implements Serializable {

    private PieChartModel modelo;

    public GraficoBean() {
        criarModeloGrafico();
    }

    public PieChartModel getModelo() {
        return modelo;
    }

    public void setModelo(PieChartModel modelo) {
        this.modelo = modelo;
    }

    private void criarModeloGrafico() {
        modelo = new PieChartModel();
        List<time> listaTime = new ArrayList<time>();
 TimeDAO timeDAo = new TimeDAO();
 listaTime = timeDAo.listaTodos();
 for (Time time : listaTime) {
 modelo.set(time.getNomeTime(), time.getProbabilidade());
 }
 }
}

Declaramos um objeto do tipo PieChartModel para espelhar o modelod o gráfico de torta que usaremos na nossa página. Como este é um exemplo simples e prático, decidi simplesmente criar um método para preencher o modelo e chamá-lo no construtor. Provavelmente, em suas apps, você deverá invocar o método através de uma action de um botão, menuitem, etc.

Confira abaixo um pouco sobre os principais atributos da tag pieChart

 Nome

Valor Padão

Tipo

Descrição

id

null

String

Identificador único

rendered

TRUE

Boolean

Indica que o componente deve ou não ser renderizado na tela

binding

null

Object

Uma expression language que faz o mapeamento do componente com um objeto UICOmponente localizado no backingbean.

value

null

Collection

É o modelo do gráfico

diameter

null

Integer

Tamanho do diâmetro da torta.

legendPosition

null

Object

Campo que indica a posição da legenda. Coloque as siglas dos pontos cardeais em inglês. Ex.: w, ne, n, etc.

style

null

String

Define o estilo do painel do gráfico, tamanho, tamanho de fonte, etc.

seriesStyle

null

String

Cores dos items. Coloque as cores em formato RGB sem o #.

Não explicarei todos os atributos, até porque você não os utilizará, mas em caso de dúvida post um comentário. Segue o código da nossa página que exibirá o gráfico:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:p="http://primefaces.prime.com.tr/ui"
      xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>Gráficos com JSF 2.0</title>
    </h:head>
    <h:body>
        <p:pieChart value="#{graficoBean.modelo}"
                    legendPosition="w"
                    title="Probabilidade de Título - Brasileirão 2011"
                    style="width:800px;height:600px;"/>
    </h:body>
</html>

Veja na imagem abaixo como ficou:
Gráfico de Torta

É isso ai, bem simples, qualquer dúvida coloca um comentário. Valeu!

JSF 2.0 – PRIMEFACES – P:TREE – CONTROLE DE PERMISSÕES A MENUS

zApós algum tempo sem postar, devido a grande carga de trabalho, consegui um tempo para escrever sobre este maravilhoso componete da biblioteca primefaces. Desde que o vi no showcase sempre tive a idéia de utiliza-lo conforme irei mostrar para vocês, como um controle de permissões com checkboxs. A capacidade de uso deste componente é muito grande e variada devido a flexibilidade e quantidade de recursos agredados a ele.

Antes de iniciar o post gostaria de avisar aos nossos leitores que estão abertas as inscrições para dois cursos na nossa plataforma de ensino a distância. São eles o de FUNDAMENTOS DA LINGUAGEM JAVA e DESENVOLVENDO UMA APLICAÇÃO BÁSICA COM JSF 2.0 E PRIMEFACES. Para mais detalhes, visite a área de cursos em http://www.quebrandoparadigmas.com/cursos/, os preços estão bastante acessiveis, por isso, espero a participação de vocês.

O componete TREE

É um componente usado para exibir dados em formato de árvore. Abaixo os atributos do componente com uma breve descrição:

Nome Valor Padrão Tipo Descrição
id null Tipo Identificador único do componente.
rendered TRUE Boolean Valor boleano que especifica a renderização ou não do componente, quando FALSE o componente não será renderizado.
binding null Object Uma expression language que mapeia o componente para um UIComponente no managed bean.
value null Object Representa uma instância de TreeNode no managed bean.
var null String Nome da variável que será usada para representar cada nó da árvore durante a renderização.
expandAnim null String Animação a ser exibida quando um nó for expandido. Os valores válidos são: FADE_IN ou FADE_OUT.
collapseAnim null String Animação a ser exibida quando um nó for retraido. Os valores válidos são: FADE_IN ou FADE_OUT.
nodeSelectListener null MethodExpr Método do managed bean a ser executado quando um nó for selecionado.
nodeExpandListener null MethodExpr Método do managed bean a ser executado quando um nó for expandido.
nodeCollapseListener null MethodExpr Método do managed bean a ser executado quando um nó for retraído.
cache TRUE Boolean Defini se haverá cache para os nós carregados dinâmicamente. Quando TRUE os nós expandidos serão mantidos na memória.
widgetVar null String Valor da variável para JavaScript.
onNodeClick null String Evendo JavaScript a ser processado quando um nó for clicado.
expanded FALSE Boolean Quando TRUE todos os nós iniciarão expandidos.
update null String Id(s) do(s) componente(s) a ser(em) expandido(s) quando um nó for selecionado.
onselectStart null String Evento JavaScript invocado antes da requisição ajax.
onselectComplete null String Evento JavaScript invocado antes da requisição ajax.
selection null Object Array que referencia todos os nós selecionados.
propagateSelectionUp FALSE Boolean Propaga as seleções para os nós superiores.
propagateSelectionDown FALSE Boolean Propaga as seleções para os nós inferiores.
selectionMode null String Define o modo de seleção.

Fonte: Primefaces User’s Guide 2.2

Para o nosso exemplo utilizaremos:

– Mojarra 2.1
– Primefaces 2.2.1
– Mysql 5.1.53

Neste exemplo irei demonstrar como criar um controle de permissões, com o componente Tree, para gerenciar o acesso de usuários aos menus de uma aplicação. Para quem conseguiu implementar o exemplo de menu dinâmico, pode agregar esta funcionalidade e criar as permissões para cada usuário.

Abaixo o DER com a disposição das tabelas:

Assim, teremos três tabelas, uma para cadastrar os usuários da aplicação, outra para cadastrar os menus e finalmente uma que irá definir os menus que os usuários podem ter acesso.

Desta forma, criaremos os beans e os DAOs, veja imagem abaixo com a organização do projeto.

Como você puderam observar criaremos os três beans, um para cada tabela, abaixo veja o código dos modelos:

Obs.: Suprimimos os getters e setters.

Menu.java

public class Menu {

    private int id;
    private String descricao;
    private String url;
    private String icone;
    private String indice;

    /* Getters e Setters */

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Menu other = (Menu) obj;
        if (this.id != other.id) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 3;
        hash = 67 * hash + this.id;
        return hash;
    }

    @Override
    public String toString() {
        return descricao;
    }
}

Usuario.java

public class Usuario {

    private int id;
    private String login;
    private String senha;
    private Timestamp ultimoAcesso;
    private List<Permissao> listaPermissao = new ArrayList<Permissao>();

   /* Getters e Setters */

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Usuario other = (Usuario) obj;
        if (this.id != other.id) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 31 * hash + this.id;
        return hash;
    }
}

Permissao.java

public class Permissao {

    private int id;
    private Menu menu = new Menu();
    private Usuario usuario = new Usuario();

   /* Getters e Setters */

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Permissao other = (Permissao) obj;
        if (this.id != other.id) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 11 * hash + this.id;
        return hash;
    }
}

No beans é muito importate sobreescrever os métodos equals, hashcode e toString, principalmente na classe Menu, pois iremos fazer comparações entre os objetos criados a partir desta classe.

Com estas classes criadas, vamos criar os DAOs pra acessar os dados na base de dados. Abaixo o código:

MenuDAO.java

public class MenuDAO {

    private Connection con;
    private final String COL_ID = "id";
    private final String COL_DESCRICAO = "descricao";
    private final String COL_URL = "url";
    private final String COL_ICONE = "icone";
    private final String COL_INDICE = "indice";

    public List<Menu> listaTodos() throws SQLException {
        List<Menu> listaMenu = new ArrayList();
        String query = "select * from menus";
        con = ConnectionFactory.getMySQLConnection();
        PreparedStatement ps = con.prepareStatement(query);
        ResultSet rs = ps.executeQuery();
        while (rs.next()) {
            Menu menu = new Menu();
            menu.setId(rs.getInt(COL_ID));
            menu.setDescricao(rs.getString(COL_DESCRICAO));
            menu.setUrl(rs.getString(COL_URL));
            menu.setIcone(rs.getString(COL_ICONE));
            menu.setIndice(rs.getString(COL_INDICE));
            listaMenu.add(menu);
        }
        con.close();
        return listaMenu;
    }
    public Menu buscaPorId(int id) throws SQLException {
        Menu menu = new Menu();
        String query = "select * from menus where id=?";
        con = ConnectionFactory.getMySQLConnection();
        PreparedStatement ps = con.prepareStatement(query);
        ps.setInt(1, id);
        ResultSet rs = ps.executeQuery();
        if (rs.next()) {
            menu.setId(rs.getInt(COL_ID));
            menu.setDescricao(rs.getString(COL_DESCRICAO));
            menu.setUrl(rs.getString(COL_URL));
            menu.setIcone(rs.getString(COL_ICONE));
            menu.setIndice(rs.getString(COL_INDICE));
        }
        con.close();
        return menu;
    }
}

Na classe acima, temos somente dois métodos básicos dos DAOs, listaTodos e buscaPorId.

UsuarioDAO.java

public class UsuarioDAO {

    private Connection con;
    private final String COL_ID = "id";
    private final String COL_LOGIN = "login";
    private final String COL_SENHA = "senha";
    private final String COL_ULTIMOACESSO = "ultimo_acesso";

    public List<Usuario> listaTodos() throws SQLException {
        List<Usuario> listaUsuario = new ArrayList<Usuario>();
        String query = "select * from usuarios";
        con = ConnectionFactory.getMySQLConnection();
        PreparedStatement ps = con.prepareStatement(query);
        ResultSet rs = ps.executeQuery();
        while (rs.next()) {
            Usuario usuario = new Usuario();
            usuario.setId(rs.getInt(COL_ID));
            usuario.setLogin(rs.getString(COL_LOGIN));
            usuario.setSenha(rs.getString(COL_SENHA));
            usuario.setUltimoAcesso(rs.getTimestamp(COL_ULTIMOACESSO));
            listaUsuario.add(usuario);
        }
        con.close();
        return listaUsuario;
    }

    public Usuario buscaPorId(int id) throws SQLException {
        Usuario usuario = new Usuario();
        String query = "select * from usuarios where id=?";
        con = ConnectionFactory.getMySQLConnection();
        PreparedStatement ps = con.prepareStatement(query);
        ps.setInt(1, id);
        ResultSet rs = ps.executeQuery();
        if (rs.next()) {
            usuario.setId(rs.getInt(COL_ID));
            usuario.setLogin(rs.getString(COL_LOGIN));
            usuario.setSenha(rs.getString(COL_SENHA));
            usuario.setUltimoAcesso(rs.getTimestamp(COL_ULTIMOACESSO));
        }
        con.close();
        return usuario;
    }
}

Na classe acima, temos somente dois métodos básicos dos DAOs, listaTodos e buscaPorId.

PermissaoDAO.java

public class PermissaoDAO {

    private Connection con;
    private final String COL_ID = "id";
    private final String COL_USUARIO = "usuarios_id";
    private final String COL_MENU =  "menus_id";

    public List<Permissao> buscaPorUsuario(Usuario usuario) throws SQLException {
        List<Permissao> listaPermissao = new ArrayList<Permissao>();
        MenuDAO menuDAO = new MenuDAO();
        String query = "select * from permissoes where usuarios_id=?";
        con = ConnectionFactory.getMySQLConnection();
        PreparedStatement ps = con.prepareStatement(query);
        ps.setInt(1, usuario.getId());
        ResultSet rs = ps.executeQuery();
        while(rs.next()) {
            Permissao permissao = new Permissao();
            permissao.setId(rs.getInt(COL_ID));
            permissao.setUsuario(usuario);
            permissao.setMenu(menuDAO.buscaPorId(rs.getInt(COL_MENU)));
            listaPermissao.add(permissao);
        }
        con.close();
        return listaPermissao;
    }

    public Permissao buscaPorMenuUsuario(Menu menu, Usuario usuario) throws SQLException {
        Permissao permissao = new Permissao();
        String query = "select * from permissoes where usuarios_id=? and menus_id=?";
        con = ConnectionFactory.getMySQLConnection();
        PreparedStatement ps = con.prepareStatement(query);
        ps.setInt(1, usuario.getId());
        ps.setInt(2, menu.getId());
        ResultSet rs = ps.executeQuery();
        if (rs.next()) {
            permissao.setId(rs.getInt(COL_ID));
            permissao.setMenu(menu);
            permissao.setUsuario(usuario);
        }
        con.close();
        return permissao;
    }

    public void excluiPorUsuario(Usuario usuario) throws SQLException {
        String query = "delete from permissoes where usuarios_id=?";
        con = ConnectionFactory.getMySQLConnection();
        PreparedStatement ps = con.prepareStatement(query);
        ps.setInt(1, usuario.getId());
        ps.execute();
        con.close();
    }

    public void salvar(Permissao permissao) throws SQLException {
        String query = "insert into permissoes(menus_id,usuarios_id) values(?,?)";
        con = ConnectionFactory.getMySQLConnection();
        PreparedStatement ps = con.prepareStatement(query);
        ps.setInt(1, permissao.getMenu().getId());
        ps.setInt(2, permissao.getUsuario().getId());
        ps.execute();
        con.close();
    }
}

Na classe acima temos os métodos buscaPorUsuario, que retorna uma coleção de Permissao, para todos os registros que o usuário for igual ao passado como parâmetro.  Temos tambem, buscaPorMenuUsuario, que retorna uma coleção de Permissao, para aquele registro onde o usuário e o menu são iguais aos passados como parâmetro. Além desses, temos excluirPorUsuario, que exclui todas as permissões do usuário passado como parâmetro e o método salvar, que persiste a permissão passada como parâmetro.

Com estas classes criadas, estamos prontos para partirmos para o desenvolvimento da página. Como toda aplicação JSF criaremos um managed bean para a página que iremos criar e neste colocaremos os atributos que serão acessados na página, além dos métodos que controlarão todas as ações.

A seguir confira como ficou nosso managed bean:

Obs.: Irei suprimir os getters e setters.

PermissaoManagedBean.java
@ManagedBean
@ViewScoped
public class PermissaoManagedBean {

    private TreeNode root;
    private TreeNode[] nosSelecionados;
    private Usuario usuarioSelecionado = new Usuario();
    private List<Usuario> listaUsuario = new ArrayList();
    private List<Permissao> listaPermissao = new ArrayList();
    private List<Menu> listaMenu = new ArrayList();
    private List<Menu> menusPermitidos = new ArrayList();
    private List<Menu> menusUsuario = new ArrayList();
    private UsuarioDAO usuarioDAO = new UsuarioDAO();
    private PermissaoDAO permissaoDAO = new PermissaoDAO();
    private MenuDAO menuDAO = new MenuDAO();

    public PermissaoManagedBean() {
        try {
            listaUsuario = usuarioDAO.listaTodos();
        } catch (SQLException ex) {
            Logger.getLogger(PermissaoManagedBean.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

/* Getters e Setters */
    private boolean isFilho(String[] indicesPai, String[] indicesFilho) {
        boolean isFilho = false;
        int i = 0;
        if (indicesPai.length == indicesFilho.length - 1) {
            for (String string : indicesPai) {
                isFilho = string.equals(indicesFilho[i]);
                if (!isFilho) {
                    break;
                }
                i++;
            }
        }
        return isFilho;
    }

    private void carregarFilhos(List<Menu> menus, Menu menu, TreeNode treeNode) {
        for (Menu m : menus) {
            String[] indicesPai = menu.getIndice().split("\\.");
            String[] indicesFilho = m.getIndice().split("\\.");
            TreeNode tr;
            if ((indicesFilho.length > indicesPai.length)) {
                if (isFilho(indicesPai, indicesFilho)) {
                    if (m.getUrl().equals("")) {
                        tr = new DefaultTreeNode(m, treeNode);
                        carregarFilhos(menus, m, tr);
                    } else {
                        tr = new DefaultTreeNode(m, treeNode);
                        if (isPermitido(m)) {
                            tr.setSelected(true);
                        }
                    }
                }
            }
        }
    }

    private boolean isPermitido(Menu menu) {
        boolean retorno = false;
        for (Menu m : menusPermitidos) {
            if (m.equals(menu)) {
                retorno = true;
                break;
            }
        }
        return retorno;
    }

    public void carregaPermissoesUsuario() {
        permissaoDAO = new PermissaoDAO();
        menuDAO = new MenuDAO();
        root = new DefaultTreeNode("Qp", null);
        menusPermitidos = new ArrayList<Menu>();
        try {
            listaPermissao = permissaoDAO.buscaPorUsuario(usuarioSelecionado);
            listaMenu = menuDAO.listaTodos();

            for (Permissao permissao : listaPermissao) {
                menusPermitidos.add(permissao.getMenu());
            }
            if (usuarioSelecionado.getId() != 0) {
                for (Menu menu : listaMenu) {
                    if ((menu.getUrl().trim().equals("")) && (menu.getIndice().length() == 1)) {
                        TreeNode treeNode = new DefaultTreeNode(menu, root);
                        carregarFilhos(listaMenu, menu, treeNode);
                    }
                }
            }
        } catch (SQLException ex) {
            Logger.getLogger(PermissaoManagedBean.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void salvaPermissoes() {
        if (usuarioSelecionado.getId() == 0) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Nenhum usuário SELECIONADO", "Erro"));
        } else {
            try {
                permissaoDAO.excluiPorUsuario(usuarioSelecionado);
                for (TreeNode no : nosSelecionados) {
                    if (no.isLeaf()) {
                        Menu folha = (Menu) no.getData();
                        Permissao permissao = new Permissao();
                        permissao.setMenu(folha);
                        permissao.setUsuario(usuarioSelecionado);

                        permissaoDAO.salvar(permissao);
                        salvaPai(no);
                    }
                }
                carregaPermissoesUsuario();
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Permissões Salvas", "Permissões Salvas"));
            } catch (SQLException ex) {
                Logger.getLogger(PermissaoManagedBean.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void salvaPai(TreeNode no) {
        TreeNode tr = no.getParent();
        if (!tr.equals(root)) {
            Permissao p;
            try {
                p = permissaoDAO.buscaPorMenuUsuario((Menu) tr.getData(), usuarioSelecionado);
                if (p == null) {
                    Permissao permissao = new Permissao();
                    permissao.setUsuario(usuarioSelecionado);
                    permissao.setMenu((Menu) tr.getData());
                    permissaoDAO.salvar(permissao);
                }
                salvaPai(tr);
            } catch (SQLException ex) {
                Logger.getLogger(PermissaoManagedBean.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}

E abaixo o código da página, que é controlada pelo backing bean acima:

<?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:p="http://primefaces.prime.com.tr/ui"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>QuebrandoParadigmas.com</title>
    </h:head>
    <h:body>
        <h:form>
            <p:panel header="Controle de Permissões" style="margin-top: 10px; width: 500px;">
                <h:panelGrid columns="2">
                    <h:selectOneMenu value="#{permissaoManagedBean.usuarioSelecionado.id}">
                        <f:selectItem itemValue="0" itemLabel=""/>
                        <f:selectItems value="#{permissaoManagedBean.listaUsuario}" var="usuario"
                                       itemValue="#{usuario.id}" itemLabel="#{usuario.login}"/>
                        <p:ajax event="change" listener="#{permissaoManagedBean.carregaPermissoesUsuario()}"
                                update="panelPermissoes"/>
                    </h:selectOneMenu>
                    <p:ajaxStatus>
                        <f:facet name="start">
                            <h:graphicImage value="./imagens/ajax-loader.gif" />
                        </f:facet>
                        <f:facet name="complete">
                            <h:outputText value="" />
                        </f:facet>
                    </p:ajaxStatus>
                </h:panelGrid>
            </p:panel>
            <p:panel id="panelPermissoes" style="margin-top: 10px; margin-bottom: 10px; width: 500px;">
                <p:messages/>
                <p:tree value="#{permissaoManagedBean.root}" selectionMode="checkbox" var="no"
                        expanded="true" expandAnim="FADE_IN" collapseAnim="FADE_OUT"
                        selection="#{permissaoManagedBean.nosSelecionados}" propagateSelectionUp="true" propagateSelectionDown="true">
                    <p:treeNode>
                        <h:outputText value="#{no}" style="margin-left: 10px;"/>
                    </p:treeNode>
                </p:tree>
            </p:panel>
            <p:commandButton value="Salvar" action="#{permissaoManagedBean.salvaPermissoes()}" update="panelPermissoes"/>
        </h:form>
    </h:body>
</html>

Temos um selectOneMenu que lista todos os usuários, representados no managed bean por List<Usuario>, que é preenchido no controller.

Como o escopo do backing bean é de visão(@ViewScoped) sempre que dermos um refresh na página os comandos contidos no construtor serão novamente executados e a página retorna ao seu estado padrão.

Dentro do selectOneMenu inserimos um componente do AjaxEngine do primefaces, o p:ajax com o parametro event = change, ou seja, sempre que "mudarmos" o valor do "combo" será executado o método que esta em parametro listener. Ou seja, sempre que o valor for alterado o métodos carregaPermissoesUsuario() será executado e o painel panelPermissoes será atualizado ao final.

O método carregaPermissoesUsuario() preenche o objeto raiz da árvore, root, com todos os menus que existem na tabela Menu e posteriormente verifica quais dos menus são permitidos ao usuário selecionado e, através do método setSelected(true), define na visão quais "folhas" deverão ser marcadas no componente tree. Bom pessoal, espero que consigam integrar com o menu dinâmico, é simples.

Boa sorte e espero ter ajudado.

Abaixo vídeo da aplicação exemplo rodando:

Gostou do Post? Então faça-nos uma doação:

JSF 2.0 – Primefaces 2.2 – FileUpload com ImageCropper

 

FileUpload

O componente FileUpload, como o prórprio nome diz, é responsável pelo envio de imagens da máquina cliente para o lado servidor. Este componente vai além da navegação da tag html <input type=”file”>, trazendo funcionalidades flashjavascript. Podemos filtrar arquivos, fazer múltiplos uploads, processamento parcial da página e uma barra para acompanhamento do progresso do upload. Caso o navegador cliente não suporte flash ou javascrip o fileupload retorna a funcionalidade padrão de <input type=”file”>.

Em um post anterior, já descrevi como utilizar FileUpload, porém, da versão utilizada no post até a atual tivemos algumas modificações na forma de configuração, o que me leva a descrever alguns procedimentos novamente.

Bibliotecas necessárias:

Configuração do web.xml:

<filter>
   <filter-name>PrimeFaces FileUpload Filter</filter-name>
   <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>

<filter-mapping>
   <filter-name>PrimeFaces FileUpload Filter</filter-name>
   <servlet-name>Faces Servlet</servlet-name>
</filter-mapping>

Abaixo descrição dos principais atributos do componente:

  • id:  Identificador único do componente
  • rendered: Valor boleano para especificar se o componente deve ou não ser exibido
  • fileUploadListener:  Método a ser executado quando sempre que um arquivo for ser enviado
  • multiple:  Habilita o envio de múltiplos arquivos
  • update: id de um componente a ser atualizado após o término do envio do arquivo
  • auto: Quando habilitado(true) o upload do arquivo começa logo após a seleção
  • label: Rótulo do botão, o padrão é ‘Browse’
  • image: Imagem de fundo do botão
  • cancelImage: Imagem do botão cancelar
  • width: Largura do botão de procura
  • height: Altura do botão de procura
  • allowTypes: Lista de extensões de arquivos aceitas
  • description: Rótulo que descreve quais tipos de arquivo podem ser enviados
  • sizeLimit: Número máximo de bytes aceitos
  • wmode: Propriedade wmode do objeto flash
  • customUI: Quando habilitado(true) os links upload e cancel  não são exibidos
  • widgetVar: Nome do widget para referências em javascript

ImageCropper

O componente ImageCropper  tem como funcionalidade recortar determinadas regiões de uma imagem. Esta funcionalidade criauma nova imagem contendo a região recordada e associando-a a um objeto do tipo CroppedImage instanciado no lado servidor.

Abaixo descrição dos principais atributos do componente:

  • id:  Identificador único do componente
  • rendered: Valor boleano para especificar se o componente deve ou não ser exibido
  • required: Indica se o campo é obrigatório
  • value:  EL para um Objeto do tipo CroppedImage instanciado no managed bean.
  • image:  Caminho para a imagem(context path)
  • initialCoords:  Coordenadas da posição inicial da região de corte

Criação de Aplicação integrando FileUpload e ImageCropper

Para criação desta aplicação iremos criar uma view(index.xhtml), uma pasta imagens onde armazenaremos as imagens utilizadas no sistema e uma pasta upload para colocar as imagens enviadas através do file upload. A estrutura do projeto ficará conforme imagem abaixo:

Para este projeto simples devemos criar um bean gerenciado de escopo de sessão para controlar a nossa view, abaixo confira o código.
Obs.: Desconsideramos os getters e setters.

IndexManagedBean.java

@ManagedBean
@SessionScoped
public class IndexManagedBean {

private StreamedContent imagemEnviada = new DefaultStreamedContent();
private String imagemTemporaria;
private CroppedImage croppedImage;
private boolean exibeBotao = false;

/* getters e setters */

   public void criaArquivo(byte[] bytes, String arquivo) {
      FileOutputStream fos;
      try {
         fos = new FileOutputStream(arquivo);
         fos.write(bytes);
         fos.close();
      } catch (FileNotFoundException ex) {
         Logger.getLogger(IndexManagedBean.class.getName()).log(Level.SEVERE, null, ex);
      } catch (IOException ex) {
         Logger.getLogger(IndexManagedBean.class.getName()).log(Level.SEVERE, null, ex);
      }
   }

   public void enviarImagem(FileUploadEvent event) {
      byte[] img = event.getFile().getContents();
      imagemTemporaria = event.getFile().getFileName();
      FacesContext facesContext = FacesContext.getCurrentInstance();
      ServletContext scontext = (ServletContext) facesContext.getExternalContext().getContext();
      String arquivo = scontext.getRealPath("/upload/" + imagemTemporaria);
      criaArquivo(img, arquivo);
      setExibeBotao(true);
   }

   public void crop() {
      setImagemEnviada(new DefaultStreamedContent(new ByteArrayInputStream(croppedImage.getBytes())));
   }
}

O método enviarImagem(FileUploadEvent event) é utilizado no atributo fileUploadListener para ser executado sempre que uma imagem estiver sendo enviada. É neste método onde poderemos fazer conversões, criação de arquivos, etc.

Observem que no método é passado um parâmetro event com o qual eu consigo retirar todos os dados que preciso, como nome de arquivo, caminho, array de bytes referentes ao arquivo, etc. Iremos criar um arquivo temporário que será utilizado na view com o imageCropper, este arquivo é criado na pasta upload através do método criaArquivo, e também salvar o nome do arquivo criado em uma String, a imagemTemporaria.

Em seguida criamos o método crop() para coletar a imagem recortada e jogar dentro da imagemEnviada que é do tipo StreamedContent, que pode ser trabalhado dinamicamente com o um p:graphicImage. Abaixo confira a utilização de todos os métodos e atributos na view:

<h:form>
   <p:panel header="ImageCropper com FileUpload - QuebrandoParadigmas.com" style="width: 900px; margin: 0 auto; margin-top: 0px">
      <p:fileUpload fileUploadListener="#{indexManagedBean.enviarImagem}" sizeLimit="204800" auto="true"
                            image="/imagens/imgBuscar.png" customUI="true" update="outputPanelUpload"/>
      <p:outputPanel id="outputPanelUpload">
         <h:panelGrid columns="2">
            <h:outputText value="Imagem" rendered="#{indexManagedBean.exibeBotao}"/>
             <h:outputText value="Pre-visualização" rendered="#{indexManagedBean.exibeBotao}"/>
             <p:imageCropper id="imageCropperImagemTemporaria" value="#{indexManagedBean.croppedImage}"
              image="#{pageContext.servletContext.contextPath}/upload/#{indexManagedBean.imagemTemporaria}"/>
              <p:graphicImage value="#{indexManagedBean.imagemEnviada}" cache="false"/>
         </h:panelGrid>
         <p:commandLink action="#{indexManagedBean.crop}" update="outputPanelUpload"
                                   rendered="#{indexManagedBean.exibeBotao}">
            <p:graphicImage style="margin-top: 5px; border: none;" value="/imagens/imgCortar.png"/>
         </p:commandLink>
      </p:outputPanel>
   </p:panel>
</h:form>

Criamos um outputPanel de nome outputPanelUpload que é  atualizado sempre que algum dado no managed bean é alterado, como quando a imagem de upload é enviada e damos um update para exibi-la ou quando cortamos a imagem e atualizamos para exibir a região cortada em uma outra imagem. Gostaria de salientar o código abaixo, pois é nele onde carregamos  a imagem que foi criada no na pasta upload do servidor:
image=”#{pageContext.servletContext.contextPath}/upload/#{indexManagedBean.imagemTemporaria}”

Perceba que pego o caminho do contexto(pasta web) e dentro dele a pasta upload e, em seguida, acrescento com uma EL que representa o nome do arquivo que foi definido no fileUploadListener(enviaImagem).

O resultado você pode conferir no vídeo abaixo:





Twitter: @benignoms

JSF 2.0 + PRIMEFACES + iREPORT

Neste post iremos demonstrar, de forma sucinta, como criar relatórios com iReport e como utiliza-lo em suas aplicações web. O iReport é uma ferramenta para  se desenhar relatórios para o JasperReport, que é a uma biblioteca para geração de relatórios. Escolhemos o iReport, por ser uma ferramenta open-source e de bastante disseminação na comunidade Java, além de ser muito fácil de usar e possuir integração com o JFreeChart, para geração de gráficos, e com o Barbecue, gerador de código de barras.

No nosso exemplo utilizaremos

  • Mojarra 2.0.3
  • Primefaces 2.2.1
  • Mysql JDBC Connector 5.1.14

Alé disso precisamos acrescertar ao projeto, as bibliotecas necessárias para rodar relatórios jasper. São elas:

  • Jasper Reports 3.7.6
  • iText 2.1.7
  • Grovy All 1.7.5
  • Commons beanutils 1.8.2
  • Commons collections 3.2.1
  • Commons Digester 1.7
  • Commons Logging 1.1

Lembre-se que a maioria destes jars você pode encontrar na pasta libs do iReport..

Abaixo você pode ver a estrutura que usaremos para nossa base de dados:

Imagem 1

Como você pode ver, utilizaremos uma tabela cargos(mestre) com uma tabela funcionários(detalhes), onde um cargo pode ser comum de vários funcionários, mas um funcionário só de ter um cargo.

Iniciando com o iRerpot

O iReport é uma ferramenta para criação do arquivo jrxml, que nada mais é do que uma definição do relatório em xml. Esta definição poderia ser feita em um bloco de notas, ou qualquer outro editor de texto, porém seria uma atividade incomparavelmente mais custosa para o desenvolvedor.

Com o iReport, é possível desenhar todo o relatório, incluir imagens, além de manipular sub-relatórios e diferentes fontes de dados.

Bom, no início de qualquer relatório é necessário primeiro definir a fonte de dados, ou seja, de onde iremos captar os dados para construção do relatório. Existem duas formas que gosto de trabalhar, uma é utilizando uma consulta SQL diretamente no banco e utilizando os dados retornados para preencher o relatórios. Outra forma, é através da utilização de JavaBeans enviado para o relatório apenas uma coleção dos dados a serem utilizados.

Ao construirmos um relatório temos diversas bandas aparentes na tela, estas seções são divisões da tela do relatório onde podemos preenche-las com textos e imagens .

No iReport estão visíveis 9 seções, ou bandas. São elas:

1. Title: Título do relatório. Pode ser impresso em uma página separada;

2. Page Header: Cabeçalho de cada página do relatório;

3. Column Header: Seção exibida em cada página que contém uma seção Detail;

4. Detail: Nesta seção são impressos todos os registros fornecidos ao relatório;

5. Column Footer: Exibido em cada página que contém uma seção Detail;

6. Page Footer: Rodapé de cada página;

7. Summary: Seção exibida no fim do relatório. Pode ser impresso em uma página separada;

8. No Data: Seção exibida quando não há registros;

9. Background: Nesta seção é possível inserir uma imagem de fundo que será exibida em cada página do relatório.

Fonte: Gerando relatórios com iReport – Roberto Jundi Furutani da Java Magazina 84.

Imagem 2

Criando os Beans

Na aplicação exemplo que iremos fazer, teremos dois beans. Abaixo você pode ver a codificação de ambos:

Cargo.java

public class Cargo {

private int id;

private String descricao;

public String getDescricao() {

return descricao;

}

public void setDescricao(String descricao) {

this.descricao = descricao;

}

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

}

Funcionario.java


public class Funcionario {

private int id;

private String nome;

private String email;

private Cargo cargo = new Cargo();

public Cargo getCargo() {

return cargo;

}

public void setCargo(Cargo cargo) {

this.cargo = cargo;

}

public String getEmail() {

return email;

}

public void setEmail(String email) {

this.email = email;

}

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getNome() {

return nome;

}

public void setNome(String nome) {

this.nome = nome;

}

}

Para que você possa utilizar os beans no iReport é necessário gerar os arquivos .jar e incluir no classpath. Caso você utilize o netbeans você poderá criar uma nova aplicação desktop, criar as classes e executar a aplicação. Dentro da pasta dist, será gerado um arquivo .jar, com o nome que você de ao projeto da aplicação. Com este arquivo criado,  basta colocar para o classpath do iReport apontar para o local onde você o salvou e pronto. Agora, você já pode configurar seu relatório baseado nos dois modelos que criamos.

Imagem 3

Para isso, vamos criar um novo relatório no iReport e depois clicar com o botão direito do mouse sobre o nome do relatório que fica na aba Report Inspector. Feito isso, clique em Edit Query. Abaixo veja imagens das telas:

Imagem 4

Imagem 5

Você deve escolher a segunda aba, JavaBean DataSource, a primeira é para utilizar-se com uma consulta SQL diretamente na base de dados. Digite o nome da classe, nome completo, incluindo o pacote e depois clique em Read Attributes e depois  selecione os campos e clique em Add Selected Field(s)

Imagem 6

Após adicionar os campos vamos montar nosso relatório. Utilize a paleta com as imagens, static text e text fields para montar seu relatório.

Montamos de acordo com a imagem abaixo:

Imagem 7

Criei uma aplicação JSF simples, somente com um botão para chamar o  relatório.

Imagem 8

Veja abaixo os DAOS:

FuncionarioDAO.java

public class FuncionarioDAO {

private Connection conexao;

public List<Funcionario> listaTodos() {

List<Funcionario> listaFuncionario = new ArrayList<Funcionario>();

String consulta = "select * from tab_funcionarios";

try {

conexao = ConnectionFactory.getMySQLConnection();

PreparedStatement ps = conexao.prepareStatement(consulta);

ResultSet rs = ps.executeQuery();

CargoDAO cargoDAO = new CargoDAO();

while(rs.next()) {

Funcionario funcionario = new Funcionario();

funcionario.setId(rs.getInt("id"));

funcionario.setNome(rs.getString("nome"));

funcionario.setEmail(rs.getString("email"));

funcionario.setCargo(cargoDAO.buscaCargoPorId(rs.getInt("tab_cargos_id")));

listaFuncionario.add(funcionario);

}

} catch (SQLException ex) {

Logger.getLogger(FuncionarioDAO.class.getName()).log(Level.SEVERE, null, ex);

}

return listaFuncionario;

}

}

CargoDAO.java

public class CargoDAO {

private Connection conexao;

public Cargo buscaCargoPorId(int id) {

Cargo cargo = new Cargo();

try {

conexao = ConnectionFactory.getMySQLConnection();

String consulta = "select * from tab_cargos where id=?";

PreparedStatement ps = conexao.prepareStatement(consulta);

ps.setInt(1, id);

ResultSet rs = ps.executeQuery();

if(rs.next()) {

cargo.setId(rs.getInt("id"));

cargo.setDescricao(rs.getString("descricao"));

}

} catch (SQLException ex) {

Logger.getLogger(CargoDAO.class.getName()).log(Level.SEVERE, null, ex);

}

return cargo;

}

}

Para chamar o relatório, colocamos o arquivo compilado(.jasper) na pasta report dentro da pasta web-inf e usamos o método imprimeRelatório() do manager bean:

public void imprimeRelatorio() throws IOException, SQLException {

Connection con = ConnectionFactory.getMySQLConnection();

FuncionarioDAO funcionarioDAO = new FuncionarioDAO();

List<Funcionario> listaFuncionario = new ArrayList<Funcionario>();

listaFuncionario = funcionarioDAO.listaTodos();

JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(listaFuncionario);

HashMap parameters = new HashMap();

try {

FacesContext facesContext = FacesContext.getCurrentInstance();

facesContext.responseComplete();

ServletContext scontext = (ServletContext) facesContext.getExternalContext().getContext();

JasperPrint jasperPrint = JasperFillManager.fillReport(scontext.getRealPath("/WEB-INF/report/relatorio_funcionarios_por_cargo.jasper"), parameters, ds);

ByteArrayOutputStream baos = new ByteArrayOutputStream();

JRPdfExporter exporter = new JRPdfExporter();

exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);

exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, baos);

exporter.exportReport();

byte[] bytes = baos.toByteArray();

if (bytes != null && bytes.length > 0) {

HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();

response.setContentType("application/pdf");

response.setHeader("Content-disposition", "inline; filename=\"relatorioPorData.pdf\"");

response.setContentLength(bytes.length);

ServletOutputStream outputStream = response.getOutputStream();

outputStream.write(bytes, 0, bytes.length);

outputStream.flush();

outputStream.close();

}

} catch (Exception e) {

e.printStackTrace();

}

}


Abaixo o resultado do relatório:

É isso, o que ficar de dúvida a gente tenta resolver pelos comentários.

Abraços.

Criando Gráficos Com Primefaces

Meu tempo está realmente mais curto trabalhos, consultoria e agora o curso de java da FAETE. Mas não vou deixar de escrever. E para continuar o assunto PrimeFaces eu vou apresentar o suporte a gráfico deste framework.

Exsitem duas formas de se desenhar gráficos em nossa aplicação web com o primefaces: Ou utilizamos seu suporte nativo que utiliza Flash para desenhar os gráficos ou usamos a integração do framework com o JFreeChart. A segunda opção é minha preferida por usar uma biblioteca já consagrada. Vou demostrar as duas formas.

Criando um novo Projeto

Para iniciar nossos exemplos vamos criar um novo projeto no netbeans 6.8 e vamos utilizar a especificação JEE6 com glassfish v3. Em caso de dúvida de como criar um projeto JSF 2.0 veja os post anteriores. Não esqueçam de adicionar nas bibliotecas do projeto o arquivo primefaces-2.0.1.jar, isso para que possamos utilzar as tag libs do primefaces em nossas páginas.

Graficos Utilizando o suporte Nativo.

O Primefaces possui alguns componente para criar diversos tipos de gráficos de forma bem simples e intuítiva, os tipos de gráficos são:

  • Pie Chart – Usado para desenhar gráficos do tipo pizza.

  • Line Chart – Usando para desenhar gráficos em Linha.


  • Column Chart – Usado para desenhar gráficos em coluna. Este mesmo gráfico existe a opção de ser desenhado na horizontal (Bar Chart).

  • Stacked (Column ou Bar) Chart – Usado para desenhar gráfico (de coluna) empilhado.

Para nosso primeio exemplo vamos criar um gráfico do tipo pizza. Para tanto devemos pensar o que nosso gráfico vai demostrar, que tipo de dado estatístico ele vai exibir. Aproveitando o ano eleitoral, vamos criar um gráfico que demostre a intenção de votos para alguns dos candidatos à presidencia da república. Antes de tudo vamos criar um nova classe que vai possuir apenas dois atributos: canditado e totalVotos. Nossa classe segue abaixo, eu a chamei de ConcorrenciaEleitoral e está no meu pacote modelo.


package modelo;

/**
 * criando em 23/05/2010
 * @author wagner
 */
public class ConcorrenciaEleitoral {
 private String candidato;
 private int totalVotos;

 public ConcorrenciaEleitoral() {
 }

 public ConcorrenciaEleitoral(String candidato, int totalVotos) {
 this.candidato = candidato;
 this.totalVotos = totalVotos;
 }

 public String getCandidato() {
 return candidato;
 }

 public void setCandidato(String candidato) {
 this.candidato = candidato;
 }

 public int getTotalVotos() {
 return totalVotos;
 }

 public void setTotalVotos(int totalVotos) {
 this.totalVotos = totalVotos;
 }
}

Agora já temos nossa classe capaz de armazenar as informações que precisamos. O próximo passo é criar nosso Managed Bean e adicionarmos um atributo que seja uma coleção de objetos da entidade ConcorrenciaEleitoral. Nosso Managed Bean vai ter aparecia do código abaixo, eu a chamei de ConcorrenciaEleitoralController e está no pacote controller:


package controller;

import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import modelo.ConcorrenciaEleitoral;

/**
 * criando em 23/05/2010
 * @author wagner
 */
@ManagedBean(name="concorrenciaEleitoral")
public class ConcorrenciaEleitoralController {
 private List<ConcorrenciaEleitoral> concorrencia = new ArrayList();

 public ConcorrenciaEleitoralController() {
 carregaDadosVotacao();
 }

 public List<ConcorrenciaEleitoral> getConcorrencia() {
 return concorrencia;
 }

 public void setConcorrencia(List<ConcorrenciaEleitoral> concorrencia) {
 this.concorrencia = concorrencia;
 }

 public void carregaDadosVotacao() {
 concorrencia.add(new ConcorrenciaEleitoral("José Serra", 650));
 concorrencia.add(new ConcorrenciaEleitoral("Dilma Rousseff", 450));
 concorrencia.add(new ConcorrenciaEleitoral("Marina Silva", 200));
 concorrencia.add(new ConcorrenciaEleitoral("Outros", 150));
 }
}

Olhando para nosso controlador não existe nenhuma novidade. Como já foi dito em post anteriores, no JSF 2.0 nós declaramos nossos Managed Beans através de anotações, ou seja, não precisamos mais fazer nenhuma configuração em arquivos XML (faces-config.xml). O nome do objeto que será criado será concorrenciaEleitoral, conforme esta nesta linha @ManagedBean(name=”concorrenciaEleitoral”). Essa declaração do nome ela é facultativo, quando não explicitamos o nome do objeto que será criado o nome dado é o mesmo nome da classe com a primeira letra em minusculo. Logo abaixo crie um atributo do tipo List que irá armazenar objetos do tipo ConcorrenciaEleitoral contendo as intenções de voto para cada canditato. Logo abaixo um método chamado carregaDadosVotacao foi criado para preencher a Lista com dados fictícios, esse método é chamado no construtor da classe para carregar a lista no momento da criação do objeto.

Agora devemos escrever nossa página que vai exibir nosso gráfico com essas informação. A tag lib, do primefaces, responsavel por desenhar um gráfico em pizza é a p:pieChart, e essa tah possui alguns atributos que merecem comentários:

  • value – É o atributo que esperaça a lista com os dados (a lista que será interada).
  • var – A variável que representa cada elemento da lista. (No nosso caso a variável irá representar cada objeto da nossa lista)
  • categoryField – Nesse atributo devemos informar qual o atributo de nossa classe de modelo representa a categoria quantificada, em nosso caso é o atributo canditado da nossa classe ConcorrenciaEleitoral
  • dataField – Nesse atributo informamos o atributo que possui o valor de uma determinada categoria, no nosso caso é o atributo totalVotos da classe ConcorrenciaEleitoral.

obs: para esse exemplo esses atributos que merecem destaques, mas existem atributos interessante que serão visto em um post seguinte.

A página index.xhml, depois de adicionada a tag lib p:pieChart com os atributos descritos acima, segue abaixo:



<?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://java.sun.com/jsf/html"

xmlns:p="http://primefaces.prime.com.tr/ui">

<h:head>

<title>Gráficos com PrimeFaces</title>

</h:head>

<h:body>

<p:pieChart value="#{concorrenciaEleitoral.concorrencia}" var="concorrencia"

categoryField="#{concorrencia.candidato}" dataField="#{concorrencia.totalVotos}"/>

</h:body>

</html>

O resultado pode ser visto abaixo:

No próximo post vamos utilizar o mesmo projeto e as mesmas informações para também criar um gráfico de pizza, só que dessa vez vamos utilizar a integração com o JFreeChart.

um abraço e até o próximo.

Desenvolvimento Web Com JSF 2.0

No dia 20 de maio, quinta-feira, estarei ministrando uma palestra sobre JEE6, mais precisamente sobre JSF2, no Centro de Ensino Unificado de Teresina – CEUT. Então quem tiver interesse pode aparecer por lá. Abaixo um pouco mais de informações.

Horário, Data e Local

Data: 20 de Maio de 2010
Horário: 14:30h às 16:30h
Local:  Faculdade CEUT.

Então eu conto com a presença de vocês.

um abraço.

Categorias:Frameworks, Java, JSF 2.0, JSP, RIA, Servlet

Introdução ao JSF 2.0 com PrimeFaces parte II

Hoje eu vou mostrar mais um componente do primefaces e vou também falar um pouco sobre a nova forma de declarar Managed Beans no JSF 2.0. O componente que vou mostrar é o <p:collector />, esse componente é um facilitador para formulario do tipo  mestre-detalhe visto que ele inseri e remove objetos de uma lista a ele associado. O componente comumente está associado á um componente <h:commandButton> e um <h:dataTable />.

Criando nossas classes de Modelo e Managed Bean.

Seguindo o exemplo que foi dado no último post, a nossa estrutura de projeto deve está conforme a imagem exibida abaixo:

Estrutura do projeto

Por questão de organização e padronização nós vamos adicionar dois novos pacotes em nosso pacotes de código-fonte chamados de org.seed.exemploprime.managedbeans e org.seed.exemploprime.modelo. Para criar os pacotes basta clicar com o botão direito sobre a pasta Pacotes de código-fonte –> Novo –> Pacote Java. Dentro do pacote org.seed.exemploprime.modelo vamos adicionar uma classe java chamada de Aluno, a classe Aluno representa uma entidade de nosso sistema e é comumente chamada pela comunidade como um DTO (Data Transfer Object) e segue um padrão chamado de JavaBeans. A nossa classe é exibida abaixo:

package org.seed.exemploprime.modelo;

/**
 *criado em 27/04/2010
 * @author wagnerborges
 */
public class Aluno {
 private String matricula;
 private String nomeCompleto;
 private String login;
 private String senha;

 public String getLogin() {
 return login;
 }

 public void setLogin(String login) {
 this.login = login;
 }

 public String getMatricula() {
 return matricula;
 }

 public void setMatricula(String matricula) {
 this.matricula = matricula;
 }

 public String getNomeCompleto() {
 return nomeCompleto;
 }

 public void setNomeCompleto(String nomeCompleto) {
 this.nomeCompleto = nomeCompleto;
 }

 public String getSenha() {
 return senha;
 }

 public void setSenha(String senha) {
 this.senha = senha;
 }
}

Agora vamos adicionar no pacote org.seed.exemploprime.managedbeans uma classe chamada de AlunoManagedBean, essa classe vai interagir com nossa página capturando os eventos e dados fornecidos pelos usuários. Essa classe também é chamada de Backing Bean. A classe vai ficar como o código abaixo:


package org.seed.exemploprime.managedbeans;

import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import org.seed.exemploprime.modelo.Aluno;

/**
 *criado em 27/04/2010
 * @author wagnerborges
 */

@ManagedBean
@SessionScoped

public class AlunoManagedBean {
 private Aluno aluno = new Aluno();
 private List<Aluno> listaAlunos = new ArrayList();

 public Aluno getAluno() {
 return aluno;
 }

 public void setAluno(Aluno aluno) {
 this.aluno = aluno;
 }

 public List<Aluno> getListaAlunos() {
 return listaAlunos;
 }

 public void setListaAlunos(List<Aluno> listaAlunos) {
 this.listaAlunos = listaAlunos;
 }

public void create(){
 aluno = new Aluno();
 }


}

A classe acima merece alguns comentários. Como foi dito acima ela representa um managed bean, isso significa dizer que eu posso vincular (binding) seus atributos ou métodos com componentes de minhas páginas JSF. É essa caracteristica que torna o JSF uma framework orientado a componentes e a eventos. O que caractetiza nossa classe como sendo um bean gerenciado é a anotação @ManagedBean sobre a definição da classe. Essa é nova forma de se declarar  Managed Bean na nova especificação JSF, antes isso era feito em pelo menos 5 linhas em um arquivo xml chamdo de faces-config.xml que é o arquivo de configuração do Java Server Faces. Uma outra anotação que podemos perceber logo abaixo é a anotação @SessionScoped, essa anotação informa que o escopo de nosso bean gerenciado é de sessão, ou seja, enquanto durar minha sessão eu vou ter um objeto da classe AlunoManagedBean na sessão da minha aplicação. Análogo ao escopo de sessão existe o escopo de request referenciado pela anotação @RequestScoped onde um novo objeto é criado a cada requisição realizada pelo usuario. Ainda existem outros tipos de escopos: @ConversationScoped que cria um escopo de conversação entre duas páginas onde os objetos permanecem “vivos”  entre a pagina que originou o request até a página alvo. @ApplicationScoped que cria um escopo cujos os objetos são vistos por toda aplicação enquanto a aplicação estiver em execução.

Nossa classe AlunoManagedBean possui dois atributos: aluno da classe Aluno cujos atributos vamos vincular com os campos do nosso formulario e um atributo listaAlunos que é do tipo ArrayList que é onde vamos armazenar nossos objetos criado. A lista também será usada para exibir uma tabela com os objetos já cadastrados. Além dos dois atributos a classe possui um método chamado de create que será chamdo sempre que um novo objeto for inserido na lista, isso para que todos objetos sejam diferentes e não apontem para o mesmo endereço de memória.

Feito isso, a nova estrutura de nosso projeto deve está conforme imagem abaixo:

Nova Estrutura

O que vamos fazer agora é vincular nossa página index.xhtml com os atributos do nosso Bean Managed, mas qual é o nome do nosso Bean Managed? é o mesmo nome da classe? Antes do JSF2 deveriamos informa qual o nome do objeto que seria criado e referenciado nas páginas, mas agora quando colocamos a anotação @ManagedBean temos a opção de informa um nome ou não. Se desejarmos informar um nome fazemos assim: @ManagedBean(name=”alunoBean”), mas se não desejamos explicitar um nome para o nosso bean gerenciado um nome é criado tomando como base o nome da classe com a primeira letra em minusculo, então no nosso caso o objeto que será criado e que vamos referenciar em nossas páginas vai ser alunoManagedBean. Abaixo o código da nossa página index.html depois de alterado. Os comentários sobre os componentes vem logo em seguida.


<?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://java.sun.com/jsf/html"

xmlns:p="http://primefaces.prime.com.tr/ui"

xmlns:f="http://java.sun.com/jsf/core">

<h:head>

<title>Facelet Title</title>

</h:head>

<h:body>

<h:panelGrid>

<p:messages />

<h:form>

<p:panel closable="true" footer="Cadastro" header="Cadastro de Alunos" style="width: 350PX">

<h:panelGrid columns="2">

<h:outputLabel value="Matricula:"/>

<h:inputText id="matricula" required="true" value="#{alunoManagedBean.aluno.matricula}"

requiredMessage="Campo [Matricula] obrigatório"/>

<h:outputLabel value="Nome Completo:"/>

<h:inputText id="nome" required="true" value="#{alunoManagedBean.aluno.nomeCompleto}"

requiredMessage="Campo [Nome Completo] obrigatório"/>

<h:outputLabel value="Nome p/ Login:"/>

<h:inputText id="login" required="true" value="#{alunoManagedBean.aluno.login}"

requiredMessage="Campo [Nome p/ login] obrigatório"/>

<h:outputLabel value="Senha:"/>

<p:password minLength="6" value="#{alunoManagedBean.aluno.senha}"

promptLabel="Digite uma senha segura"

goodLabel="Boa"

weakLabel="Razoável"

strongLabel="Excelente" />

<h:commandButton value="Cadastrar" action="#{alunoManagedBean.create}">

<p:collector value="#{alunoManagedBean.aluno}" addTo="#{alunoManagedBean.listaAlunos}"/>

</h:commandButton>

</h:panelGrid>

</p:panel>

</h:form>

<br/><br/>

<h:form>

<p:dataTable value="#{alunoManagedBean.listaAlunos}" var="aluno">

<p:column>

<f:facet name="header">

<h:outputText value="Matricula" />

</f:facet>

<h:outputText value="#{aluno.matricula}" />

</p:column>

<p:column>

<f:facet name="header">

<h:outputText value="Nome" />

</f:facet>

<h:outputText value="#{aluno.nomeCompleto}" />

</p:column>

<p:column>

<f:facet name="header">

<h:outputText value="Login" />

</f:facet>

<h:outputText value="#{aluno.login}" />

</p:column>

<p:column>

<f:facet name="header">

<h:outputText value="Remover" />

</f:facet>

<h:commandLink value="remover">

<p:collector value="#{aluno}" removeFrom="#{alunoManagedBean.listaAlunos}"/>

</h:commandLink>

</p:column>

</p:dataTable>

</h:form>

</h:panelGrid>

</h:body>

</html>

Vamos aos comentários

Primeiramente, fazemos a vinculação dos campos com os atributos:

<pre><h:inputText id="matricula" required="true" value="#{alunoManagedBean.aluno.matricula}" requiredMessage="Campo [Matricula] obrigatório"/></pre>

alunoManagedBean é o nome do objeto que foi criado da nossa classe AlunoManagedBean, aluno é um atributo da classe Aluno e nomeCompleto um atributo do objeto aluno.

O trecho abaixo mostra onde fazemos uso do componente <p:collector /> associado com um componente <h:commandButton />, o componente <h:commanButton/> possui um atributo chamado de action onde informamos qual o método que deverá ser executado quando o mesmo for pressionado. Nesse caso, a action associada a esse botão é o método create do nosso ManagedBean. Em seguida nosso componente <p:collector/> é adicionado com dois atributos, no atributo value é informado qual o objeto do ManagedBean se deseja armazenar na lista e no atributo addTo é informado em qual lista o objeto será amazeado.

<pre><h:commandButton value="Cadastrar" action="#{alunoManagedBean.create}">

<p:collector value="#{alunoManagedBean.aluno}" addTo="#{alunoManagedBean.listaAlunos}"/>

</h:commandButton></pre>

Em seguida criamos uma tabela informando no atributo value qual a lista que será exibida e um atributo var para informa o nome do objeto que está sendo interado pela lista.

<pre><p:dataTable value="#{alunoManagedBean.listaAlunos}" var="aluno"></pre>

Na tabela também adicionamos um link para remover objetos da lista utilizando o componente <p:collector> informando qual o objeto se deseja remover através do atributo value e de qual lista esse objeto será removido através do atributo removeFrom.

<pre><h:commandLink value="remover">

<p:collector value="#{aluno}" removeFrom="#{alunoManagedBean.listaAlunos}"/>

</h:commandLink></pre>

A imagem abaixo exibe nossa página index.xhtml em execução:

Resultado Final do Exemplo

Bom pessoal é isso aí. Espero que gostem e que seja útil.

abraços e até a próxima.

Introdução ao JSF 2.0 com PrimeFaces

Depois de mais um longo tempo sem post resolvi voltar com JSF 2.0. Estive ministrando algumas palestras em algumas faculdades daqui da cidade e prometi um post sobre JSF 2.0 com PrimeFaces. Então vamos lá!! Esse post vai de forma especial para os empolgantes alunos do curso de Sistema de Informação da FAETE.

Enquanto o RichFaces não aparece com sua versão final para o JSF2 a melhor alternativa com certeza é o PrimeFaces, que com certeza largou na frente, com seus maravilhosos componentes. Nesse post vou iniciar uma introdução ao JSF 2 e apresentar alguns dos principais componentes do PrimeFaces.

Ambiente de desenvolvimento

Mais uma vez vamos utilizar o NetBeans IDE 6.8 para o nosso exemplo. Mas fiquem a vontade para utilizar qualquer IDE de sua preferência.

Criando o projeto

Com o NetBeans aberto vamos criar um novo projeto através do Menu Arquivo –> Novo Projeto, na tela que se abrir vamos escolher a categoria Java Web e do lado direito a opção aplicação web conforme imagem abaixo:

Assistente de criaçãode Novo Projeto no Netbeans 6.8

Assistente de criaçãode Novo Projeto no Netbeans 6.8

Na próxima tela o assistente solicita o nome projeto, vamos chamar nosso projeto de exemplo_primefaces. Na próxima tela, o assistente pede para que seja informado o servidor que gostariamos de utilizar na nossa aplicação e qual a versão da especificação JEE que queremos usar. Vamos utilizar como servidor o GlassFish V3 e como especificação JEE a versão 6, já que queremos fazer uso do JSF 2.0. Conforme mostra a imagem abaixo:

Escolhendo a especificação e o servidor

Na próxima tela o assistente nos pergunta qual framework gostariamos de utilizar na nossa aplicação, vamos selecionar a opção Java Server Faces.

Nosso projeto está criado, agora só falta nós informar que o nosso projeto vai fazer uso da suite de componentes do PrimeFaces. Para isso basta teremos quer fazer o download da biblioteca do PrimeFaces aqui, escolhe a opção JSF 2.0 e baixe o arquivo binario primefaces-2.0.1.jar. Vamos adicionar o arquivo baixado como biblioteca de nosso projeto, com um click com o botão direito sobre a pasta bibliotecas escolha a opção Adicionar JAR/pasta…, vá até onde está o arquivo que foi baixado e adicione-o. Nosso projeto deve está com a estutura mostrado na imagem abaixo:

Estrutura do projeto

Vamos agora testar se nossa aplicação realmente esta pronta para utilizar os componentes do primefaces. Observe que nós temos na pasta Páginas Web um arquivo chamado index.xhtml, vamos abrir esse arquivo e adicionar a tag lib do primefaces. É através da tag lib que fazemos uso dos componentes da biblioteca através de um prefixo, que nesse caso é prefixo p. O novo depois de alterado fica conforme mostrado abaixo

<?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://java.sun.com/jsf/html"
xmlns:p="http://primefaces.prime.com.tr/ui">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
Hello from Facelets
</h:body>
</html>

O primeiro componente que vou mostrar aqui é o <p:messages />, esse componente é responsavel por capturar as mensagens originadas no processo de validação, converção de dados ou de erros. É equivalente ao <h:messages />, mas muito mais interessante visto que ele já é um componente estilizado. Nesse mesmo exemplo outros dois componentes serão mostrado, o <p:panel /> e o <p:password/>.

Alguns atributos desses componentes merecem destaque:

<p:panel header=”Cadastro Alunos” footer=”cadastro” closable=”true”> –> o atributo header coloca um cabeçalho no panel, enquanto que o footer coloca um texto no rodapé do panel. o Atributo clasable indica se o panel pode ser fechado ou não. Se tiver marcado como true o mesmo poderá ser fechado através de um icone redenrizado pelo próprio componente.

<p:password minLength=”6″  promptLabel=”Digite uma senha segura” goodLabel=”Boa”  weakLabel=”Razoável” strongLabel=”Excelente” /> –> Esse componente é muito bom, o objetivo é fazer com que o usuário informe uma senha segura em sistema que possui controle de acesso por senha. O atributo minLength espera qual o tamanho minino para uma boa senha. No atributo prompLabel informamos a mensagem exibida quando o campo ganha foco. No atributo goodLabel informamos uma mensagem que será exibida quando a senha digita for avaliada como boa, no atributo weakLabel a mensagem quando a senha for razoavelmente boa e em strongLabel a mensagem quando a senha for considerada dificil.

Para testar os componentes descrito acima vamos alterar nosso arquivo index.xhtml e deixa-lo conforme mostrado abaixo:


<?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://java.sun.com/jsf/html"

xmlns:p="http://primefaces.prime.com.tr/ui">

<h:head>

<title>Facelet Title</title>

</h:head>

<h:body>

<h:panelGrid>

<p:messages />

<h:form>

<p:panel closable="true" footer="Cadastro" header="Cadastro de Alunos" style="width: 350PX">

<h:panelGrid columns="2">

<h:outputLabel value="Matricula:"/>

<h:inputText id="matricula" required="true" requiredMessage="Campo [Matricula] obrigatório"/>

<h:outputLabel value="Nome Completo:"/>

<h:inputText id="nome" required="true" requiredMessage="Campo [Nome Completo] obrigatório"/>

<h:outputLabel value="Nome p/ Login:"/>

<h:inputText id="login" required="true" requiredMessage="Campo [Nome p/ login] obrigatório"/>

<h:outputLabel value="Senha:"/>

<p:password minLength="6" promptLabel="Digite uma senha segura"

goodLabel="Boa"

weakLabel="Razoável"

strongLabel="Excelente" />

<h:commandButton value="Cadastrar" />

</h:panelGrid>

</p:panel>

</h:form>

</h:panelGrid>

</h:body>

</html>

Podemos visualizar nossa aplicação pressionando a tecla F6. Abaixo uma imagem que exibe nossa aplicação após o botão cadastrar ser pressionado sem informar os campos obrigatórios. O campos obrigatórios no formulario são aqueles marcados com atributo required=”true”.

Aplicação em execução

Pronto esse é o resultado do que foi descrito acima. Observe que não tivemos que fazer nenhuma configuração em nem um arquivo xml, isso porque o servlet do primefaces é registrado dinamicamente.

Em um post seguinte vou mostrar outros componentes interessantes desse excelente framework.

Para conhecimento eu deixo aqui alguns links sobre o assunto:

http://blog.gilliard.eti.br/2009/10/mojarra-jsf-ri-2-0-disponivel/ –> Gilliard Cordeiro

http://www.rponte.com.br/ –> Rafael Pontes

Esses caras aí são referencia nacional no assunto, sabem muito.

espero que gostem e até a próxima.

Categorias:Frameworks, Java, JSF 2.0, JSP, Servlet

Palestra Desenvolvimento Web com JSF

Recentemente fiz duas apresentações sobre o assunto em algumas faculdade aqui da cidade, no IFPI e na FAETE. A pedido dos alunos abaixo deixo a apresentação.

Desenvolvimento WEB

Categorias:Frameworks, Java, JSF 2.0, JSP, Servlet

Introdução à JPA com Hibernate

Pessoal, desculpa pelo longo tempo sem fazer nenhum post aqui no blog. Esses dias eu andava ocupadíssimo escrevendo um pré-projeto para participar de uma seleção de mestrado da UFPE, graças a Deus que deu certo :).

Voltando aos posts, hoje eu vou escrever um post que prometi para alguns alunos que me indagaram esses dias sobre JPA e Hibernate.

Introdução ao Hibernate

Para quem ainda não sabe o hibernate é uma ferramenta de ORM, Object Relational Mapping (Mapeamento objeto relacional) que foi desenvolvido por Gave King e hoje faz parte da corporação Red Hat, juntamente com o JBoss. Uma ferramenta de mapeamento Objeto relacional como o Hibernate, TopLink, JDO  tem como objetivo facilitar o trabalho do desenvolvedor no que diz respeito ao relacionamento entre uma aplicação java orientada a objeto e um banco de dados relacional. A idéia principal é criar uma camada entre a aplicação e o banco de dados de modo que o desenvolvedor não tenha que se preocupar com instruções SQL ou com o banco de dados na qual a aplicação irá persistir seus dados, algo que não é feito utilizando só JDBC.

Anotações e JPA

Fazer mapeamento no hibernate era um tanto trabalho até a chegada do Java 5 que trouxe as fabulosas anotações. Antes tudo era configurado em arquivos XML, mas agora tudo ficou bem mais simples com o uso das anotações.

O hibernate se tornou de fato a ferramenta ORM  mais utilizada no mundo e uma prova disso foi o convite da Sun Microsystems para o Gavin King escrever a especificação JPA (Java Persistence API). Agora o java possui uma especificação para ORM.

Estudo de Caso

Para demonstrar o básico do hibernate vamos criar um pequeno sistema de gerencia de projetos contendo as seguintes entidades: Projeto, Atividade e Responsavel. Para esse projeto vamos utilizar o Netbeans IDE 6.8, banco de dados MySQL e o Hibernate 3.x . Em um outro post vamos utilizar JSF 2.0 para colocar nosso projeto na web e aproveitar para conhecer as novidades desse magnifico framework na JEE6.

Criando novo Projeto e Configurando o hibernate.

Com o Netbeans aberto cri um novo projeto aplicativo java( Arquivo -> Novo Projeto -> Java -> Aplicativo Java) e chame-o de exemplo_hibernate.

Vamo agora preparar nosso projeto para utilizar o hibernate. A primeria coisa a ser feita é adicinar as bibliotecas do hibernate no nosso projeto, para fazer isso clique com o botão direito sobre a pasta bibliotecas e escolha a opção Adicionar Biblioteca. Na tela que se abrir procure por Hibernate JPA e depois clique em adicionar, a partir desse momento nosso projetojá possui todas as bibliotecas que precisamos para trabalhar com o hibernate.

Uma outra biblioteca deve ser adicionada, essa corresponde ao driver JDBC do banco que vamos utilizar para o nosso exemplo, nesse caso o driver do MySQL. O procedimento é semelhante ao descrito acima, o nome da biblioteca a ser adicionada é MySQL JDBC Driver.

Depois de ter adicionado nossas bibliotecas, vamos adicionar três pacotes no nossso pacote de código fonte:

conf -> pacote onde vamos colocar o arquivo de configuração do hibernate

modelos – > pacote onde vamos coloca nossas classes de domínio (Projeto, Atividade e Responsavel)

testes -> pacote onde vamos colocar as classes que vamos utilizar para fazer nossos testes.

utils -> pacote onde vamos colocaralgumas classes utilitarias.

Para adicionar um pacote siaga: botão direito em cima da pasta pacotes de código fonte -> Novo -> Pacote Java

Vamos adicionar no pacote conf o arquivo de configuração do hibernate, o hibernate.cfg.xml, clique com o botão direito do mouse sobre o pacote conf e escolha a opção novo. Na tela que abrir escolha, no lado categorias a opção Hibernate e do lado direito escolha a opção Assistente Para configuração do Hibernate, conforme imagem abaixo:

Criando arquivo de configuração do Hibernate

Clicando no botão próximo o assistente solicita o nome arquivo, vamos deixar com estar. Observe o campo pasta, provavelmente ele deve está com o src, vamos subistituir por src/conf, porque nós queremos que nosso arquivo fique no pacote conf.

Na próxima tela ele pede que seja informado uma conexão com alguma fonte de dados, essa conexão pode ter sido criada anteriomente, mas nós vamos criar uma nova conexão. Então escolhano combobox a opção Nova Conexão com Banco de Dados, uma tela semelhante a exibida abaixo deverá aparecer:

Nova Conexão

Configuração da Nova conexão com o bando de dados

Algumas informações importantes dessa última tela:

Nome do Driver: Informação do Driver JDBC do banco que gostariamos de nos conectar. No nosso caso, vamos escolher MySQL

Host: Máquina onde nosso banco de dados está instalado e esperando por conexão, vamos informar localhost para dizer que o banco está instalado na nossa própria máquina.

Porta: Informação sobre qual porta o mysql está escutando, aguardando por conexão, se nenhuma porta é informada é utilizada a porta padrão a 3306.

Banco de Dados: Nome da nossa fonte de dados, onde nossas tabelas serão criadas. Caso ainda não tenha criado seu banco faço isso agora usando o seu mysql. Vamos chamar nosso banco de dados de projectdb

Nome Usuário: Nome do usuário usado para acessar seu banco de dados, vamos usar o usuário administrador que no mysql é o usuario root.

Senha: Informe a senha usada para acessar o banco de dados.

Pronto,  feito isso pode-se clicar em OK.  Se tudo estiver certo o assistente vai retornar para a tela anterior e nossa conexão vai está criada. Já podemos finalizar o assistente. Nossa arquivo irá aparecer dentro do nosso pacote conf e será automaticamente aberto pela nossa IDE, na visualização existem duas opções de exibição: XML e Projeto, a primeira exibe o xml corresponde e a outra dá a possibilidade de fazermos tudo visualmente.

Vamos fazer uma alteração na configuração atual do hibernate, vamos fazer com que seja exibido no console toda e qualquer instrução enviada para o banco de dados. Na janela de configuração do arquivo vamos selecionar a opção Propriedades Opcionais -> Propriedades de Configurar -> Adicionar, conforme imagem abaixo:

Adicionando a propriedade adicional

Na janela que se abrir escolha a opção hibernate.show_sql e campo digite true. Pronto está configurado.

Vamos adicionar nossa primeira entidade no nosso pacote modelos. Vamos escrever a entidade Responsavel. Clicando com o botão direito do mouse escolha a opção Novo -> Classe Java. Nossa classe ficará igual ao trecho abaixo:

package modelos;

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

/**
 * criando em 21/03/2010
 * @author wagner
 */
@Entity
public class Responsavel implements Serializable {

 @Id
 @GeneratedValue
 private long id;
 private String matricula;
 private String nome;

 public long getId() {
 return id;
 }

 public void setId(long id) {
 this.id = id;
 }

 public String getMatricula() {
 return matricula;
 }

 public void setMatricula(String matricula) {
 this.matricula = matricula;
 }

 public String getNome() {
 return nome;
 }

 public void setNome(String nome) {
 this.nome = nome;
 }
}

A classe acima merece alguns destaques. Nossa classe já se encontra devidamente anotada com as anotações da JPA. É importante observar que os imports feitos, foram todos do pacote javax.persitence e não do pacote do hibernate, isso porque nós queremos seguir a especificação e não apenas usar o hibernate de forma pura. Detalhando as anotações:

@Entity -> Informa que nossa classe é uma entidade e que seus objetos serão persistido em banco de dados.

@Id -> Informa o atributo que será nossa chave primaria.

@GeneratedValue -> Informa que o valor desse atributo será gerado automaticamente.

Observe que em nenhum momento fizemos referencia à nenhum nome de tabela ou coluna do banco de dados, isso porque estamos convencionando que o nome da tabela será o mesmo nome da classe e que o nome das colunas será o mesmo nome dos atributos. Caso quisessemos fazer isso deuma forma diferente poderiamos utilizar a anotação @Table(name=”nome_tabela”) para informa o nome da tabela com a qual nossa entidade seria mapeada. E também poderíamos utilziar @Column(“nome_coluna”) para informa nomes diferente para nossas colunas da tabela.

Vamos agora informar para o hibernate a localização da classe Responsavel para que ele possa reconhecer como uma entidade mapeada. Para isso vamos abrir nosso arquivo hibernate.cfg.xml e na opção mapeamentos vamos adicionar nossa classe. Veja Imagens abaixo:

Adicionando a entidade Responsavel no mapeamento

Adicionando a entidade Responsavel

Próximo passo é criar uma classe que leia nossa configuração e gere nosso banco de dados. Vamos criar uma classe chamada de GerarBancoDeDados no pacote utils, a classe em questão é exibida logo abaixo com os devidos comentários.

package utils;

import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.tool.hbm2ddl.SchemaExport;

/**
 * criando em 21/03/2010
 * @author wagner
 **/
public class GerarBancoDeDados {
 public static void main(String...args) {
 /**
 * A classe AnnotarionConfiguration é classe responsavel por ler nosso arquivo
 * hibernate.cfg.xml e reconhecer nossas entidades mapeadas.
 **/
 AnnotationConfiguration configuration = new AnnotationConfiguration();
 /**
 * o método configure é um método sobrecarregado, e em uma de suas sobrecargas
 * ele solicita o caminho do arquivo hibernate.cfg.xml. Caso o arquivo
 * não esteja em um pacote diferente do pacote desta classe, não seria necessario
 * informa o arquivo. Simplesmente chamariamos configuration.configure().
 **/
 configuration.configure("conf/hibernate.cfg.xml");
 SchemaExport export = new SchemaExport(configuration);
 /**
 * 0o método create espera dois argumento booleanos. O primeira informa
 * se queremos que ele exiba o script sql gerado. O segundo se queremos
 * que ele execute diretamente as instruções no banco de dados.
 * Vamos colocar ambos o paramentros true, para exibir o sql e executar
 * o mesmono banco de dados.
 **/
 export.create(true, true);
 }

}

Bom, se tudo estiver bem configurado e você não tiver esquecido nenhum detalhe, o hibernate gerou para você a tabela responsavel em seu banco de dados. Você pode contastar isso abrindo seu banco de dados ou simplesmente olhando o log gerado pelo hibernate na saída padrão (console), vocë deve ver algo parecido com isso:

...
INFO: connection properties: {user=root, password=****}
drop table if exists Responsavel
create table Responsavel (id bigint not null auto_increment, matricula varchar(255), nome varchar(255), primary key (id))
21/03/2010 14:35:07 org.hibernate.tool.hbm2ddl.SchemaExport execute
INFO: schema export complete
21/03/2010 14:35:07 org.hibernate.connection.DriverManagerConnectionProvider close
INFO: cleaning up connection pool: jdbc:mysql://localhost/projectdb
...

Com a tebela criada agora podemos fazer alguns testes. Mas antes disso vamos criar uma classe chamada de HibernateUtils, essa classe tem como finalidade funcionar como uma fábrica de sessões do hibernate para nós. Vamos adicionar essa classe no nosso pacote utils e ela tem a aparência da classe abaixo:

package utils;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

/**
 * criando em 21/03/2010
 * @author wagner
 **/
public class HibernateUtil {
 private static SessionFactory factory;

 /**
 * escopo estático. É a primeira coisa executa em uma classe e só executada
 * apenas uma vez. O bjetivo é carregar nossas configurações do hibernate
 * para que sessões possam ser criadas.
 *
 * O hibernate possui uma classe responsavel por funciona como uma fábrica
 * de sessões é a classe SessionFactory.
 *
 **/
 static {
 AnnotationConfiguration configuration = new AnnotationConfiguration();
 configuration.configure("conf/hibernate.cfg.xml");

 factory = configuration.buildSessionFactory();

 }

 /**
 * sempre que quisermos uma session do hibernate apenas chamamos
 * HibernateUtils.getSession();
 * @return
 **/
 public static Session getSession(){
 return factory.openSession();
 }

}

Esse procedimento para se obter uma sessão do hibernate, agora imagina ter que fazer isso sempre precisassemos de uma sessão! Por isso que escrevemos a classe HibernateUtils e adicionamos o método getSeesion(). Agora é bem simples obter uma sessão do hibernate, basta chama o método estático getSession assim: HibernateUtil.getSession().

Vamos agora fazer alguns testes com nossa entidade Responsavel. Para isso vamos criar uma nova classe no pacote testes chamada de TestaEntidadeResponsavel. O primeiro teste que vamos fazer é verificar se nossos objetos realmente estão sendo persistindo (armaezados) no nosso banco de dados. Nossa classe vai ter aparencia da classe abaixo:

package testes;

import modelos.Responsavel;
import org.hibernate.Session;
import utils.HibernateUtil;

/**
 * criando em 21/03/2010
 * @author wagner
 **/
public class TestaEntidadeResponsavel {
 public static void main(String...args) {
 /**
 * Solicitando uma sessão para nossa fábrica de sessões.
 **/
 Session session = HibernateUtil.getSession();
 /**
 * Criando um objeto da nossa entidade que será salvo no banco
 **/

 Responsavel responsavel = new Responsavel();
 responsavel.setMatricula("AM-123");
 responsavel.setNome("Wagner Borges");

 /**
 * Iniciando uma transação com o banco de dados
 **/
 session.getTransaction().begin();
 /**
 * chamando o método save do hibernate para persistir nosso objeto
 **/
 session.save(responsavel);
 /**
 * encerrando e comitando nossa transação
 **/
 session.getTransaction().commit();
 }
}

É simples assim mesmo. Dessa forma acabamos de fazer um insert na nossa tabela responsavel. Para constatar isso veja seu banco de dados e dê select em sua tabela. Ou simplesmente veja o log gerado na saída padrão, você deve ver algo mais ou menos assim:

...
INFO: building session factory
21/03/2010 15:08:36 org.hibernate.impl.SessionFactoryObjectFactory addInstance
INFO: Not binding factory to JNDI, no JNDI name configured
Hibernate: insert into Responsavel (matricula, nome) values (?, ?)
...

Utilizando a mesma classe poderíamos recuperar o objetos Responsavel cojo ID seja igual 1 de nosso banco de dados, assim:

...
Responsavel resp = (Responsavel) session.load(Responsavel.class, 1L);
System.out.println("Nome: " + resp.getNome());
...

Bom pessoal, pra começar já esta bom. Isso foi bem pouco do que realmente o hibernate pode fazer. No próximo post vamos falar um pouco de DAO, Generic DAO, Criteria API. Um abraço a todos e espero que ajude alguém com esse post. 🙂