Java

ruby

segunda, 03 de novembro de 2008

Quando Java não for suficiente

Escrito por: Alberto

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.

tags: , ,

Java

terça, 21 de outubro de 2008

Trazendo um pouco de Ruby para Java

Escrito por: Alberto

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.

tags: ,



newsletter

cadastre seu e-mail!  

últimas do twitter

» siga a settech no twitter

swTV

 


Atuando no mercado desde 1999, a SetWeb conta com um time de profissionais que busca soluções adequadas e eficazes para a sua empresa. Aliando estratégia à tecnologia, a SetWeb possui como foco principal o resultado de ações implementadas para cada negócio.
Esse é o nosso compromisso e o nosso desafio.