Eu estava procurando uma api para acessar o delicious via Java, como nenhuma foi satisfatória, pelo menos para mim, resolvi fazer uma :). O código foi desenvolvido sob a idéia do máximo de fluência, então para tudo tem Tiny Types e os metodos foram programados para permitirem o encadeamento de chamadas, deixando o código mais fácil de ser lido. No começo achei que o beneficio do Tiny Type iria ficar restrito a fluência, mas no final, na hora de parsear o xml de retorno com o XStream, ele foi de fundamental importância para as conversões. O projeto está no github, e quem quiser pode acessar clicando aqui :).
Como eu precisava fundamentalmente fazer a busca dentro de todos os posts e também possibilitar inserção, só tá implementado estes 2 metodos, mas acho que logo logo todas as chamadas estarão disponíveis. Espero que ajude!
Talvez esteja errado, mas em vários projetos temos algumas classes que implementam o Composite Pattern, ou algo parecido :). Com esses objetos, por exemplo, temos que criar algum metodo que retorne os possiveis pais para montar um combo ou então apresentá-lo de alguma forma, tipo avo/pai/filho e por aí vai. Para poupar um pouco de trabalho, criei um projetinho, hospedado no github :), que visa facilitar nossa vida. Caso tenham projetos desse tipo e ainda não tenham implementado algo para isolar isso, talvez valha a pena dar uma olhada :). Valeu!!!
Recentemente tive que configurar um Virtual Host no Tomcat, como eu nunca tinha feito, tive que pesquisar e aprender. Um Virtual Host é útil quando você tem um único Tomcat atendendo vários dominios, tipico em hospedagens compartilhadas. Existem vários tutorias aí na internet, inclusive o do próprio site do Tomcat, que foi o que eu segui. Vou deixar aqui os passos e espero que sirva para vocês.
Comece criando uma pasta a partir da raiz da instalação do seu tomcat, por exemplo /usr/local/tomcat/nova_pasta, podemos dizer que isso já é o seu novo Virtual Host, ela está funcionando agora como a pasta webapps padrão do Tomcat, que por sinal é o Virtual Host default. Agora vem a hora de colocar seu projeto, pegue seu .war e descompacte dentro da pasta criada, para ele ser o root de seu Virtual Host, crie com o nome ROOT.war, procedimento idêntico ao que faria usando a webapps. Feito isso, dentro do contexto que você acabou de criar, ROOT por exemplo, crie a pasta META-INF e crie um arquivo context.xml, onde ficarão as configurações do seu contexto. Segue um exemplo:
<?xml version="1.0" encoding="UTF-8"?>
<Context path="" docBase="${CATALINA_HOME}/nomeDoSeuVirtualHost/nomeDoContexto">
<!-- Caso tenha um contexto -->
<Resource name="jdbc/xxxxx" auth="Container" type="javax.sql.DataSource"
username="xxx"
password="xxxx"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://xxxx:3306/xxx?autoReconnect=true"
maxActive="15"
maxIdle="7"
validationQuery="Select 1" />
</Context>
Feito isso, vem a última parte, que é configurar o tomcat para que ele ache seu Virtual Host. Vá em ${CATALINA_HOME}conf/server.xml e procure pela tag engine, aí você vai achar o que falamos no ínicio, a pasta webapps configurada para ser o Virtual Host default. Agora adicione o seu Virtual Host adicionando o seguinte trecho:
<Host name="www.seudominio.com.br" appBase="sua_nova_pasta"> </Host>
Pronto, feito isso, teoricamente tudo deve funcionar normalmente :), caso não funcione posta aqui ou manda email :).
Ontem aconteceu mais uma edição do Falando em Java, evento promovido pela Caelum e patrocinado por grandes empresas do nosso mercado, entre elas, Globo, Locaweb e JBoss. O evento contou com excelentes palestrantes, destaque para o Jim Webber, consultor da ThoughtWorks e que fez duas excelentes palestras sobre SOA.
Como já falei, é sempre muito legal participar destes eventos, além de excelente conteúdo, você tem a oportunidade de ampliar sua rede de contatos. Ontem conheci uma galera da ceJug, Grupo de Usuarios Java do Ceará, muito legal. Já conhecia de nome o Rafael Carneiro, um dos lideres, e ainda fiquei sabendo que a comunidade lá é muito ativa. De acordo com o Rafael só perde para a souJava, que é a mais ativa do Brasil. Conheci também um pessoal de Vitória-ES, eles estão pensando em iniciar um projeto opensource sobre TV Digital, e claro, me escalei para ajudar :). Para finalizar, conheci a galera da Caelum que participa do Stella, o Cauê, que por sinal vem palestrar em agosto para o Oxente Rails, e o Jonas.
Tenho que separar um paragrafo, para falar da galera do Rio, os caras são muito gente fina. Tinha feito curso com os caras ano passado na Caelum e eles estavam lá para o evento. Atualmente são instrutores da Caelum - Rio, em junho vou passear lá com minha namorada e já marcamos de ir no baile funk. Isso é, se os caras não enrolarem, porque se tem uma galera enrolada, são aqueles caras!!!.
No final do evento rolou um coquetel para a galera interagir mais e depois todo mundo foi para um bar chamado o O’Malleys(não sei bem se o nome é esse…), devo falar que a galera ficou um pouco alta :). Gostaria que tivesse mais conterrâneos meus lá, mas de qualquer forma achei muito bom o evento!!! Com o passar do tempo vou postando sobre as palestras, a do VRaptor 3, Guerrilha SOA e Para onde vai a plataforma Java foram as melhores na minha opinião.
O google lançou recentemente a versão do GAE para rodar aplicar em Java, e eu, um pouco atrasado é verdade, fiz apenas um teste simples subindo uma aplicação de exemplo para o ambiente deles, nada de mais, pelo menos por enquanto :). O ambiente contém algumas restrições, aqui você acha todas as classes que tem execução permitida. É muito legal termos um ambiente deste para testar algumas das nossas aplicações. Como ainda tá em fase beta é necessário fazer um cadastro e esperar a confirmação para o uso. Logo abaixo estarei falando do que tive de fazer para subir minha primeira app, então se tiver interessado em fazer o mesmo, continue lendo :).
Primeiro baixei o Eclipse Ganymede JEE, por conveniência mesmo, depois vem a hora de instalar o plugin do google para facilitar o desenvolvimento, você encontra a explicação aqui. Feito isso, basta você seguir os passos do tutorial do link anterior que vai conseguir construir sua primeira app. Finalmente é a hora de fazer o upload para o ambiente do google, bem, nessa hora tive uma dificuldade inesperada. O plugin faz o build do seu projeto para fazer o upload e durante este build ele usa javac para compilar algumas coisas. Para achar a localização do javac, ele faz uso do System.getProperties(”java.home”) para pegar a localização da JRE que o eclipse tá usando, caso não ache o javac na pasta bin ele tenta em ../bin/, ou seja, tenta achar bin no diretório acima. Quando instalei o Java aqui, pedi para instalar tanto o JDK quanto apenas a JRE, não me lembro o motivo agora, o importante é que o eclipse tava apontando justamente apenas para a JRE e, consequentemte, deu pau na hora de fazer o upload da app. Então, para consertar, você pode ir em, seu projeto->botão direito->Properties->Run/Debug Settings/sua_app/edit/aba jre/Installed JREs e escolher a pasta jre dentro da sua pasta Jdk. Quando o plugin for fazer o upload, ele não vai encontrar o javac dentro da pasta jre/bin mas vai encontrar em ../bin/ e você vai ficar feliz. Caso esteja na mesma situação que eu me encontrei, espero que o post ajude, caso não esteja, realmente a leitura desse paragrafo pode ter sido meio sem sentido
Uma coisa bastante interessante, e que a comuninade vem testando bastante, é rodar as linguagens de script em cima da JVM no ambiente do google, então aproveite para colocar seu projeto JRuby on Rails nas nuvens do google!!!.
Em um projeto aqui na empresa, estava precisando acessar o webservice do SugarCRM. O problema aconteceu quando descobri que o estilo de binding dele era rpc/encoded e que os projetos em Java mais atuais não estavam dando suporte a isso, alguns exemplos são : Axis2 e CXF.
Então foi que pensei, deixa eu ver se tem jeito de fazer isso em Ruby, e descobri que era até meio ridiculo…
require('md5')
require 'soap/wsdlDriver'
@wsdl = "http://localhost/settech_orcamentos/soap.php?wsdl"
@soap = SOAP::WSDLDriverFactory.new(@wsdl).create_rpc_driver
resultado = @soap.login({:user_name=>"login",:password=>MD5.new("password"),:version=>"5.1.0a"},"SugarCRM")
puts resultado.id
Isso porque o Ruby faz o parse do wsdl em tempo de execução e cria uma classe para você naquele momento, na verdade um proxy, e permite que todos os metodos sejam acessados. Ainda conta a ferramenta wsdl2ruby para fazer algo similar ao wsdl2java.
Com isso em mãos, resolvi fazer o mix de Java com Ruby, usando o Java como linguagem, mas também como plataforma para execução de código, nesse caso o Ruby através da sua implementação em Java, JRuby. Isso oferece um potencial incrível pois, por exemplo, podemos usar o potencial do Ruby para fazer algo que Java não seja muito bom ou até querer manter um código em Java que seja dinâmico, sim é permitido acessar as API’s do Java através do Ruby. Abaixo segue o código que fiz. A primeira parte em Ruby e a segunda em Java. As variaveis no código Ruby que estão com $, foram compartilhadas do código em Java para o Ruby
require('java')
include_class('br.com.settech.sugarsoap.Result')
include_class('br.com.settech.sugarsoap.helper.ContextSoapComunication')
require 'soap/wsdlDriver'
require 'MD5'
module IntegracaoSugarCRM
class SugarCRM
def initialize(name_value_pairs)
@name_value_pairs = name_value_pairs
@params = Array.new
end
def params
@name_value_pairs.each {|name_value_pair| @params.push({:name=>name_value_pair.name,:value=>name_value_pair.value})}
@params
end
end
class Integrador
def initialize
if not $context
@soap = SOAP::WSDLDriverFactory.new($info.url_wsdl).create_rpc_driver
end
end
def login
result = @soap.login({:user_name=>$info.login,:password=>MD5.new($info.password),:version=>$info.version},$info.app_name)
ContextSoapComunication.new(Result.new(result.error.number,result.error.description,result.id),@soap)
end
def logout
#logout aqui
end
#Usa as variaveis definidas no codigo java.
def executa_metodo
params = SugarCRM.new($name_value_pairs).params
result = $context.driver.set_entry($context.login_id,$which_module,params)
Result.new(result.error.number,result.error.description,result.id)
end
end
end
if not $context
IntegracaoSugarCRM::Integrador.new.login
else
IntegracaoSugarCRM::Integrador.new.executa_metodo
end
public class JRubyIntegrationTest {
private ContextSoapComunication contextSoapComunication;
private BSFHelper helper;
@Before
public void testCreateLogin() throws BSFException,IOException{
helper = new BSFHelper();
SugarInfo sugarInfo = new SugarInfo("login","password","SugarCRM","5.1.0a","http://localhost/settech_orcamentos/soap.php?wsdl");
helper.declareBean("info",sugarInfo);
this.contextSoapComunication = (ContextSoapComunication)helper.evalFile("C:\\ambiente\\ruby_project\\IntegracaoSugarCRM\\lib\\integrador.rb");
this.contextSoapComunication.loginId();
}
@Test
public void testExecuteJRubyCode() throws BSFException,IOException{
NameValuePairCreator lista = new NameValuePairCreator();
this.helper.declareBean("which_module",ModuleTypes.OPPORTUNITIES);
this.helper.declareBean("name_value_pairs",lista.addNameValuePair("lead_source","Self Generated").addNameValuePair("name","Projeto integracao2").addNameValuePair("amount","53500.55").nameValuePairList());
this.helper.declareBean("context",this.contextSoapComunication);
Result result = (Result)helper.evalFile("C:\\ambiente\\ruby_project\\IntegracaoSugarCRM\\lib\\integrador.rb");
System.out.println(result.createdId());
helper.finalize();
}
}
Para acessar o script através do Java, uso o projeto BSF(Bean Scripting Framework), ideal para quem, como eu, está no Java 5 ainda. A classe BSFHelper foi extraída do site ociweb.com. A única ressalva que faço, é que para usar um script que faça uso do require ou algo parecido, devemos forncer ao BSF a localização das bibliotecas. Para fazer isso, coloque o seguinte código:
System.getProperties().put("jruby.lib",jrubyBase+"\\lib");
System.getProperties().put("jruby.home",jrubyBase);
Bom, por hoje é isso, desculpem o tamanho do post, mas queria mostrar algo que foi realmente útil para mim e acho que pode ser para vocês também.
Estudando Ruby, nós do Java ou .NET, vemos umas coisas que nos parecem meio estranhas. Por exemplo, todo metodo retorna algo, mas para que eu quero que meu metodo setter retorne alguma coisa?. Bem, inicialmente pode não fazer sentido, mas se parar e der uma olhada, verá que não faz diferença nenhuma para seu código se seu metodo pessoa.setNome(”Alberto”) retornar uma referencia para ele mesmo(this).
Você usa o retorno se quiser, querendo pode fazer algo besta, mas na minha opinião muito mais legivel,
pessoa.setNome("Alberto").setSobreNome("Souza").qqCoisaAqui(...);
É isso que venho colocando na minha cabeça, aprender uma linguagem nova é muito legal, mesmo que não coloquem em produção, não custa nada dar uma olhada, ver uma forma diferente de fazer algo.
