I’m big fan of JRuby. The Ruby language’s flexibility with the JVM’s power give to us a big weapon to create amazing applications. 

http://www.jruby.org/2013/01/04/jruby-1-7-2.html

Durante esse feriado de natal, estive testando o suporte a JRuby no Google App Engine. Conseguir rodar tanto uma aplicação feita com Sinatra quanto uma feita em Rails 2.3.10. Infelizmente a gem google-appengine ainda não suporta o Rails 3, mas esse suporte já está sendo desenvolvido.

Então pesquisando no Github achei um gist mostrando como gerar uma aplicação com Rails 2.3.10 e DataMapper, infelizmente não funcionou como deveria. Mas ao analisar percebi que o problema era não está incluindo o DataMapper::Resource no model, então fiz um fork do gist e modifiquei, testei e agora tudo está funcionando. Para acessar o gist clique aqui e divirta-se.

Esse é o primeiro post de uma séria voltada para como melhorar o desempenho de seu site/sistema web. Hoje em dia, trabalhar com desenvolvimento web envolve vários fatores. Um deles é o desempenho, desenvolver um sistema/site que tenha uma performance boa também envolve diversos aspectos. Existem algumas extensões para o firefox capaz de testar o desempenho da sua camada de visão, são eles o yslow do Yahoo! e o Page Speed do Google. Ambos tem basicamente as mesmas funcionalidades, que no geral se resume a testar a performance da sua camada de visão e lhe dá dicas de como melhora-las. Ele lhe avisa, por exemplo, quando você tem uma imagem grande e está reduzindo sua visualização no html ou css. Dentre outras coisas, tais como: habilitar a compressão GZIP, diminuir o tamanho dos cookies, habilitar o cache para determinadas áreas/arquivos. Enfim, é uma extensão super simples de usar e que não pode faltar a um Desenvolvedor web.

Um das principais fontes de dúvida para quem está começando a aprender JSF é o componente SelectOneMenu. Basta uma simples garimpada no google e você confirmará isso. Diversas soluções para o uso do SelectOneMenu são indicadas, uma das que mais vejo é utilizar um converter para converter o objeto selecionada na SelectOneMenu no objeto desejado. Porém eu prefiro uma maneira que acho mais simples, que irei mostrar a seguir. No nosso exemplo, terei um objeto do tipo “Classe” que representará uma classe de alunos, cada classe contem um objeto do tipo “Professor”. Ao cadastrar uma classe o usuário deverá selecionar o professor em uma determinada lista. Então vamos lá: Teremos um backing bean chamado ClasseBean que conterá uma objeto do tipo classe.

public class ClasseBean {

    private Classe classe;
    private ClasseDao classeDao;
    private List<SelectItem> listaItem;
    private int professorSelecionado;

public ClasseBean() {
        classe = new Classe();
        classeDao = new ClasseDao();
        listaItem = getLista();
    }

 public List<SelectItem> getLista() {
        ArrayList<SelectItem> lista = new ArrayList<SelectItem>();
	ProfessorDao professorDao = new ProfessorDao();
        List<Professor> resultado = (List<Professor>) professorDao.listAll();

        for (Professor teste : resultado) {
            SelectItem item = new SelectItem(teste.getId(), teste.getNome());
            lista.add(item);
        }
        return lista;
    }

 public String salvar() {

	 ProfessorDao professorDao = new ProfessorDao();
         professor = professorDao.procurar(professorSelecionado);
         this.classe.setProfessor(professor);
         classeDao.salvar(classe);

        classe = new Classe();
        return "listarClasses";
    }

	//métodos getters e setters omitidos

}
No exemplos não irei me apegar a camada de persistência, devendo essa ter sido criada previamente pelo programador e conter os métodos de busca pelo ID e buscar todos os registros. Iremos começar pelo método getLista(), nesse método é criado uma lista de SelectItem que será usada como exibição, os objetos SelectItem recebem como parametro no construtor dois atributos, o primeiro é a chave do selectItem (que será igual ao id do professor) e o valor de exibição (que no nosso caso será o nome do professor). Já o método salvar() utilizar o ProfessorDao para efetuar uma busca através do atributo professorSelecionado (o valor desse atributo será igual a chave do item escolhido no SelectOneMenu, que no nosso caso será o id do professor. Lembra-se do: “SelectItem item = new SelectItem(teste.getId(), teste.getNome());” ) após isso o atributo professor do objeto Classe é setado e o o objeto é persistido. Agora iremos para a criação da página jsf:
<h:selectOneMenu value="#{classeBean.professorSelecionado}">
classeBean.listaItem}">
                            <f:selectItems value="#{classeBean.listaItem}"/>
</h:selectOneMenu>
O atributo value do SelectOneMenu recebe como parametro o atributo que receberá o valor da chave do atributo selecionado da lista. E utilizamos o selectItems para informar em qual atributo está a lista de SelectItem’s a ser exibida.

Esse post faz parte de uma série que estou preparando sobre o hibernate, o primeiro foi sobre a extensão especial Hibernate Spatial e esse segundo irei falar sobre um pouco sobre um poderoso recurso do Hibernate, a API Criteria. Nesse tutorial não irei entrar em detalhes sobre configuração do Hibernate, assume-se que você tem o hibernate pré-configurado, irei apenas falar da API. Primeiro criaremos nossa entidade exemplo “Cliente” :


package modelo;

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

/**
 *
 * @author lucas
 */
@Entity
public class Cliente implements Serializable {

    @Id
    @GeneratedValue
    private int id;
    private String nome;
    private int idade;
    private String cpf;
    private double saldo;

    public String getCpf() {
        return cpf;
    }

    public int getIdade() {
        return idade;
    }

    public void setIdade(int idade) {
        this.idade = idade;
    }

    public void setCpf(String cpf) {
        this.cpf = cpf;
    }

    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;
    }

    public double getSaldo() {
        return saldo;
    }

    public void setSaldo(double saldo) {
        this.saldo = saldo;
    }
}

Até aqui nada de novo, marcamos a classe com a anotação @Entity, para indicar que é uma entidade e marcamos o atributo id com as anotações @Id e @GeneratedValue, a primeira diz que esse atributo é a chave primaria e segunda que seu valor será gerado automaticamente. O cliente também tem um atributo saldo, que representará um valor de saldo, tecnicamente o cliente não deveria possuir um saldo e sim um objeto conta e a conta possuir um saldo, porém como o objetivo desse tutorial é demonstrar a api Criteria, não me apeguei a regras de modelagem OO. Agora criaremos a classe HibernateUtil, que irá conter um método estático que devolve um objeto Session. Com essa classe não precisaremos ficar instanciando o objeto Session toda vez que precisarmos acessar o banco. O próprio netbeans tem um assistente que gera automaticamente essa classe.

package util;


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

/**
 * Hibernate Utility class with a convenient method to get Session object.
 *
 * @author lucas
 */
public class HibernateUtil {
    private static final SessionFactory sessionFactory;

    static {
        try {
            sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static Session getSession() {
        return sessionFactory.openSession();
    }
}
Agora criaremos um Dao genérico com os métodos padrão em todos os DAO’s, evitando assim o trabalho de implementar os mesmos métodos em todos os DAO’s.

package Dao;

import org.hibernate.Session;
import org.hibernate.Transaction;
import util.HibernateUtil;

/**
 *
 * @author lucas
 */
public class Dao<T> {

    private Class classe;
    private Session session;

    protected Session getSession() {
        return session;
    }


    public Dao(Class classe) {
        this.session = HibernateUtil.getSession();
        this.classe = classe;
    }

    public void salvar(T objeto){
        session.save(objeto);
    }

    public void remover(T objeto){
        Transaction ts = session.beginTransaction();
        session.save(objeto);
        ts.commit();
    }

    public void atualizar(T objeto){
        Transaction ts = session.beginTransaction();
        session.update(objeto);
        ts.commit();
    }

    public T load(long id){
        return (T) session.load(classe, id);
    }
}
Utilizamos na declaração da classe o tipo parametrizado T (de type), indicando que essa classe terá um tipo de Objeto. No seu construtor, ela receberá um objeto que definirá o tipo usado na classe e utiliza o HibernateUtil para receber uma session. Observe que o método getSession() do Dao genérico é protected pois suas classes filhas precisarão acessa-lo para seus próprios métodos. Agora criaremos o ClienteDao, que herdará todos os métodos do Dao genérico, sendo assim não será necessário criar os métodos básicos (Salvar, Atualzar, Remover e Carregar).

package Dao;

import java.util.Collection;
import modelo.Cliente;
import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

/**
 *
 * @author lucas
 */
public class ClienteDao extends Dao<Cliente> {


    public ClienteDao(){
        super(Cliente.class);
    }

    public Collection<Cliente> buscaPorNome(String nome){
        Criteria c = getSession().createCriteria(Cliente.class);
        c.add(Restrictions.ilike("nome", nome));
        c.addOrder(Order.asc("idade"));
        return c.list();
    }

    public int qtdeTotalCliente(){
        Criteria c = getSession().createCriteria(Cliente.class);
        c.setProjection(Projections.rowCount());
        return (Integer) c.uniqueResult();
    }

    public int totalSaldo(){
        Criteria c = getSession().createCriteria(Cliente.class);
        c.setProjection(Projections.sum("saldo"));
        return (Integer) c.uniqueResult();
    }
}
Agora conheceremos o poder da API Criteria. No método buscaPorNome, é recebido como parametro uma String que representa o nome do Cliente a ser buscado. Em seguida é criado o objeto Criteria, através do método createCriteria() e esse recebe como argumento o tipo de objeto a ser pesquisado, como o objeto está mapeado para uma tabela do banco (eu não demonstrei aqui como mapear, porque como disse não é o objetivo do artigo) a API Criteria já sabe exatamente em qual(is) tabela(s) buscar. Na linha seguinte utilizamos o método add() para refirnarmos a busca, no nosso caso adicionamos uma restrição através do ilike() do objeto Restrictions e passamos dois parâmetros o primeiro é o campo que será aplicada a restrição e o segundo o valor da restrição. Então no nosso caso informamos que queremos apenas os registros com o campo nome igual ao valor da variável nome. Para melhorar ainda mais a busca, podemos definir a ordem que os objetos será apresentados. Para isso na linha seguinte usamos o método addOrder() e usamos o objeto Order para definir a ordem, que no nosso caso será o campo idade. Na linha seguinte é usado o método list() que retorna uma lista de objetos que se encaixa no perfil informado ou null caso não encontre nada. No método qtdeTotalCliente() é retornado um inteiro com a quantidade total de registro de Clientes salvos no banco. Para isso é utilizado o método setProjection e é passado como parâmetro o que queremos fazer, no caso utilizamos o método rowCount() do Projections para contar a quantidade de registros. Para finalizar usamos o uniqueResult() para retornar a quantidade de registros. E para finalizar o artigo, no totalSaldo() estamos utilizando também o setProjection para somar os valores de um determinado campo de todos os registros do banco, para isso utilizamos o método sum() do objeto Projections Bom, no geral é isso. A API Criteria é muito poderosa, podemos ser utilizada para realizar (quase) todas as queries que você desejar, porém muita gente acha mais rápido e produtivo escrever as queries utilizando a HQL (Hibernate Querie Language) que irei mostrar no próximo artigo.

Esse tutorial tem como objetivo fazer uma introdução ao uso do Hibernate Spatial juntamente com o banco de dados postgresql e a extensão espacial postgis. Nesse exemplo estarei utilizando o netbeans 6.8. Para começar, crie um projeto Java no netbeans, clique com o botão direito sobre o projeto e adicione as bibliotecas do “Hibernate” e “Hibernate JPA” ambas disponíveis no netbeans. Você também irá precisar das seguintes bibliotecas:

Adicione todas as listadas acima ao projeto. Agora iremos criar o hibernate.cfg.xml, o próprio netbeans fornece um utilitário para criação. Clique com o botão direito no projeto, selecione o menu Novo -> Outro -> Hibernate -> Assistente para configuração do hibernate. Configure seu hibernate da seguinte maneira: [sourcecode language=”xml”] <?xml version=”1.0” encoding=”UTF-8”?> <!DOCTYPE hibernate-configuration PUBLIC “-//Hibernate/Hibernate Configuration DTD 3.0//EN” “http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd”> <hibernate-configuration> <session-factory> <property name=”hibernate.dialect”>org.hibernate.dialect.PostgreSQLDialect</property> <property name=”hibernate.connection.driver_class”>org.postgresql.Driver</property> <property name=”hibernate.connection.url”>jdbc:postgresql://localhost/teste</property> <property name=”hibernate.connection.username”>postgres</property> <property name=”hibernate.connection.password”>web</property> <property name=”hibernate.show_sql”>true</property> <property name=”hibernate.format_sql”>true</property> <mapping class=”modelo.Evento”/> </session-factory> </hibernate-configuration> [/sourcecode] Agora iremos criar a classe “Eventos” que será nossa entidade. Ela irá conter o atributo Id que será um inteiro, descrição que será uma string contendo a descrição e o atributo ponto que será do tipo geográfico “Point”. [sourcecode language=”java”] package modelo; import com.vividsolutions.jts.geom.Point; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import org.hibernate.annotations.Type; /** * * @author lucas */ @Entity public class Evento implements Serializable { @Id @GeneratedValue private long id; private String descricao; @Type(type=”org.hibernatespatial.GeometryUserType”) @Column(columnDefinition=”Point”) private Point ponto; public String getDescricao() { return descricao; } public void setDescricao(String descricao) { this.descricao = descricao; } public long getId() { return id; } public void setId(long id) { this.id = id; } public Point getPonto() { return ponto; } public void setPonto(Point ponto) { this.ponto = ponto; } } [/sourcecode] Agora criaremos a classe HibernateUtil, que possuirá um atributo SessionFactory do hibernate, um método que retorne uma Session criada pelo SessionFactory e um bloco de código, todos estáticos. O próprio netbeans possui uma opção de criar automaticamente o HibernateUtil, ela está no mesmo menu que foi usado anteriormente para gerar o arquivo de configuração. [sourcecode language=”java”] package util; import org.hibernate.Session; import org.hibernate.cfg.AnnotationConfiguration; import org.hibernate.SessionFactory; public class HibernateUtil { private static final SessionFactory sessionFactory; static { try { sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory(); } catch (Throwable ex) { throw new ExceptionInInitializerError(ex); } } public static Session getSession() { return sessionFactory.openSession(); } } [/sourcecode] Criaremos agora a classe que irá ler a configuração do hibernate e a partir dos mapeamentos das classes irá gerar automaticamente as tabelas do banco. [sourcecode language=”java”] package util; import org.hibernate.cfg.AnnotationConfiguration; import org.hibernate.cfg.Configuration; import org.hibernate.tool.hbm2ddl.SchemaExport; /** * * @author lucas */ public class GeraBanco { public static void main(String args[]){ Configuration conf = new AnnotationConfiguration(); conf.configure(); SchemaExport se = new SchemaExport(conf); se.create(true, true); } } [/sourcecode] O próximo passo é mapear a entidade Evento no hibernate, para isso adicionaremos abaixo do último ‘property’ a linha a seguir: [sourcecode language=”xml”] <mapping class=”modelo.Evento”/> [/sourcecode] Deixando o hibernate.cfg.xml da seguinte maneira: [sourcecode language=”xml”] <?xml version=”1.0” encoding=”UTF-8”?> <!DOCTYPE hibernate-configuration PUBLIC “-//Hibernate/Hibernate Configuration DTD 3.0//EN” “http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd”> <hibernate-configuration> <session-factory> <property name=”hibernate.dialect”>org.hibernate.dialect.PostgreSQLDialect</property> <property name=”hibernate.connection.driver_class”>org.postgresql.Driver</property> <property name=”hibernate.connection.url”>jdbc:postgresql://localhost/teste</property> <property name=”hibernate.connection.username”>postgres</property> <property name=”hibernate.connection.password”>web</property> <property name=”hibernate.show_sql”>true</property> <property name=”hibernate.format_sql”>true</property> <mapping class=”modelo.Evento”/> </session-factory> </hibernate-configuration> [/sourcecode] E por fim iremos trabalhar na classe main: [sourcecode language=”java”] import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.Point; import modelo.Evento; import org.hibernate.Session; import org.hibernate.Transaction; import util.HibernateUtil; /** * * @author lucas */ public class Main { public static void main(String[] args) { Evento evento = new Evento(); evento.setDescricao(“Testando”); Geometry geom = null; evento.setPonto((Point) geom); Session session = HibernateUtil.getSession(); Transaction tx = session.beginTransaction(); session.save(evento); tx.commit(); session.close(); } } [/sourcecode] Agora rode o GeraBanco para que a tabela do banco seja criada e em seguinda o main. Após fazer isso dê uma conferida no banco e se tiver ocorrido tudo bem o registro estará lá.

Excelente video tutorial feito pela própria equipe do GeoServer para quem está começando. Mostra como configurar o GeoServer para trabalhar com os Shapefile.

Introdução ao GeoServer

O Hibernate Spatial é uma extensão do famoso framework de persistência Hibernate. Ele faz o mapeamento objeto relacional de tipos de dados geográficos. Para quem trabalha com desenvolvimento de SIG é uma excelente idéia dá uma conferida.
Ele suporta a maioria das funções da OGC (Open Geospatial Consortium) além de suportar também os SGBD Oracle 10g/11g, Postgresql/Postgis, and MySQL.

O site oficial é http://www.hibernatespatial.org/ e para quem trabalha com a plataforma .NET NHibernate

Uma coisa que sempre gosto de fazer quando estou programando usando JSF, é criar uma classe mensageira para facilitar o trabalho com mensagens (de erro, informação e etc..).

Essa classe, me livra do trabalho de:

  • Obter repetidamente o FacesContext.
  • Criar repetidamente o objeto FacesMessage.
  • Escrever repetidamente as mensagens.
Pode parecer pouco, mas imagina você ter que repetir isso todas as vezes que precisar adicionar uma mensagem para o usuário. Segue abaixo a implementação:
package lucasallan.com.blog.exemplo import java.util.ResourceBundle; import javax.faces.application.FacesMessage; import javax.faces.context.FacesContext; /** * * @author Lucas Allan Cardoso */ public class Mensageiro {

private static ResourceBundle bundle = ResourceBundle.getBundle(“messages”, FacesContext.

getCurrentInstance().getViewRoot().getLocale());

public static void errorMsg(String msg){

msg = bundle.getString(msg);

FacesMessage fm = new FacesMessage(FacesMessage.SEVERITY_ERROR,msg, msg);

FacesContext fc = FacesContext.getCurrentInstance();

fc.addMessage(“erro”, fm);

}

public static void infoMsg(String msg){

msg = bundle.getString(msg);

FacesMessage fm = new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg);

FacesContext fc = FacesContext.getCurrentInstance();

fc.addMessage(“info”, fm);

} }
Agora criaremos um arquivo chamado “messages.properties” dentro da raiz da aplicação, onde poderemos definir as mensagens da nossa aplicação, bem como chaves para poder utiliza-las. O conteúdo desse arquivo consiste em: chave = valor Exemplo: bdError = Erro ao acessar banco de dados! Quando precisarmos utilizar nosso mensageiro, basta usar: Mensageiro.errorMsg(“bdError”); E nossa classe irá procurar dentro do messages.properties um valor que tenha como chave “bdError”, no nosso exemplo ele adicionaria a mensagem “Erro ao acessar banco de dados!” ao nosso contexto. Bem simples né? Bom, agora iremos entender a nossa classe mensageira:
  1. Primeiro nós temos o objeto estático ResourceBundle que utilizaremos para efetuar as buscas das mensagens através dos valores passado no arquivo messages.properties. Repare que eu passo o nome do arquivo sem a extensão .properties e a localização dele, no nosso caso utilizamos o método getViewRoot do FacesContext para obter a localização. O interessante é que todas essas mensagens possuem suporte a internacionalização, você pode definir dentro do messages.properties mensagens personalizadas para cada locale, por isso utilizamos o método getLocale.
  2. Os métodos: infoMsg e errorMsg são os responsáveis pelas mensagens, recebem como parâmetro uma string, que será utilizada como chave para encontrar o valor da mensagem.
  3. Na linha seguinte ele faz com que a variável ‘msg’ que antes possuía a chave receba como valor a própria mensagem que é buscada através do método getString do objeto ResourceBundle.
  4. Nas próximas linhas não tem muito o que explicar, crio o objeto FacesMessage com a mensagem conseguida anteriormente, obtenho a instancia do FacesContext e adiciona a mensagem.
  5. E fim, você está pronta p usar o seu mensageiro.
Espero que possa ajudar vocês a tornar o desenvolvimento do seus sistemas menos repetitivo e mais divertido. Quem quiser saber mais sobre jsf

Se é boato ou verdade eu não sei, o fato é: o rails vem crescendo de maneira assustadora e é claro que grandes empresas como RedHat, SUN e etc… não iam ficar de fora disso.

Não é atoa que em 2006 a SUN contratou o Charles Nutter e Tom Enebo para colocar pra frente o projeto JRuby, o que deve permitir codigos Ruby serem executados na JVM.

Agora é esperar para ver.

Fonte:

http://blog.seatecnologia.com.br/articles/2008/10/20/jboss-on-rails