Executando expressões lógicas dinâmicas em java

Esses dias me deparei com o seguinte problema: como gerar expressões lógicas a partir de atributos anotados de um objeto como no exemplo abaixo, que são construídas pelo usuário através de uma interface gráfica?

public class Contact {

  @MyAnnotion
  private String name;

  @MyAnnotation(operators={Operator.Equal, Operator.GreaterThan....})
  private Date birthday;

  @MyAnnotion 
  private String address;
 
  @MyAnnotation(operators={Operator.Equal, Operator.GreaterThan....})
  private Integer age;

}

Digamos que queremos construir regras como “nome contains ‘Joao’ AND birthday <= '10/12/2013' OR age < 18", ou seja queremos criar regras para serem aplicadas nos objetos Contacts e selecionar os objetos de acordo com aqueles que atendem a regra ou não. Construir a regra em si não é um grande problema. O desafio está em executar a regra construída obedecendo a precedência dos operadores lógicos, e havendo parênteses, aumenta a complexidade, pois temos que executar os mais internos primeiro.

Uma das soluções, apontada por um amigo meu, é gerar um programa java script e utilizar a engine de script para avaliar a expressão lógica gerada. Por exemplo a expressão “nome igual ‘Eduardo’ and idade > 10” seria traduzido para algo assim:

if('Eduardo' == 'Eduardo' && 30 > 10){ return true; } else { return false; }

Basicamente geramos uma string contendo um código semelhante ao mostrado acima substituindo o campos (nome,idade no exemplo) pelos seus respectivos valores e os operadores pelos seus correspondentes na linguagem javascript.

Abaixo segue o código completo do programa em java, mostrando a solução que adotamos e que funcionou muito bem, muito superior ao que tínhamos antes que gerava um SQL, mas tinha um problema grave, pois quando estamos criando ou editando um objeto ainda não colocamos o objeto (Contact no caso desse artigo) no banco, logo as regras que estão lá não conseguirão ser aplicadas sobre os novos dados. Mas salvar o objeto no banco para poder aplicar as regras e apagá-lo caso, o usuário desista da edição ou criação do novo contato, é um convite para erros de inconsistência no banco. O jeito foi executar as regras sem precisar do banco e essa solução de usar a script engine da JVM caiu como uma luva.

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class ExecutaRegra {
	
	public static void main(String[] args){
		try {
			String expressaoJavascript = "if('Teste'=='Teste1' || 1==0){r=true} else {r=false}";

			ScriptEngineManager mgr = new ScriptEngineManager();
			ScriptEngine jsEngine = mgr.getEngineByName("JavaScript");
			boolean result = (Boolean) jsEngine.eval(expressaoJavascript);
			
			System.out.println("Resultado: " + result);
			
		} catch (ScriptException ex) {
			ex.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} 
	}
}
Advertisements

Creating a REST API in Python using Bottle and MongoDB

A simple example how to implement a REST API with bottle.py

My Adventures in Coding

I have been using Bottle and MongoDB for a REST API project for almost a year now. I frequently get asked the question “Bottle, what is Bottle, I have never heard of it” and “Ok, I have read the Bottle tutorial, it is simple, but how do I use Bottle with MongoDB?”. So I decided to write up a simple “Getting Started” tutorial for my friends curious about these technologies.

Prerequisites: Python 2.7 or higher

Setup MongoDB

MongoDB is a document store, a schema less database. What makes MongoDB unique (and why we decided to use it) is that MongoDB is a hybrid document store. What this means is that MongoDB offers the freedom of storing data in a schema less fashion, while still providing a flexible query syntax that will make anyone familiar with SQL feel comfortable.

You will need to download the latest version of MongoDB from the

View original post 420 more words

Micro web frameworks em Python: experimentando o Bottle.py

Estamos geralmente acostumados a trabalhar com frameworks web complicados, principalmente os desenvolvedores java/JEE, cheios de funcionalidades e opções que muitas vezes, para fazer um aplicativo pequeno, como um blog ou uma lista de tarefas, provocam um desânimo só de pensar em ter que configurar maven, xml’s, properties e por aí vai.

Em outras linguagens como ruby ou python temos frameworks muito fáceis de aprender  como o Ruby on Rails, Django e Web2py (esse último tem conceitos bem interessantes que vou explorar em um post futuro). Mesmo assim, se você ainda quiser uma coisa mais simples por que acha que não precisa de tantas funcionalidades, como aquelas disponíveis no Rails ou o Django, ou ainda, você não quer instalar nada, ter que gerenciar pacotes de pendências e esse tipo de coisa, talvez seja interessante olhar para os micro-frameworks, que oferecem apenas o mínimo necessário para se implementar um aplicativo web.

Nesse post eu descrevo apenas minha experiência com o bottle.py, embora o mesmo valha para outros microframeworks semelhantes, como o flask, tido por alguns como o mais completo e com mais suporte da comunidade.

O framework bottle pode ser usado como um módulo python sem dependências adicionais. Inclusive, você pode baixá-lo do site e incluir no seu projeto facilmente por que ele é constituído de apenas um arquivo. Ele implementa o padrão WSGI e suporta roteamento, templates de views, upload de arquivos, cookies e inclusive websockets. Também conta com a possibilidade do uso de plugins de terceiros.

O famoso hello world é mostrado no código abaixo:


from bottle import route, run, template

@route('/hello/')
def index(name='World'):
  return template('Hello {{name}}!', name=name)

run(host='localhost', port=8080, debug=True)

e reparem na semelhança com o flask:

from flask import Flask
app = Flask(__name__)

@app.route('/';)
def hello():
 return 'Hello World!;

if __name__ == '__main__&quot':
 app.run()

De acordo com o código acima, os decorators do python são utilizados para realizar o mapeando das url’s. Os parâmetros das url’s correspondem aos parâmetros dos métodos decorados, cujo retorno pode apontar para uma template a ser renderizada, um redirecionamento ou um código HTTP. É possível também responder em formato JSON e XML, caso a intenção seja implementar uma API REST.

O bottle possui uma template engine embutida (embora suporte outras mais conhecidas como a jinja2) chamada Simple Template ou stpl muito fácil de aprender. Os parâmetros paras as views são passadas via dicionários como no exemplo abaixo, que retorna uma lista de posts:

@route('/posts')
def posts():
  posts = find_all()
  return template('index', dict(posts=posts))

Nas linhas abaixo, segui o mesmo exemplo de primeiro projeto quando somos apresentados ao rails, a implementação de um blog. O código completo está disponível no github nesse link.

Começamos pelo modelo de Post, bem simples, que terá um título, uma data e um conteúdo. Aproveitando que estava aprendendo um pouco de python e bottle, inclui mais um framework, de ORM, na brincadeira, para mapear o objeto Post para a camada de persistência. Resolvi utilizar o SQLAlchemy que parece ser o mais recomendado de acordo com o site stackoverflow. Abaixo temos o nosso modelo de Post:


from sqlalchemy.engine import create_engine
from sqlalchemy.ext.declarative.api import declarative_base
from sqlalchemy.schema import Column, Sequence
from sqlalchemy.types import Integer, String, DateTime

#definicao do banco de dados
DATABASE='sqlite:///blog.db';
engine = create_engine(DATABASE, echo=True)
BASE = declarative_base(engine)

class Post(BASE):
   '''modelo de post'''
   __tablename__ = 'posts'
   id = Column(Integer, Sequence('post_id_seq'), primary_key=True)
   title = Column(String(250))
   content = Column(String())
   date=Column(DateTime())

def __init__(self, title, content, date):
   self.title = title
   self.content = content
   self.date = date

def __repr__(self):
   return '%s, %s, %s', (self.id, self.title, self.date)

BASE.metadata.create_all(engine)

Em seguida, precisamos implementar um controlador para realizar as operações de criação, edição e exclusão dos posts. Abaixo segue o código:

from model.post import Post, DATABASE
from sqlalchemy.engine import create_engine
from sqlalchemy.orm.session import sessionmaker
from sqlalchemy.sql.expression import desc

def get_connection():
  """
  Connect to our SQLite database and return a Session object
  """
  engine = create_engine(DATABASE, echo=True)
  Session = sessionmaker(bind=engine)
  session = Session()
  return session

def save(post):
  if post.title != '' and post.title != None:
   session = get_connection()
   session.add(post)
   session.commit()
   session.close()
  else:
   raise Exception(u'Title cannot be empty')

def update_post(post):
  if post:
    session = get_connection()
    session.query(Post).filter(Post.id == post.id).update({'title':post.title, \
    'date':post.date, 'content':post.content})
    session.commit()
    session.close()

def delete_post(post):
  if post:
   session = get_connection()
   session.delete(post)
   session.commit()
   session.close()

def find_by_id(id):
  session = get_connection()
  post = session.query(Post).filter(Post.id==id).first()
  session.close()
  return post

def find_all():
  session = get_connection()
  posts = session.query(Post).order_by(desc(Post.date))
  session.close()
  return posts

Agora que temos nossa camada de persistência e um controlador, vamos a parte que interessa, a implementação da camada web. Praticamente, essa fase corresponde a mapear as url’s que desejamos expôr e fazer as respectivas chamadas para o nosso controlador persistir as mudanças e os posts criados.

No código abaixo temos algumas linhas destacadas que vale a pena explicar. As linhas 8 até 14 definem um método auxiliar para renderizar as views passando seus argumentos, incluindo uma mensagem de erro, pois o bottle não apresenta o flash do rails ou algo parecido (pelo menos não achei nada na documentação).

Também faltam mensagens automáticas de validação em forms tal como ocorre no Rails ou web2py. Mas é uma boa oportunidade para vc aprender a fazer o seu lendo os códigos-fontes de outros frameworks.

Nas linhas 16 a 18 o método send_static é utilizado para servir arquivos estáticos como figuras, css e javascripts, etc. Qualquer link apontando para ‘/assests/js/hello.js’, por exemplo, será mapeado por este método para, o arquivo localizado em views/js/hello.js. Esses paths dependem de onde o programa principal está sendo executado. Maiores detalhes você encontra na documentação do bottle.

Finalmente, nas linhas 79 a 81 definimos um método que será executado sempre que ocorrer o erro 404 do HTTP, de forma a exibir a uma página padrão de erro.

# -*- coding: utf-8 -*-
from bottle import get, post, request, route, run, template, view, redirect, \
static_file, error
from controller.postcontroller import *
from model.post import Post
import datetime

def render_template(args, kwargs=None, error=None, msg_success=None):
 if kwargs == None:
  kwargs = dict()

 kwargs['error']=error
 kwargs['msg_success']=msg_success
 return template(args, kwargs)

@route('/assets/')
def send_static(filename):
 return static_file(filename, root='views')

@route('/posts')
def posts():
  '''Listing of posts'''
  posts = find_all()
  return render_template('index', dict(posts=posts))

@route('/post/')
def get_post(id):
  '''Get post given the id'''
  return 'Not Implemented Yet';

@get('/posts/new')
def new():
  '''create a empty post to fill the new form'''
  today = datetime.date.today()
  return render_template('new', dict(post=Post(None, None, today)))

@post('/post/create')
def create():
  '''Get the attributes from request and create a new post'''
  post = build(request)
  try:
   save(post)
  except Exception as e:
   return render_template('new', dict(post=post), \
   error='Title cannot be empty')
 redirect('/posts')

@get('/posts/edit')
def edit(id):
 if id:
  post = find_by_id(id)
  if post:
    return render_template('edit', dict(post=post))

 posts=find_all()
 return render_template('index', dict(posts=posts), error='Post not found')

@route('/post/update/:id', method='POST')
def update(id):
  if id:
    post = find_by_id(id)

  if post:
    post_from_request = build(request)
    post.title = post_from_request.title
    post.date = post_from_request.date
    post.content = post_from_request.content
    update_post(post)

 posts = find_all()
 return render_template('index', dict(posts=posts), \
                        msg_success='Post edited with success')

@route('/posts/delete/:id', method='POST')
def delete(id):
 post = find_by_id(id)
 delete_post(post)

@error(404)
def error404(error):
  return 'Nothing here, sorry'

def build(request):
 '''
 Extract from the request the parameters to create the new post
 '''
 title = request.forms.get('title')
 content = request.forms.get('content')
 day,month,year = request.forms.get('date').split('/')
 return Post(title, content,  datetime.date(int(year),int(month),int(day)))

if __name__ == '__main__':
 run(host='localhost', port=9090)

Agora, faltam as views, que como dito anteriormente são implementadas com uma engine de template própria do framework. O código abaixo dá uma idéia dessas views. Não listaremos todas elas por questão de espaço. Mas o código completo você pode pegar no github e ver como o código está organizado.

%rebase layout title="New Post"

%if error:
    <div class="alert alert-error">
        {{error}}
    </div>
%end

<form action="/post/create" method="post">
   <fieldset>
     <input id="date" type="text" name="date" 
            value="{{post.date.strftime('%d/%m/%Y')}}" />
     <label for="title">Title</label>
     <input id="title" type="text" name="title" />
     <textarea id="content" cols="400" name="content" rows="10">
        {{post.content or ''}}
     </textarea>
     <button class="btn" type="submit">Submit</button>
   </fieldset>
</form>
<script type="text/javascript">
// <![CDATA[
$(function(){   
  $( "#date" ).datepicker({dateFormat:'dd/mm/yy'});   
});
// ]]>
</script>

No código acima, na linha 1 indica um layout padrão a ser renderizado junto com a view evitando repetição de código entre várias páginas. E, nas linhas 3 a 7 temos o exemplo de como exibir uma mensagem de erro quando esta ocorre. Nota-se que o  código da view é bem simples, usa-se código python sem maiores traumas, nada muito diferente de outras templates como a ERB do Rails.

No código do controlador as linhas 92-93 são responsáveis por inicializar o servidor http. Basta digitar a seguinte linha no terminal e acessar http://localhost:9090/posts:

 python blog.py

Apesar do Bottle não possuir features muito avançadas para desenvolvimento web ele me pareceu bem interessante para implementar coisas pequenas e rápidas, inclusive uma API REST. A implementação desse exemplo foi bem rápida e não faz muito tempo que aprendi o básico da linguagem python.

Na minha opinião é um ótimo framework para implementar aplicativos com poucas funcionalidades e principalmente se você deseja executá-lo em várias máquinas sem precisar instalar vários pacotes, ou se você não tem a senha de administrador da máquina, por exemplo. Basta ter python instalado, o que acontece na maiorias das distribuições linux e no OSX. Por outro lado, se temos que implementar um aplicativo mais complexo, com vários objetos na camada de modelo, com diversas validações e relacionamentos entre os mesmos, talvez não seja a melhor opção por nos obrigar a implementar vários códigos adjacentes, como por exemplo a validação de objetos antes de persistir e exibição de mensagens de erros ou sucesso, o que no Rails, é feito de maneira bem intuitiva e com poucas linhas de código.

Como o código é aberto você pode baixá-lo da internet e ler o código-fonte caso queria entender como funciona um framework web, sendo essa, a sua principal vantagem. É uma ótima fonte de estudo para quem deseja entender como funciona a internet e um pouco do protocolo HTTP. E no caso de se sentir confortável o bastante, desenvolver seu próprio framework web adicionando opções mais avançadas de acordo com a necessidade.

Referências:
Bottle.py: http://bottlepy.org/docs/dev/index.html

PyBlog, código-fonte de exemplo:
https://github.com/eduardocl/pyblog

Outros frameworks minimalistas:
werkzeug: http://werkzeug.pocoo.org/

Flask: http://flask.pocoo.org

Jetty com JSF2, JPA2 e Weld

Seguindo aquele experimento (post) de utilizar o jetty para desenvolver um aplicativo com JSF e JPA, também surgiu a necessidade de ver como fazer para uilizar o Weld, o framework de injeção de dependência. Basicamente, para poder utilizar o Weld no jetty deve-se seguir os seguintes passos:

1) No web.xml criamos um listener para o weld, como mostrado nas linhas em destaque abaixo:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
  <context-param>
    <param-name>facelets.DEVELOPMENT</param-name>
    <param-value>true</param-value>
  </context-param>
  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.jsf</url-pattern>
  </servlet-mapping>
  <listener>
    <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
  </listener>
  
   <listener>
    <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
  </listener>
  
  <resource-env-ref>
    <description>Object factory for the CDI Bean Manager</description>
    <resource-env-ref-name>BeanManager</resource-env-ref-name>
    <resource-env-ref-type>javax.enterprise.inject.spi.BeanManager</resource-env-ref-type>
  </resource-env-ref>
  
   <context-param>
<param-name>primefaces.THEME</param-name>
<param-value>bootstrap</param-value>
</context-param>
  
<!-- <context-param> -->
<!-- <param-name>primefaces.skin</param-name> -->
<!-- <param-value>none</param-value> -->
<!-- </context-param> -->
  
</web-app>

e adicionar o arquivo jetty-env.xml no WEB-INF com o seguinte conteúdo:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure id="webAppCtx" class="org.mortbay.jetty.webapp.WebAppContext">
<New id="beanManager" class="org.mortbay.jetty.plus.naming.Resource">
   <Arg>
     <Ref id="webAppCtx" />
   </Arg>
  <Arg>BeanManager</Arg>
  <Arg>
    <New class="javax.naming.Reference">
      <Arg>javax.enterprise.inject.spi.BeanManager</Arg>
      <Arg>org.jboss.weld.resources.ManagerObjectFactory</Arg>
     <Arg />
    </New>
</Arg>
</New>
</Configure>

Um projeto completo está disponível aqui.

para rodar basta entrar no diretório e digitar:

mvn jetty:run

depois, acesse o link: http://localhost:8080/contactlist/list.jsf

A diferença de projeto para o anteior, que não usava o weld, é que este usa o hibernate e o sqlite como banco de dados. Então pra quem quer usar o jetty com essas duas tecnologias vale a pena dar uma olhada no pom.xml.

Usando JSF2 e JPA2 com Jetty

Trabalhar com java para web muitas vezes é um exercício de paciência enorme, principalmente para fazer alguma coisa bem simples. Você pode gastar muito tempo para configurar direito o maven (praticamente nunca trabalhei em projeto que usasse maven ou ant), isso quando não se perde mais de um dia pra isso. Outro detalhe é o servidor de aplicação (jboss por exemplo) que entre vários restarts para fazer deploy toma muito tempo, por que até hoje não vi nenhum desses servidores de aplicação java que, mesmo com hot-deploy habilitado não dê um PermGem exception depois de seguidos re-deploys.

Resolvi tentar o jetty, que me parecia bem rápido e é utilizado de forma embarcada, em aplicativo como o Solr, que tem uma boa performance.

O Jetty é um servidor web feito em java muito leve. Apesar de ser um container servlet podemos estendê-lo para também ser um container EJB, por exemplo. Ele não vem com toda a stack do JEE, mas pesquisando um pouquinho na internet, consegui criar um pom.xml que permite usar JSF 2 (primefaces) e JPA 2 (Ebean, mas dá para usar o hibernate, simplesmente adicionando no pom as dependências).

A principal vantagem do jetty é a rapidez do deploy já que no boot ele não tem tanta coisa pedurada como o Jboss, que leva quase 8 segundos bootando na minha máquina.

Abaixo listo o pom.xml para um projeto baseado no Jetty, JSF e JPA:

 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>sh.app.sample-projects</groupId>
<artifactId>jsf2-jetty-maven</artifactId>
<version>SNAPSHOT</version>
<name>JSF 2, JPA 2, Jetty and Maven together</name>

<dependencies>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>${com.sun.faces.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>${com.sun.faces.version}</version>
<scope>runtime</scope>
</dependency>

<dependency>
<groupId>commons-fileupload</groupId>
<artifactId> commons-fileupload</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId> commons-io</artifactId>
<version>2.1</version>
</dependency>

<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.7.2</version>
</dependency>

<dependency>
<groupId>org.avaje</groupId>
<artifactId>ebean-spring</artifactId>
<version>2.7.7</version>
</dependency>

<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.1-901.jdbc4</version>
</dependency>
    
     <!-- primefaces -->
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>3.4.2</version>
</dependency>

<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.2.8</version>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.0.0.GA</version>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>

<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>

<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>

<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2</version>
</dependency>

<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>3.1</version>
</dependency>

<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
</dependency>

  <!-- SQLite database JDBC -->
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.6.0</version>
</dependency>

</dependencies>


<repositories>
<repository>
<id>prime-repo</id>
<name>PrimeFaces Maven Repository</name>
<url>http://repository.primefaces.org</url>
<layout>default</layout>
</repository>
<repository>
<id>JBoss repository</id>
<url>http://repository.jboss.com/maven2/</url>
</repository>
</repositories>

<build>
<finalName>contactlist</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.source.level}</source>
<target>${java.source.level}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty-maven-plugin.version}</version>
<configuration>
    <webApp>
     <contextPath>/contactlist</contextPath>
   </webApp>
   </configuration>
</plugin>
      
     <!-- Tomcat plugin for embedded tomcat -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<configuration>
<path>/contactlist</path>
</configuration>
</plugin>

</plugins>
</build>

<properties>
<encoding>UTF-8</encoding>

<java.source.level>1.6</java.source.level>
<spring.version>3.1.3.RELEASE</spring.version>
<com.sun.faces.version>2.1.7</com.sun.faces.version>
<jetty-maven-plugin.version>8.1.2.v20120308</jetty-maven-plugin.version>
<org.slf4j.version>1.6.5</org.slf4j.version>
<junit.version>4.10</junit.version>
</properties>

</project>

Um exemplo de projeto pode ser encontrado aqui

Para rodar entre no diretório do projeto e digite:

mvn jetty:run

e depois acessar a url:

http://localhost:8080/contactlist/list.jsf

CDI Alguns conceitos

Abaixo uma apresentação, também disponível no slideshare, sobre os conceitos do CDI (Contexts and Dependency Injection for Java EE).

Enviando Mensagem Jabber via Ruby ou Python

Esses dias eu queria enviar de alguma maneira por jabber, uma vez que estou 90% com um cliente jabber rodando no meu micro, mensagens me informando de eventos de alguma coisa que me interesse que ocorra em algum servidor ou mesmo no meu micro. Depois de tentar algumas libs em python e java, acabei conseguindo fazer um pequeno script em ruby (e python), simplesmente muito fácil, que atendeu totalmente o que eu queria.

Sem muito bla bla bla, pois o que interessa é mostrar funcionando, listo abaixo como instalar a gem (eu uso ruby 1.9) e um exemplo de como enviar a mensagem.
Instalando:

gem install xmpp4r

Eis os script que envia a mensagem:

require 'xmpp4r'
include Jabber

CLIENT_ID = 'cliente@jabber.org'
PASSWORD = ''

SEND_TO = 'destinatario@gmail.com'
JABBER_SERVER='jabber.org'   #para enviar a partir de um servidor jabber 
GTALK_SERVER='talk.google.com' #para enviar usando o google

Client.new(JID.new CLIENT_ID).instance_eval do
  connect JABBER_SERVER
  auth PASSWORD
  send Message.new(SEND_TO, 'enviando uma mensagem via ruby').tap{|m| m.type = :chat}
  close
end

Mas mesmo assim, pra quem gosta de programar em Python, baixe o xmmpy, descompacte e entre no diretório, para em seguida:

python setup.py install

Pronto, a biblioteca já está instalada. Abaixo um exemplo de como enviar a mensagem por Jabber:

import sys
import xmpp

# Google Talk constants
FROM_GMAIL_ID = "remente@gmail.com"
GMAIL_PASS = "senha_do_remente"
GTALK_SERVER = "talk.google.com"
TO_GMAIL_ID = "destinatario@gmail.com"

jid=xmpp.protocol.JID(FROM_GMAIL_ID)
cl=xmpp.Client(jid.getDomain(),debug=[])

if not cl.connect((GTALK_SERVER,5222)):
   raise IOError('Can not connect to server.')
if not cl.auth(jid.getNode(),GMAIL_PASS):
   raise IOError('Can not auth with server.')

cl.send( xmpp.Message(TO_GMAIL_ID ,"Fala meu bruxo!" ) )
cl.disconnect()

É isso galera, bem simples enviar mensagens para o seu cliente Jabber usando essas duas dicas. Detalhe: vc não precisa ter duas contas no Gtalk, basta enviar de vc para vc mesmo. Nerds carentes devem evitar esses scripts ehhehe.