Categoria: Frameworks

Jericho Selector, ou jQuery para Java

CSS3

É com grande satisfação que venho anunciar a publicação da primeira versão estável (stable release) da biblioteca Jericho Selector.

O Jericho Selector é uma extensão para a conhecida biblioteca de leitura e manipulação de HTML Jericho HTML Parser que permite selecionar elementos de um documento HTML ao estilo do jQuery, ou seja, utilizando seletores CSS.

Por quê Jericho? Diferente do jsoup, por exemplo, ele permite alterar documents HTML mantendo a formatação original. Outras bibliotecas reescrevem o documento inteiro. De qualquer forma, eu gosto de ter opções! 😉

Jericho Selector é totalmente livre, sob a licença MIT.

Como usar

O Jericho Selector está disponível no Repositório Central do Maven, então basta configurar o seu projeto com a seguinte dependência:

<dependency>
    <groupId>br.com.starcode.jerichoselector</groupId>
    <artifactId>jericho-selector</artifactId>
    <version>1.0.1-RELEASE</version>
</dependency>

Depois, faça a importação do método estático $ que pode ser usado como ponto de entrada para uso do Jericho Selector:

import static br.com.starcode.jerichoselector.jerQuery.$;

Então você poderá realizar consultas da seguinte forma:

$(html, "p.my-text")

O que foi feito

Antes de iniciar a implementação do Jericho Selector, tive que implementar um interpretador (parser) completo de seletores CSS. Para isso, implementei outra biblioteca que chamei de parCCSer. Ela foi baseada na especificação oficial do W3C para CSS3 e cobre praticamente todos os aspectos da especificação, exceto alguns detalhes que se aplicariam apenas no contexto de um navegador e também algo relacionado a suporte de caracteres UTF-8. Ela também está sob a licença MIT.

O Jericho Selector então utiliza a árvore de objetos gerada pelo parCCser, assim como a API do Jericho HTML Parser para consultar os elementos de um documento HTML com base em um dado seletor.

Todas as implementações possuem cobertura em testes unitários de mais de 90% do código, sem contar os casos excepcionais que o plugin de cobertura não consegue analisar.

O que precisa ser feito

Nas próximas semanas pretendo adicionar ao Jericho Selector funcionalidades de uma API fluente, análogas ao jQuery, para que seja possível realizar operações com os elementos recuperados usando lambdas e outros recursos. Métodos como closest, parentsUntil, find, each são meus primeiros alvos.

Outro ponto a melhorar é o desempenho da biblioteca. Alguns seletores específicos podem ter sua execução otimizada utilizando cache ou métodos específicos do Jericho HTML Parser como getAllElementsByClass.

O que você pode fazer

Reporte qualquer problema e sugira novas funcionalidades!

Código-fonte

Confira o código e maiores detalhes na minha página do GitHub:

https://github.com/utluiz/jericho-selector/

Jericho Selector, a.k.a jQuery for Java

CSS3

I’m pleased to announce the first stable release of Jericho Selector.

Jericho Selector is an extension to the known library Jericho HTML Parser that allows you to select elements from an HTML document just like you do with jQuery, using CSS selectors.

Why Jericho? Different from jsoup, it allows you to modify the document keeping the original formatting. Other libraries rewrite the entire document. Anyway, I like to have a choice! 😉

Jericho Selector is completely free. It uses MIT license.

How to use

Jericho Selector is available at Maven Central Repository, so you just need to add the following dependency to your project:

<dependency>
    <groupId>br.com.starcode.jerichoselector</groupId>
    <artifactId>jericho-selector</artifactId>
    <version>1.0.1-RELEASE</version>
</dependency>

Import the static method $ that is the entry point for Jericho Selector:

import static br.com.starcode.jerichoselector.jerQuery.$;

Then you can query HTML elements just like jQuery:

$(html, "p.my-text")

What has been done

Before implementing Jericho Selector, I had to implement a full CSS parser. In order to do that, I created another library called parCCSer. It was based on the official W3C CSS3 specification and covers almot all of the specification, except some details that are valid only in the context of a browser and also something related to UTF-8 support that I considered not entirely necessary. It’s also under MIT license.

Jericho Selector then uses the object tree generated by parCCser, as the Jericho HTML Parser API, to query the HTML document elements given a CSS selector.

All implementitions are covered by unit testes above 90%, without taking in account excepcional cases that the plugin are not able to analyse.

What is coming

In the next weeks I aim to add some fluent API features to Jericho Selector, similar to jQuery, so you can make some operations using lambdas, for example. Methods like closest, parentsUntil, find, each are my priorities.

Another point to improve is the performance. Specific selectors can be optimized using cache or specific Jericho HTML Parser methods like getAllElementsByClass.

What you can do

Report any problem and suggest new features!

Souce code

You can get check out the source code from GitHub account:

https://github.com/utluiz/jericho-selector/

Qual a diferença entre MVC action based e component based?

Frameworks Component Based

Frameworks Component Based mantém sincronia entre os estados dos componentes da view e do seu modelo de dados no lado do servidor.

Quando o usuário interage com a tela, as alterações realizadas são, em um dado momento, refletidas no modelo que fica no servidor.

No JSF, por exemplo, a “tela” é gerada por um facelet, que nada mais é que um XML que define quais componentes serão exibidos para o usuário e associam os valores desses componentes a um objeto (Java Bean) que fica no servidor. Esses componentes são então renderizados em HTML e, quando o usuário executa uma ação, o JSF atualiza os objetos no servidor.

Não encontrei uma representação visual adequada, mas algo aproximado num artigo da Caelum sobre o tema:

Component Based Request

Component Based Request

Em frameworks component based, a view é responsável por mapear valores para os beans e para o modelo. A imagem acima ilustra a ordem de chamadas:

  1. O usuário executa uma ação no sistema
  2. O front controller do framework atualiza os componentes da view com o estado atual
  3. O método do Managed Bean é chamado (usando JSF como exemplo), podendo executar alguma regra de negócio com os novos valores
  4. Finalmente, o modelo do sistema é atualizado

Frameworks Action Based

Já os frameworks Action Based não mantém necessariamente esse vínculo entre os estados do servidor e do cliente.

Isso não quer dizer que o desenvolvedor não possa armazenar estado no servidor, por exemplo, na sessão do usuário, mas que o vínculo entre o modelo e a view não é tão acoplado como no modelo Component Based.

Um framework Action Based geralmente irá receber diretamente requisições HTTP. Isso torna o modelo action based mais flexível, já que o desenvolvedor pode optar por qualquer tipo de view que gere uma requisição HTTP compatível.

Considere a ilustração a seguir (da mesma fonte anterior):

Action Based Request

Action Based Request

O resumo dos passos da execução é:

  1. O usuário executa uma ação no sistema
  2. O front controller do framework direciona a requisição e os parâmetros para um método do controller
  3. O controller lê os parâmetros necessários e executa regras de negócio que atualizam o modelo
  4. O controller “devolve” uma view para o usuário

Conclusão

Podemos dizer que os frameworks component based são mais centrados nas views (com seus componentes que mapeiam o modelo e os dados do usuário), enquanto os action based são mais centrados nos controllers (que recebem parâmetros via request).


Este artigo é baseado na minha resposta do Stack Overflow em Português

Reflexões sobre o uso de frameworks

Construção Errada

Em meu último artigo, Porque eu odeio frameworks, traduzi uma parábola fictícia que critica a crescente complexidade dos frameworks. Se você não tem muita experiência com Design Patterns (Padrões de Projeto) e com diversificados frameworks, provavelmente não tenha entendido ou mesmo achado o texto pouco interessante.

Agora, sendo mais direto, irei analisar nos tópicos a seguir alguns dos problemas e dificuldades que devemos nos precaver quando usamos frameworks e bibliotecas. Escolhas erradas impactam todas as fases do desenvolvimento de um sistema!

Complexidade excessiva

Quando aprendemos sobre Design Patterns e princípios como coesão e desacoplamento, temos a tendência de considerar tudo isso como soluções mágicas para os problemas de complexidade do software. Alguns começam a aplicá-los indiscriminadamente de forma que, mesmo operações que antes eram simples, exigem agora diversas classes para implementação e conhecimentos de vários conceitos para o entendimento.

Quando ainda estamos nessa fase de “descoberta”, onde acreditamos cegamente nas “vantagens”, sem compreender as consequências de nossas decisões ou mesmo a correta aplicação dos padrões, podemos acabar com dezenas de frameworks pendurados em nossos sistemas e inúmeras classes adicionais mesmo para tarefas simples. Já ouviu a expressão “matar uma mosca com um canhão?”

Soluções “genéricas”

Bons frameworks e bibliotecas possuem aplicações bem definidas. Nenhum framework é tão bom e completo a ponto de ser usado em todo e qualquer projeto. Nem mesmo uma determinada arquitetura como o MVC, por exemplo, mas infelizmente não é sempre assim que aprendemos na teoria.

Por outro lado, nós, desenvolvedores, somos culpados muitas vezes de usar um framework ou biblioteca indiscriminadamente, simplesmente porque já temos algum conhecimento.

Comprometimento da Arquitetura

Muitos frameworks são intrusivos no que diz respeito à arquitetura do software. Isso quer dizer que eles nos obrigam a tomar certas decisões arquiteturais simplesmente para que eles funcionem.

Infelizmente, a realidade hoje é que a grande maioria dos sistemas existentes possuem suas regras de negócios codificadas conjuntamente com classes específicas de terceiros. Não sabemos, e talvez nem pensemos sobre isso, o quanto somos orientados a tecnologias. Para falar a verdade, eu reconheço que também sou culpado disso. Quando codificamos, na maior parte das vezes, estamos mais preocupados com questões técnicas do que em realmente atender aos requisitos. Ou pior, quantas vezes não queremos simplesmente concluir o trabalho e não nos preocupamos com a qualidade interna do código? Infelizmente, a “preguiça” do programador em codificar corretamente é um dos grandes fatores que fazem crescer o número de defeitos e o número de horas extra.

Conclusão

Infelizmente, é preciso queimar muitos neurônios para criar frameworks e bibliotecas que, sendo flexíveis, não sejam demasiadamente complexos e intrusivos nos sistemas. E o mesmo se aplica ao uso deles.  Bons programadores devem saber não apenas como configurar, instanciar e executar objetos de frameworks e bibliotecas, mas principalmente sua precisa escolha e aplicação.

Por fim, para divertimento dos nerds de plantão, selecionei um exemplo de um Hello World em Java que abusa um pouco da complexidade. Ele serve para ilustrar como é possível complicar algo tão trivial.

public interface MessageStrategy {
    public void sendMessage();
}

public abstract class AbstractStrategyFactory {
    public abstract MessageStrategy createStrategy(MessageBody mb);
}

public class MessageBody {
    Object payload;
    public Object getPayload() { return payload; }
    public void configure(Object obj) { payload = obj; }
    public void send(MessageStrategy ms) {
        ms.sendMessage();
    }
}

public class DefaultFactory extends AbstractStrategyFactory {
    private DefaultFactory() {}
    static DefaultFactory instance;
    public static AbstractStrategyFactory getInstance() {
        if (null==instance) instance = new DefaultFactory();
        return instance;
    }
    public MessageStrategy createStrategy(final MessageBody mb) {
        return new MessageStrategy() {
            MessageBody body = mb;
            public void sendMessage() {
                Object obj = body.getPayload();
                System.out.println(obj.toString());
            }
        };
    }
}

public class HelloWorld {
      public static void main(String[] args) {
            MessageBody mb = new MessageBody();
            mb.configure("Hello World!");
            AbstractStrategyFactory asf = DefaultFactory.getInstance();
            MessageStrategy strategy = asf.createStrategy(mb);
            mb.send(strategy);
      }
}

* Extraído de http://seenonslash.com/node/465

Porque eu odeio frameworks…

Decidi construir uma prateleira de temperos. Como já fiz pequenos projetos com madeira anteriormente, acredito ter uma boa ideia do que eu vou precisar: um pouco de madeira e algumas ferramentas básicas, como fita métrica, serra, nivelador e um martelo.

Vou até uma loja de ferramentas para comprar o que preciso e pergunto ao atendente onde encontro um martelo.

– Um martelo? – ele pergunta. Na verdade ninguém mais compra martelos. Eles estão meio fora de mora.

Surpreso com essa mudança, pergunto a ele o por quê.

– Bem, o problema com martelos é que existem muitos tipos diferentes: do tipo marreta, o tradicional (com as duas pontas para tirar pregos), o de cabeça arredondada, o de borracha e assim por diante. E se você comprar um tipo de martelo e depois perceber que precisava de outro tipo? Você teria de comprar outro martelo. Sendo assim, a maioria das pessoas queria apenas um único martelo que pudesse executar todos os tipos de marteladas que você possa conhecer em sua vida.

– Suponho que isso seja bom. Pode me mostrar onde encontro o “martelo universal”?

– Não, nós não vendemos ele mais. Estão obsoletos.

– Sério? Mas você acabou de me dizer que o “martelo universal” é a onda do futuro.

– Descobrimos que, se você faz um tipo de martelo capaz de fazer todos os tipos de tarefas de todos os tipos de martelos, ele na verdade não é tão bom em nenhuma tarefa. Pregar um prego com uma marreta não é muito eficiente. E, se você quer matar sua ex-namorada, não há melhor substituto do que o martelo com cabeça arredondada.

– Isso é verdade. Mas então, se ninguém compra mais “martelos universais” e você não vende mais os martelos tradicionais, que tipo de martelos você vende?

– Na verdade, nós não vendemos nenhum martelo.

– Então…

– Conforme nossas pesquisas, o que as pessoas realmente precisavam não era um “martelo universal”, no fim das contas. Sempre foi melhor ter o tipo de martelo adequado para o trabalho. Então nós começamos a vender fábricas de martelos capazes de produzir qualquer tipo de martelo que você possa se interessar em usar. Tudo o que você precisa fazer é preencher a fábrica de martelos com trabalhadores, ativar a maquinaria, comprar a matéria prima dos martelos, pagar as contas e, voilà, você terá exatamente o tipo de martelo que precisa na hora!

– Mas eu não queria comprar uma fábrica inteira de martelos.

– Isso é bom, porque nós também não as vendemos mais.

– Mas você acabou de dizer que…

– Nós descobrimos que a maioria das pessoas realmente não precisa de uma fábrica inteira de martelos. algumas pessoas, por exemplo, nunca precisarão de um martelo com cabeça arredondada (talvez porque não tenham uma ex-namorada ou já usaram um furador de gelo para matá-las). Então, não há razão para alguém comprar uma fábrica de martelos que pode produzir todo tipo de martelo existente debaixo do sol.

– Sim, isso faz muito sentido.

– Então, ao invés disso, nós começamos a vender esquemas para fábricas de martelos, permitindo a nossos clientes construir suas próprias fábricas de martelos, personalizadas para fabricar apenas os tipos de martelos que eles iriam precisar.

– Deixe-me adivinhar: vocês não vendem isso mais…

– Não! Certamente não! Descobrimos que as pessoas não queriam construir uma fábrica inteira apenas para fabricar um ou dois martelos. Deixe a construção da fábrica para os especialistas em construção de fábricas, foi o que eu sempre disse!

– E eu tenho que concordar com você.

– Isso. Então nós paramos de vender os esquemas e começamos a vender fábricas de construção de fábricas de martelos. Cada fábrica de fábricas de martelos é construída para você pelos principais especialistas no ramo de fábrica de fábricas de martelos, então você não precisa se preocupar com nenhum detalhe em construir uma fábrica. E ainda assim você tem todos os benefícios de ter sua própria fábrica personalizada, produzindo seus martelos personalizadas rapidamente, de acordo suas próprias especificações de martelo.

– Bem, na verdade, isso não parece…

– Eu sei o que você vai dizer! Nós não vendemos mais isso também. Por alguma razão, poucas pessoas estavam comprando as fábricas de fábricas de martelos, então nós criamos outra solução para resolver o problema.

– Hu-ho!

– Nós analisamos a situação com calma e olhamos para toda a infraestrutura de ferramentas. Então entendemos que as pessoas estavam frustradas em ter que gerenciar e operar uma fábrica de fábricas de martelos, tanto quanto a fábrica de martelos que era produzida. Esse tipo de trabalho adicional pode ficar muito confuso quando você lida com um cenário provável de também ter que operar uma fábrica de fábricas de fitas métricas, uma fábrica de fábricas de serras e uma fábrica de fábrica de niveladores, sem mencionar o conglomerado de fabricação de chapas de madeira. Quando nós olhamos a situação com a devida atenção, vimos que era tudo muito complexo para alguém que quer apenas construir uma prateleira de temperos.

– Nem me diga!

– Então, nesta semana, nós estamos introduzindo no mercado a fábrica de fábricas de fábricas de ferramentas de propósito geral, de forma que todas suas diferentes fábricas de fábricas de ferramentas podem ser produzidas por uma única fábrica unificada. A fábrica de fábricas de fábricas não irá apenas produzir as fábricas de fábricas de ferramentas que você precisa, mas cada uma das fábricas de fábricas irão produzir fábricas únicas baseadas nas suas especificações personalizadas de ferramentas. O conjunto final de ferramentas que irão emergir desse processo serão as ferramentas ideias para o seu projeto em particular. Você terá exatamente o martelo e a fita métrica que precisa para sua tarefa, tudo com o simples pressionar de um botão (embora você tenha ainda que implantar alguns “arquivos de configuração” para fazer tudo isso funcionar de acordo com suas expectativas).

– Então, você não tem nenhum martelo? Nenhum mesmo?

– Não. Se você quer mesmo uma prateleira de temperos de alto padrão e de acordo com as especificações da indústria, você precisa urgentemente de algo mais avançado do que um simples martelo de uma lojinha de ferramentas.

– Isso é o que todos estão fazendo agora? Todo mundo está usando uma fábrica de fábricas de fábricas de ferramentas de propósito geral, sempre que precisam de um martelo?

– Exato!

– Tudo bem, Acho que vou querer uma dessas também. Se é assim que todos estão fazendo, acho melhor aprender dessa forma.

– Vai ser bom pra você.

– Vem com manual, né?


Trecho extraído de http://discuss.joelonsoftware.com/?joel.3.219431.12

Creative Commons O blog State of the Art de Luiz Ricardo é licenciado sob uma Licença Creative Commons. Copie, compartihe e modifique, apenas cite a fonte.