Arquivo para Maio, 2008

Relatórios em Flex? Jasper4Flex pode ser uma opção

Recentemente por uma iniciativa de Teodor Danciu, foi desenvolvido mais uma opção de renderização de relatórios feitos em jasper, so que desta vez em swf, ou seja, para desenvolvimento Flex, conhecido como Jasper4Flex, o mesmo possui algumas peculiaridades em relação ao FlexReport, pois constitui base jasper server-side, então toda a geração do relatório ocorre no servidor jasper seguido de um parser Jasper4Flex, feito por um servlet registrado no deploy descriptor:

web.xml

….

<servlet>

<servlet-name>SwfServlet</servlet-name>

<servlet-class>net.sf.jasperreports.j2ee.servlets.SwfServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>SwfServlet</servlet-name>

<url-pattern>/servlets/swf</url-pattern>

</servlet-mapping>

……

Em poucas linhas podemos fazer nossa chamada apartir de um servlet.

JasperPrint impressao = JasperFillManager.
fillReport(”Report_exemplo.jasper”, parametros,conn);
HttpSession session = request.getSession();
session.
setAttribute(BaseHttpServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE, impressao);
response.sendRedirect(”servlets/swf”);

Neste caso foi criado um servlet para testar o exemplo. O código, não tem muito mistério a única diferença está, em como esse servlet vai responder essa requisição direcionando ’servlets/swf’. O resto o jasper4Flex se encarrega de fazer. Estou ate satisfeito com os testes que tenho feito ate agora. Mais o projeto é muito recente? Sim, eu sei mais a comunidade esta ai pra isso, testar, motivar e colaborar. Vejo isso como mais um incentivo a desenvolvedores que querem usar projetos Java em front-end Flex. Os exemplos podem ser baixados aqui no site do projeto.

Injeção de Dependência e o Google GUICE

Segundo Martin Fowler todo e qualquer conteiner leve deve por si só implementar Inversão de Controle (Inversion of Control, ou IoC), definidos por três possíveis formas de Injeção de Dependência (DI), constructor Injection (Injeção por Construtores), Setter Injection (Injeção por Métodos Set) e Interface Injection (Injeção por Interfaces), a DI está relacionada ao baixo acoplamento de diferentes componentes de seu sistema e como acessar o mesmos não por uma chamada direta e sim por uma “injeção” do conteiner, hoje existem vários conteiner leves que fazem essas implementações como PicoContainer, Spring, Avalon. O Guice criado pelos “GooglersBob Lee e Kevin Bourrillion traz como principal característica um conteiner puramente DI, suportando injeção via constructor e setter e podendo funcionar somente com anotações ou se preferir, construir módulos para definir os bind entre objetos.

DI, Guice Style

Diferentemente do clássico pattern Factory que traz a instância de uma implementação, quando se trata de DI ocorre a inversão desse controle e o Guice simplifica com uma simples anotação @Inject dizendo onde o conteiner vai injetar.

Code 1.

public class Cliente {

private Service service;

@Inject

public Cliente(Service service) {

this.service = service;

}

public void getMyService(){

service.getService();

}

}

No Code 1 acima usa-se uma injeção por construtor. O mais interessante é a configuração de dependência:

Code 2.

@ImplementedBy(ServiceImpl.class)

public interface Service {

void getService();

}

@Singleton

public class ServiceImpl implements Service {

public void getService() {

System.out.println(“Metodo getService foi chamado”);

}

}

Pronto, agora podemos testar o nosso exemplo a partir da classe Cliente do Code 1, as anotações @ImplementedBy define sua implementação de classe eliminando qualquer código, e a @Singleton define o escopo de implementação por padrão o Guice cria uma instância a cada chamada.

Code 3.

public class App {

public static void main(String[] args) {

Injector guiceInj = Guice.createInjector(new Module[0]);

Cliente c = guiceInj.getInstance(Cliente.class);

c.getMyService ();

}

}

Se tivermos sorte nosso Code 3 irá imprimir “Metodo getService foi chamado”, é claro podemos também definir nosso bind explicitamente por construção de módulos:

Code 4.

public class MyModule implements Module {

public void configure(Binder binder) {

binder.bind(Service.class).to(ServiceImpl.class).in(Scopes.SINGLETON);

}

}

…..

Injector guiceInj = Guice.createInjector(new MyModule());

Cliente c = guiceInj.getInstance(Cliente.class);

c.getMyService ();

……

O Code 4 mostra que um único metodo da interface é definido com um objeto Bind, podendo ser usado para definir sua especial sintaxe que pode ser lido da seguinte forma: “Amarra interface Service a implementação ServiceImpl no escopo Singleton”. Ate ai tudo bem, mais como sair da situação onde temos mais de uma implementação para nossa Service.class? Podemos também utilizar o AbstractModule para fazer nossa subclasse. A mesma implementa a interface Module e não define argumento no metodo configure, sigamos o exemplo com essa implementação:

Code 5.

public class MyModule extends AbstractModule {

public void configure() {

bind(Service.class).to(ServiceImpl.class);

bind(Service.class).to(ServiceImplNew.class);

}

}

Provavelmente quando for executar esse Code 5 irá ocorrer um erro de execução, pois o Guice não trabalha desta forma, então como sair dessa situação? Simples, basta fazer um bind com anotação da seguinte forma:

Code 6.

public class MyModule extends AbstractModule {

public void configure() {

bind(Service.class).to(ServiceImpl.class);

bind(Service.class).annotateWith(Marca.class).to(ServiceImplNew.class);

}

}

Isso mesmo, podemos definir um bind com uma marcação anotada em uma determinada requisição, vamos a sintaxe lendo da esquerda para direita: “Amarra todas as requisições para a interface Service anotado com @Marca para a implementação ServiceImpl”, porém a anotação @Marca deve ser criada programaticamente com a seguinte estrutura:

Code

Explanation

@Retention(RetentionPolicy.RUNTIME)

Anotação em tempo de execução

@Target({ElementType.FIELD,ElementType.PARAMETER})

Onde pode ser colocada

@BindingAnnotation

Informa que é uma anotaçao ‘binding’

Public @interface Marca{}

Como é declarada

Feito isso basta definir como marcação:

public class Cliente {

private Service service;

@Inject

public Cliente(@Marca Service service) {

this.service = service;

}

……

Bom, explorando mais a fundo o Guice podemos encontrar inúmeras funcionalidades como bindInterceptor, Aspect-Oriented Programming (AOP), Integrating Web(Struts 2, Wicket) entre outros, onde pode ou não trazer benefícios para sua arquitetura, isso vai depender muito do que você precisa e com que você esta trabalhando. Anteriormente em muitos fóruns já foi discutido isso, e muita gente não se sente muito confortável de como o Guice trabalha, porém, temos que concordar que não há muito que refazer com o que já foi feito só nos resta a escolha. Boa sorte a todos e espero que eu tenha ajudado de alguma forma com esse meu primeiro post.

Referencias:

http://martinfowler.com/bliki/InversionOfControl.html

http://www.javafree.org/content/view.jf?idContent=1

http://www.apress.com/book/view/9781590599976

http://code.google.com/p/google-guice/