sábado, 16 de outubro de 2010

PostgreSQL 9.0 - Instalando no Ubuntu 10.04

É faz tempo que não posto nada e já estava até nem ligando mais, mas hoje fiquei brincando e configurando o PostgreSQL no trabalho e gostei muito. Já mexia antes com a versão 8.3 mas resolvi baixar hoje a 9.0 para configurar o Alfresco nela e gostei muito. Principalmente com o pgAdmin 1.12.1 que vem junto com o instalador para Windows.

Chegando em casa liguei o pc e deu vontade de tentar configurar o PostgreSQL no meu Ubuntu, mas tive alguns probleminhas então logo surgiu uma ótima ideia - "porque não fazer um post?" ehehehe ... bem vamos lá.

Bom antes de mais nada é preciso que você instale o seguinte pacote:
$ sudo apt-get install python-software-properties
Depois de feito isso vamos a velha e já boa conhecia atualização de repositórios :D. Basicamente para instalarmos o PostgreSQL 9.0 e o pgAdmin 1.12 precisamos utilizar os seguintes comandos:
$ sudo add-apt-repository ppa:pitti/postgresql                            $ sudo apt-get update                                                     $ sudo apt-get install postgresql-9.0 libpq-dev pgadmin3
Feito isso seu banco de dados já está em funcionamento e o pgAdmin já está instalado e possui um icone de atalho no seu menu. Mas mesmo depois disso ainda tive um problema ao tentar conectar no banco, não sei a senha :(.

Para isso basta digitar no terminal:
$ cd /etc/init.d/                                                          $ sudo -u postgres plsl postgres
Feito isso você estará no plql ai basta alterar a senha via linha de comando, que no meu caso mudei para postgres mesmo. Fiquei um bom tempo tentando o que os tutoriais indicavam para digitar o comando:
postgres=# ALTER USER postgres WITH PASSWORD 'postgres'                postgres=# \q
Mas o que funcionou mesmo foi um bem mais simples:
postgres=# \password postgres                                              Enter new password:                                                    Enter it again:                                                           postgres=# \q
Depois disso você ainda precisa realizar algumas configurações no seu banco de dados, para isso é necessário editar o arquivo postgresql.conf que está no diretório /etc/postgresql/9.0/main/, nele altere as seguintes linhas para:
listen_addresses = '*'                                              password_encryption = on
Desta forma, o PostgreSQL vai poder responder as requisições provenientes de outras máquinas e também cifrará as senhas. Lembre-se de remover o # para descomentar a linha. Mas você ainda precisa configurar o seu ip ou a rede que poderá acessar o banco de dados, para isso edite o arquivo pg_hba.conf no diretório /etc/postgresql/9.0/main/ e adicione a nova configuração lá em baixo, a minha por exemplo foi:
#My Ip                                                                   host    all      all             192.168.1.102/24         md5
Agora antes de reiniciar o serviço eu sugiro que você libere a edição dos arquivos de configuração do PostgreSQL usando o chmod, exemplo:
$ sudo chmod 777 /etc/postgresql/9.0/main/pg_hba.conf                     $ sudo chmod 777 /etc/postgresql/9.0/main/postgresql.conf 
Pronto agora você pode reiniciar o serviço e começar a usar
$ sudo /etc/init.d/postgresql restart
Exemplo da minha configuração no pgAdmin



domingo, 25 de julho de 2010

NS-2 - Instalando no Ubuntu 10.04

Bom se você é assim como eu que sempre quando vai começar algo novo e não faz nem idéia por onde começar, abre o navegador e busca por alguém tenha a mesma dúvida que a sua ou um tutorial de um nobre ser que gastou seu tempo para que nós meros mortais pudessemos continuar a boa e velha mata ehehehe (claro que não é bem assim mas...).

Bom mas vamos ao que interessa, neste post eu vou reescrever umas coisas que uma vez eu li no blog do arthurfurlan mas agora não o encontro mais. O tópico era sobre a instalação do Network Simulator no Ubuntu. Eu até procurei no Google e achei um outro post dele no Viva Linux que ele dava um geral (o do blog dele estava melhor ... tinha mais detalhes e comentários). Estranho que sumiu, bom foi por esse motivo que resolvi escrever o post parecido e aproveitando e já atualizando a versão do Ubuntu da 7.10 para a 10.04 e também a do NS-2.30 para NS-2.34.

Antes de tudo precisamos instalar alguns pacotes para poder compilar corretamente o NS-2.34.
$ sudo apt-get install build-essential autoconf automake libxmu-dev gcc-4.4
Próximo passo vamos baixar o NS-2.34.
$ wget http://ufpr.dl.sourceforge.net/sourceforge/nsnam/ns-allinone-2.34.tar.gz
Termiando o download podemos então descompactar os arquivos e finalmente instalar o Simulador de Rede.
$ tar xzvf ns-allinone-2.34.tar.gz                                        $ cd ns-allinone-2.34/                                                    $ ./install
Agora o NS-2 vai ser compilado e instalado no Ubuntu, isso demora alguns minutos então se quiser fazer outras coisas sinta-se a vontade.

Ao final se tudo ocorrer bem aparecerá no console para que você faça a validação da instalação mas se por algum a caso no processo de instalação for verificado algum erro, como por exemplo: make: *** [libotcl.so] Error 127 otcl-1.13 make failed! . Não se assute pode ser que na hora da compilação o compilador não foi selecionado corretamente, neste caso de uma olhada neste link que explica uma simples solução para o caso. Lembrando que em vez de usar a gcc-4.3 que ele demosntra use a gcc-4.4 que você baixou inicialmente.

Agora para que possamos usar o NS-2 normalmente teremos que configurar algumas variáveis de ambiente.
$ OTCL_LIB=~/ns-allinone-2.34/otcl-1.13                                   $ NS2_LIB=~/ns-allinone-2.34/lib                                          $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$OTCL_LIB:$NS2_LIB              $ export TCL_LIBRARY=~/ns-allinone-2.34/tcl8.4.18/library                 $ PATH=$PATH:~/ns-allinone-2.34/ns-2.34/
Feito isso podemos ir para faze final e validar a instação do NS-2. A já aviso que isso demora. Então se tiver que ir no mercado ou quiser assistir um filme vá em frente. Digite os comando no shell e bom divertimento.
$ cd ns-2.34/                                                             $ ./validate 
Pronto agora você tem o simulador instaldo no seu Ubuntu 10.04 e pode aproveitar para fazer suas modificações nos procolos ou mesmo se aventurar e implementar um nele como eu vou fazer eheheheh. Abraços e até a próxima.

domingo, 20 de junho de 2010

Hibernate - Visão básica das annotation

Bom é isso vamos a mais um post e desta vez vamos falar as anotações usando o Hibernate.

Antes de mais nada vale ressaltar que para você configurar o Hibernate na sua aplicação não necessariamente você precisa usar JPA, isto é, annotation ou anotações. As configurações do banco poderiam muito bem serem feitas usando os arquivos hbm.xml, mas como isso (no meu caso) é muito chato de fazer vamos para as annotation.

Para quem tiver o interesse ou já usa mas não sabe, o Hibernate oferece uma API que serve para eliminar de vez o uso dos complexos arquivos hbm.xml para simplificar o desenvolvimento das aplicações e facilitar a manutenção. Isso graças a vantagem de que toda essa configuração fica na classe e não em arquivos separados que em muitos caso não é de fácil entendimento.

1. @Id : é a anotação de atributo que o identifica como uma chave primaria.

2. @GeneratedValue  : é a anotação de atributo que faz com que a chave primaria tenha seu valor gerado automaticamente. em geral essa anotação vem acompanhada por @Id.

3. @Entity : é uma anotação de classe que diz que o objeto em questão possui uma tabela associada no banco de dados.

4. @Table (name="table") : anotação de classe que diz o nome da tabela a qual o objeto está mapeado. Ela não é obrigatória e por tanto se não for declara a tabela terá p mesmo nome do objeto.

5. @Column (name="column", nullable=false, length=32) : anotação de atributo que o relaciona a uma coluna da tabela atribuindo as características da coluna não poder conter um valor nulo e o seu tamanho não pode passar de 32 bytes. Essa anotação não é obrigatória e por tanto se não for declara a coluna terá o mesmo nome do atributo, podendo conter valor nulo de tamanho definido no banco.

6. @Lob : anotação de atributo que identifica que ele é um tipo Clob ou Blob.

7. @OneToMany (mappedBy="order", cascade=CascadeType.ALL, fech=FetchType.LAZY)
    @OrderBy (value="id ASC")
      - anotações de atributo que declaram que é uma relação de 1-N. A anotação @OrderBy não é obrigatória.

    @ManyToOne (cascade=CascadeType.REFRESH, optional=false)
    @JoinColumn (name="order_id")
       - anotação de atributo que declara que é uma relação de N-1. A anotação @JoinColumn só é necessário quando não houver explicitamente um campo que una as duas tabelas.

8. @Temporal (value=TemporalType.DATE) : anotação de atributo que descreve a precisão esperada no banco de dados.

9. @OneToOne (optional=true, cascade=CascadeType.ALL, mappedBy="person") : anotação de atributo que o associa a um objeto também mapeado por @Entity. Há casos em que é necessário utilizar a anotação @JoinColumn para dizer explicitamente a associação, exemplo:
   @OneToOne (optional=false, cascade=CascadeType.ALL, mappedBy="person")
   @JoinColumn (name="Person_ID", referencedColumnName="personid", unique=true)
    - anotação de atributo 1-1.

10. @ManyToMany (mappedBy="students") : anotação de atributo que declara que é uma relação de N-N. Há casos em que é necessário utilizar o @JoinColumn para dizer explicitamente a associação, exemplo:
     @ManyToMany (cascade=CascadeType.PERSIST, fetch=FeatchType.LAZY)
     @JoinColumn (name="Teacher_Student",
             joinColumns = (@JoinColumn (name="Teacher_ID", referencedColumnName="teacherid")),
             inverseJoinColumns = (@JoinColumn (name="Student_ID", referencedColumnName="Studentid")))

11. @Transient : anotação de atributo que que indica que ela não está mapeada na tabela e deve ser ignorada.

12. @Cache (usage=CacheConcurrencyStrategy.READ_WRITE) : anotação de classe que indica que para essa aplicação o objeto em questão usa cache.

terça-feira, 4 de maio de 2010

Pivot - Hello World com Maven

Saudações Rangos!

Esse post vai tratar de ajudar a fazer seu primeiro "hello world!" no Apache Pivot. Deve estar se perguntando o porque disso? Bom é simples. O tutorial que tem no site oficial está errado! E também vou aproveitar para dar uma desenferrujada e digitar um pouco ... eheheheh.

Bom para inicio de conversa eu estruturei meu exemplo no Maven. Porque? Porque eu gosto da maneira que o Maven gerencia minhas dependências de outros jars, segue o meu POM:

<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>net.sf.gaia.test</groupId>
    <artifactId>pivot-tutorial</artifactId>
    <name>Pivot Maven Tutorial</name>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.apache.pivot</groupId>
            <artifactId>pivot-core</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.pivot</groupId>
            <artifactId>pivot-wtk</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.pivot</groupId>
            <artifactId>pivot-web</artifactId>
            <version>1.4</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <inherited>true</inherited>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
    </build>
</project>


Basicamente no POM eu adicionei as dependências utilizada no tutorial para compilar a classe. E também adicionei o pluging para compilar utilizando o Java 6 com codificação de texto UTF-8.

A classe de exemplo eu usei a mesma que está no site oficial Apache Pivot - Hello World, mas segue ele ai:

package org.apache.pivot.tutorials;

import java.awt.Color;
import java.awt.Font;

import org.apache.pivot.collections.Map;
import org.apache.pivot.wtk.Application;
import org.apache.pivot.wtk.DesktopApplicationContext;
import org.apache.pivot.wtk.Display;
import org.apache.pivot.wtk.HorizontalAlignment;
import org.apache.pivot.wtk.Label;
import org.apache.pivot.wtk.VerticalAlignment;
import org.apache.pivot.wtk.Window;

public class HelloJava implements Application {
    private Window window = null;
 
    @Override
    public void startup(Display display, Map<String, String> properties) {
        Label label = new Label();
        label.setText("Hello World!");
        label.getStyles().put("font",
new Font("Arial", Font.BOLD, 24));
        label.getStyles().put("color", Color.RED);
        label.getStyles().put("horizontalAlignment", HorizontalAlignment.CENTER);
        label.getStyles().put("verticalAlignment", VerticalAlignment.CENTER);
 
        window = new Window();
        window.setContent(label);
        window.setTitle("Hello World!");
        window.setMaximized(true);
        window.open(display);
    }
 
    @Override
    public boolean shutdown(boolean optional) {
        if (window != null) {
            window.close();
        }
 
        return false;
    }
 
    @Override
    public void suspend() {
    }
 
    @Override
    public void resume() {
    }
 
    public static void main(String[] args) {
        DesktopApplicationContext.main(HelloJava.class, args);
    }
}


O que mais incomodo não foram nem o Maven e nem o classe. O que estava errado mesmo era o código HTML para adicionar a Applet e ver o exemplo funcionando. Tudo por causa de um que no tutorial era dito para usar o parâmetro "applicationClassName" quando na verdade era para ser usado "application_class_name". Esse simples troca já da uma dor de cabeça, segue como ficou:

<applet code="org.apache.pivot.wtk.BrowserApplicationContext$HostApplet" archive="lib/pivot-core-1.4.jar,lib/pivot-wtk-1.4.jar,lib/pivot-wtk-terra-1.4.jar,lib/pivot-tutorial-1.0-SNASHOT.jar" width="400" height="200" >
     <param name="application_class_name" value="org.apache.pivot.tutorials.HelloJava" >
</applet>


domingo, 2 de maio de 2010

Java - Manipulação de String

E ai pessoal, passei na SCJP e finalmente consegui tempo para terminar esse post ehehe :D ... Valeu ai a toda ajuda, mas agora voltando aos post queria falar um pouco sobre algo que me chamou muita atenção no estudo de Java - Manipulação de String. Parece simples né? Na verdade não é bem assim, vou justificar.

Todo mundo sabe que em Java você tem dois tipo de variáveis de referência, uma para tipos primitivos: int, float, double, boolean, char, shot e long(não sei se esqueci de algum) e outra que são referências aos objetos, isto é, as classes em si que você utiliza no seu dia a dia.

Essas classes em especial por padrão estendem a classe Object, isso é, todas os objetos no Java são derivados da classe Object (menos a propia Object ... obvio né ehehehe).

Mas tá e porque escrever um post sobre a classe String? Que que ela tem de diferente? Bom é que diferente dos outros objetos a uma String só pode ser criada uma vez, ela nunca poderá ser modificada. Então o que acontece quando um objeto String parece estar se modificando? Vamos ao exemplo:

String ola = "Ola!";

Vejamos, o que temos é uma variável de nome ola que serve se referência para um objeto String com valor "Ola!", até ai tudo bem né? Mas se continuarmos:

String olaAux = ola;
ola = ola.concat(" Como vai?");
if (ola.equals(olaAux))
      System.out.print("Igual");
else
      System.out.print("Diferente");


Uh que código mais tosco deve estar pensando hehehe ... Mas e ai, o que vai aparecer na saída? Resposta: "Diferente". Pode testar se não acreditar.

Intrigado? Bem isso é normal, mas lembre-se que comentei que uma variável String nunca pode ser modificada, então o que aconteceu? Simples, Quando criamos a variável se referência olaAux a atribuímos o valor de ola. Depois quando usamos o método concat adicionamos no final da String o valor " Como vai?", mas como String não pode ser mudada a JVM cria uma nova instância de String somando os dois valores "Ola!" e " Como vai!". Assim a variável ola passa a apontar para uma nova instância se String com valor "Ola! Como vai?", enquanto que olaAux continua apontando para "Ola!".

Vale destacar que a JVM cria uma lista da memória de todas as Strings que são criadas, isso quer dizer que no nosso exemplo foram criadas cinco Strings nessa lista. Cinco? Sim! Cada String criada no texto é adiciona na lista, são elas: "Ola!", " Como vai?", "Ola! Como vai?", "Igual" e "Diferente".

A JVM cria essa lista como uma forma de otimizar a utilização de memória, assim se diversas variáveis de String precisarem utilizar o mesmo conteúdo elas irão apontar para a mesma referência e não ficar criando novas instâncias todas as vezes que precisar.

Bom esse foi só um breve resumo, se quiserem mais detalhes o livro do SCJP tem um capitulo inteiro sobre Strings. Até mais!

segunda-feira, 29 de março de 2010

jQuery - Boas práticas com FreeMarker/Velocity

Primeiramente é bom estar escrevendo novamente hehehe. Faz tempo que queria postar algo mas sempre (por algum inconveniente ou destino) ficava sem tempo. Bom vamos lá ...
Antes de tudo tu já deves ou pelo menos tem uma noção de para que utilizamos ferramentas como Freemarker ou mesmo o Velocity? Não?? ... Eu gosto de falar deles com geradores de código HTML em tempo de execução, isto é, essas ferramentas me possibilitam criar componentes em código HTML a partir de um modelo pré-definido. Conseguiu entender agora? Se a reposta ainda é não fique tranquilo, isso é mais fácil do que parece.
Bom, nada melhor do que um exemplo não é? Então supondo que o modelo gere um código HTML onde eu tenho um Label (contendo a tescrição do item) e um Input (que receberá valores passados pelo usuário), algo mais ou menos assim:

O código Java por sua vez irá passar alguns váriáveis para o modelo. Neste exmplo vou usar o Velocity, segue:

VelocityContext context = new VelocityContext();
context.put("id", "my_velocity_id"); //id padrão
context.put("isEditable", true); //se o Input pode ser editado

context.put("text", "Descrição do Item"); //adicionado a Label
context.put("value", "Valor do Item"); //adicionado ao Input

StringWriter w = new StringWriter();
Velocity.mergeTemplate("myTemplate.vm", "UTF-8", context, w);

E por sua vez temos o código do arquivo myTemplate.vm:
<center>
     <div style="border:1px solid black; padding: 2px 2px 2px 2px">
        <label id="${id}_label_">${text}</label> <input id="${id}_input_" value="${value}" />
     </div>
</center>

Espero que você que estava meio em dúvida se tinha entendido ou não tenha compreendido como isso funciona. Senão não adianta continuar hahaha ... brincadeira.
Exemplinho até agora foi bonito mas não falamos nada de jQuery, bom se você prestou atenção viu que meu código Java está passando um parâmetro que não está sendo utilizado no Velocity. Consegue descobrir? ... hehehe ... se olhar bem verá que tem o parâmtro isEditable não é usado de modo algum no myTemplate.vm. Mas então para que serve? Bom se você lembra o assunto do tópico verá que queremos usar jQuery no nosso Velocity, para isso vamos usar o parâmetro isEditable para gerar um código JavaScript e modificar o nosso Input, tudo isso usando uma linha do jQuery :D ... segue o novo myTemplate.vm:
<center>
     <div style="border:1px solid black; padding: 2px 2px 2px 2px">
        <label id="${id}_label_">${text}</label> <input id="${id}_input_" value="${value}" />
     </div>
</center>
## Se isEditable for false
#if (!${isEditable})
  <script type="text/javascript">
     ## modo normal de utilizar no Velocity -- funciona!
     $("#"+"${id}_input_").attr("readonly","readonly");
  </script>
#end

Repare que em vez de eu usar o seletor do jQuery como uma só string acabei separando em duas: "#" e "${id}_input_". Isso porque se o # ficar ao lado do $ a API não irá gerar corretamente a tag, causando um transtorno e que sem dúvida o fará perder muito tempo.
Note que # e $ são palavras a ferramenta também utiliza internamente. Por isso alguns sites aconselham que em vez de usar: $(seletor), utilizar a forma extença jQuery(seletor).


quarta-feira, 24 de fevereiro de 2010

jQuery - Usando Seletores

Primeiramente você deve se perguntar é qual a vantagem em usar os seletores do jQuery? Alguns vão lhe responder que são mais rápidos, mas na verdade depende do seletor que você usar e também em qual browser está executando a aplicação.

Uma boa leitura para essas dúvidas sobre a performance pode ser vista em: 101 on jQuery Selector Performa. Nela o autor testa os usos de seletores usando id, class e tags-name. Mas pelo que entendi dos resultados ele testou esse seletores com uma versão mais antiga do jQuery. Pelo que se nota nas ultimas atualizações os seletores estão cada vez mais rápidos, como vemos no comparativos das versões 1.3.2, 1.4.1 e 1.4.2:




Mas continuando, a baixo segue a lista de seletores que podemos utilizar:

SeletorExemploDescrição

*$(’*');Este seletor retorna todos os elementos do DOM.
#id$(’#id’);Este seletor retorna todos os elementos que contenham o mesmo do ID passado.
.class$(’.class’)Este seletor retorna todos os elementos que possuam o class name passado.
element$(’element’)Este seletor retorna todos os elementos do mesmo tipo de acordo com o tag name. Ex de tag name: table, ul, li, a etc.
a, b, c. … n$(’th, td, .class, #id’)Este método pode ser usado para selecionar multiplos elementos.
parent child$(’li a’)Seleciona todos os "a" elementos que estão contidos no elemento "li".
a > b$(’table > tr’);Irá selecionar todos "tr" elementos que são filhos de "table".
a + b$(’li + a’);Seleciona todos os "a" elementos que estão imediatamente após os elementos "li".
a ~ b$(’p ~ ul’);Seleciona todos os elementos "ul" que vierem depois de "p".
:first$(’ul li:first’);Retorna o primeiro elemento.
:last$(’ul li:last’);Retorna o último elemento.
:not(a)$(’input:not(:checked)’);Retorna todos os "input" elementos que não estão "checked".
:has(a)$(’div:has(p)’);Retorna todos os "div" elementos que contenham "p".
:odd$(’ul li:odd’);Retorna todos os elementos impares da lista.
:even$(’ul li:even’);Retorna todos os elementos pares da lista.
:eq(n)$(’ul li:eq(n)’);Retorna o "n" elemento.
:gt(n)$(’ul li:gt(n)’);Retorna todos os elementos que estão após "n".
:lt(n)$(’ul li:lt(n)’);Retorna todos os elementos que estão antes de "n"
:header$(’:header’);Retorna todos elementos que são titulos. Ex; h1, h2, etc.
:animated$(’ul:animated’);Retorna todos os "ul" elementos que são com uma animação em processo.
:contains(text)$(’:contains(hello)’);Retorna todos os elementos que contenham o texto "hello".
:empty$(’:empty’);Retorna todos os elementos que não contenham filhos.
:parent$(’li:parent’);Retorna o elemento pai do elemento "li".
:hidden$(’ul:hidden’);Retorna todos os "ul" que estão escondidos (hidden)>
:visible$(’ul:visible’);Retorna todos os "ul" que são visíveis
[attribute]$(’[href]‘);Retorna todos os elementos que contenham o atributo "href".
[attribute=value]$(’[rel=external]‘);Retorna todos os elementos que contenham o atributo "ret" com o valor "external".
['attribute!=value']$(’[rel!=external]‘);Retorna todos os elementos que contenham o atributo "ret" sendo que o valor não pode ser "external".
[attribute^=value]$(’[class^=open]‘);Retorna todos os elementos que contenham o atributo "class" e que valor desse inicie com "open".
[attribute$=value]$(’[id$=-wrapper]‘);Retorna todos os elementos que contenham o atributo "id" e que valor desse termine com "-wrapper".
[attribute*=value]$(’[class*=offer]‘);Retorna todos os elementos que contenham o atributo "class" e que valor desse possua a string "offer".
:input$(’:input’);Retorna somentos os elementos de input, isto é: input, select, textarea e button
:text$(’:text’);Retorna somente os elementos de tipo "text".
:password$(’:password’);Retorna somente os elementos de tipo "password".
:radio$(’:radio’);Retorna somente os elementos de tipo "radio".
:checkbox$(’:checkbox’);Retorna somente os elementos de tipo "checkbox".
:submit$(’:submit’);Retorna somente os elementos de tipo "submit"
:image$(’:image’);Retorna somente os elementos de tipo "image"
:reset$(’:reset’);Retorna somente os elementos de tipo "rest".
:file$(’:file’);Retorna somente os elementos de tipo "file".
:button$(’:button’);Retorna somente os elementos do tipo "button".
:enabled$(’:enabled’);Retorna todos os elementos que estão "enabled".
:selected$(’:selected’);Retorna os elementos que está selected da lista de select.
:disabled$(’:disabled’);Retorna todos os elementos que estão "disabled".
:checked$(’:checked’);Retorna os elementos que estão "checked" (radio ou checkbox).



terça-feira, 23 de fevereiro de 2010

Maven - Estrutura básica de um POM

Dando continuação ao Maven vamos começar a pensar em algo mais, por exemplo, vou mostrar como construí o POM base dos meus projetos, chamado de: Gaia Parent.

Primeiramente num projeto Maven precisa-se de basicamente 3 coisas:
- groupId: indica a qual grupo de projetos este projeto faz parte;
- artifactId: caracteriza o projeto atual;
- version: indica a versão na qual este projeto se encontra.

No Gaia Parent:
- groupId: net.sf.gaia
- artifactId: gaia-parent
- version: 1.0

Logo teriamos basicamente o seguinte XML:
<project>
    <modelVersion>
4.0.0</modelVersion>
    <artifactId>
gaia-parent</artifactId>
    <groupId>
net.sf.gaia</groupId>
    <version>
1.0</version>
   
    <name>
Gaia Parent</name>
    <description>
Parent pom for Gaia Projects</description>
    <packaging>
pom</packaging>
</project>
Esse simples XML já define o projeto do Gaia Parent no Maven, onde não será gerado um jar no final da compilação. Veja que a tag packaging define se o projeto será apenas (como dizer? ...) um projeto de definições (pom). Se eu possuí-se códigos Java e necessitá-se que no final do processo de compilação fosse gerado um jar, teria que alterar a tag para: jar.

Mas se alguém tentar compilar este projeto nesse momento verá que ele não tem nenhuma serventia, pois não nos diz nada!

Bom, como nada? Bem é simples, o projeto Gaia Parent tem como função ser o projeto pai de todos os meus projetos. Como assim? Resposta simples: "Eu quis assim!"

Continuando, como sendo sendo um projeto na qual todos meus outros projetos farão uso eu preciso que ele possua algo que todos possam usar e que não atrapalhe a compilação dos projetos. Por isso estruturei que o Gaia Parent armazena-se principalmente a lista de repositórios de onde todos os projetos possam buscar suas dependências sem nenhum problema.

Não vou postar toda a lista de dependência, até porque ela é bem grandinha. Mas se você fizer questão de ver ou mesmo tiver o interesse de adicionar algumas no seu projeto, sugiro que olhe o POM que está versionado no SVN: download.

E para que não está com tanto saco assim de baixar o POM e olhar detalhadamente fica a versão mais compacta a baixo:
<project>
    <modelVersion>
4.0.0</modelVersion>
    <artifactId>
gaia-parent</artifactId>
    <groupId>
net.sf.gaia</groupId>
    <version>
1.0</version>
   
    <name>
Gaia Parent</name>
    <description>
Parent pom for Gaia Projects</description>
    <packaging>
pom</packaging>
   
    <repositories>
        <repository>
            <id>
ibiblio</id>
            <name>
ibiblio Maven 2 Repository</name>
            <url>
http://mirrors.ibiblio.org/pub/mirrors/maven2</url>
        </repository>
       
        <repository>
            <id>
ibiblio legacy</id>
            <name>
ibiblio Maven 1 Repository</name>
            <url>
http://mirrors.ibiblio.org/pub/mirrors/maven</url>
            <layout>
legacy</layout>
        </repository>
   
        <repository>
            <id>
central</id>
            <name>
Maven2 Central Repository</name>
            <url>
http://repo1.maven.org/maven2</url>
        </repository>
       
        <repository>
            <id>
codehaus-repository</id>
            <name>
codehaus maven2 repository</name>
            <url>
http://repository.codehaus.org</url>
        </repository>
       
        <repository>
            <id>
MMBase</id>
            <name>
MMBase Maven 2 Repository</name>
            <url>
http://www.mmbase.org/maven2</url>
        </repository>
       
        <repository>
            <id>
Geotools</id>
            <name>
Geotools Maven 2 Repository</name>
            <url>
http://maven.geotools.fr/repository</url>
        </repository>

        <repository>
            <id>
CMS</id>
            <name>
CMS Container repository</name>
            <url>
http://www.cmscontainer.org/files/maven/</url>
            <layout>
legacy</layout>
        </repository>
       
       
<!-- Gaia developer repository for any gaia artifacts -->
        <repository>
            <id>
Gaia-repo</id>
            <name>
Gaia Developer Repository</name>
            <url>
https://gaia-framework.svn.sourceforge.net/svnroot/gaia-framework/gaia-repository</url>
            <releases> <checksumPolicy>
ignore</checksumPolicy> </releases>
            <snapshots> <enabled>
false</enabled> </snapshots>
        </repository>
    </repositories>
</project>


sexta-feira, 19 de fevereiro de 2010

Maven - Introdução

Finalmente um assunto que eu gosto :D. O Apache Maven ou simplemente Maven. Que ele faz? Resposta bonita: "gerencia e automatiza projetos Java".Se fizerem uma rápida busca na net vão ver várias comparações entre o Ant e o Maven, mas para não se confundirem pensem no Ant como um script (similar a um .bat ou um .sh). É comum em ambientes de compilação a utilização dessas duas ferramentas. Em se tratando em definir um ambiente de compilação, o Maven ganha na sua facilidade comparado ao Ant.

O Maven tem sua estrutura definida num arquivo XML, conhecido como Project Object Model (POM). Ele descreve todo o processo de construção de um projeto, suas dependências (bibliotecas que o projeto utiliza), componentes e a sua sequência de construção. O Maven contém tarefas pré-definidas que realizam funções bem conhecidas como compilação e geração de jar.

Uma característica chave do Maven é que ele é construído para trabalhar em rede. O controle de dependência do projeto é transparente ao programador, pois quando iniciado a compilação a ferramenta verifica se há necessidade de baixar um novo jar ou atualizar a sua versão (tudo isso está definido no POM), baixando esse jar de um repositório externo (há vários repositórios de jars free) ou mesmo de um repositório corporativo.

Estrutura de pastas padrão que o Maven aceita (todos os novos projetos que utilizam Maven fazem uso dessa estrutura ... mas ela pode também ser configurada).

 pom.xml           -- Arquivo de configuração do projeto
  src/                  -- pasta raiz
    |
    |---main/           -- tronco principal
    |    |
    |    |---java/      -- código fonte Java
    |    |---resources/   --   recursos (arquivos de configuração, imagens, etc)
    |    |               

    |    |---webapp/    -- aplicação web Java
    |                     
    |---test/           --  tronco de testes unitários e de integração
    |    |---java/      -- código fonte dos testes do JUnit
    |    |---resources/ -- recursos dos testes

Exemplo de projetos que utilizam Maven:
  Glassfish: https://glassfish.dev.java.net/
  JBoss: http://www.jboss.org/
  PDFBox: http://pdfbox.apache.org/
  Velocity: http://velocity.apache.org/
  Axis: http://ws.apache.org/axis/
  CXF: http://cxf.apache.org/
  Felix: http://felix.apache.org/

... o Tomcat tem um projeto começado no Maven ... mas ainda não o adota

Java - Pré-Processadores

Bom antes de tudo o que é um pré-processador? Bem, eu vejo ele como um "if else" do compilador, como assim? Tipo se o argumento que eu passar estiver definido na VM então aquele trecho de código é carregado senão carrega outro ou no para ser mais extremo não carrega nada.

Pré-processadores não são usados no J2SE, pelo menos eu nunca vi! Mas no J2ME não é muito difícil de ver implementações de código que não possuam um ou mais instruções de um pré-processador, ainda mais quando a aplicação é feita para rodar em aparelhos diferentes com APIs nada parecidas.

Para declarar o uso de pré-processador basta iniciar a linha com //# e em seguida escrever o argumento. Como um exemplo sempre é bom e facilita as coisas, segue:

//#ifdef XMOBILE
public class MyApp extends MyCanvas {
//#else
public class MyApp extends Canvas {
//#endif

Veja que esse exemplo é uma quebra em quem está acostumado basicamente com o puro Java. Nesse exemplo acima vemos que se XMOBILE não estiver definido a classe MyApp estenderá Canvas ao invés de MyCanvas, isso muda ela completamente, consegue ver?

Veja que se eu quisesse ser mais radial poderia escolher qual os pacotes que eu vou incluir e quais eu não vou:

//#define MIDP2
//#ifdef MIDP2
import javax.microedition.media.*;
import javax.microedition.media.control.*;
import javax.microedition.media.control.ToneControl;
//#endif
//#ifdef NOKIAUI
import com.nokia.mid.sound.*;
import com.nokia.mid.ui.*;
//#endif
//#ifdef MOTOROLA
import com.motorola.multimedia.*;
//#endif
import javax.microedition.lcdui.*;
import java.io.*;

Veja que agora eu primeiramente defino o que vou usar e depois testo. Isso é só para salientar e melhorar o entendimento sobre o funcionamento. Também não deve se limitar em achar que o //#define MIDP2 deve ser inserido sempre antes do teste, isto é, na mesma classe. Não! Ele pode ser definido a qualquer momento da execução. Uma boa prática é inseri-los na classe que é carregada primeiro pelo MIDlet.

quinta-feira, 18 de fevereiro de 2010

Jad - Decompilador Java

Quem nunca ficou curioso quando após compilar uma classe Java, olhar para o .class gerado e se perguntar: "será que tem como voltar?" Bom meus amigos tem!

Um exemplo é o Jad (JAva Decompiler). Eles é um programa que faz o serviço sujo de decompilar um .class para um .jad (que na verdade é o .java "diferente" ehehe).

Você pode simplesmente baixar o Jad e executa-lo pela linha de comando:
      joppi@joppi:~$ jad MyTest.class

Vai ver que no mesmo diretório apareceu um MyTest.jad, se quiser pode renomear para MyTest.java que não vai ter problema. Esse arquivo já é um arquivo Java semelhante ao original. Sim semelhante!

O Jad também conta com uma interface gráfica, o JadClipse. Sim é um plugin do eclipse! Qualquer dúvida clique aqui ou se preferir ir direto pode usar o update do Eclipse: http://jadclipse.sf.net/update ou baixar o jar no site: http://sourceforge.net/projects/jadclipse.






quarta-feira, 17 de fevereiro de 2010

Ant - Introdução

Vamos a mais um post, mas desta vez é sobre uma ferramenta um pouco mais conhecida (seja de vista ou já tenha ouvido falar), o Apache Ant ou simplesmente Ant.

Tá mas o que é o Ant? Bom eu gosto de pensar no Ant com um script, mesma coisa que um Bat do Windows ou Sh do Linux, só com a diferença que ele é desenvolvido em Java, tem a sua estrutura montada num XML e roda em ambos os sistemas.

O Ant é bastante usado para construção de ambientes de compilação (o que é isso?). Um ambiente de compilação é onde tu vais organizar as sequências de para definir e atualizar o classpath, compilar o código separando os .java e os .class em diretórios distintos, pode também gerar o javadoc do projeto, configurar e executar a aplicação. Tudo isso definido numa sequencia de passos. Resumindo tu vais ter que montar um script que contenha todos esses passos.

Geralmente projetos Open Source mais antigos tem a sua estrutura de compilação montando no Ant, exemplo:

- Xerces: http://xerces.apache.org/
- Log4j: http://logging.apache.org/

- Xalan: http://xml.apache.org/

- TomCat: http://tomcat.apache.org/


Já outrou projetos tem a sua estrutura montada no Ant, mas já utilizam o Maven fazer esse gerenciamente da build, dentre eles são:


- XFire: http://xfire.codehaus.org/

- ServiceMix: http://servicemix.apache.org/

- Open-ESB: https://open-esb.dev.java.net/


Pra terminar um exemplo de uma estrutura Ant que compila um arquivo Java, gera o Jar e o executa:


<?xml version="1.0" encoding="ISO-8859-1" ?>
<
project name="Exemplo Ant" default="compile" basedir=".">
    <target name="compile">
        <echo>Compilando o projeto.</echo>
        <javac srcdir="${basedir}/src" destdir="${basedir}/bin" />
        <echo>Gerando o .jar do projeto.</echo>
        <jar jarfile="${basedir}/dist/HelloAnt.jar" basedir="${basedir}/bin">
            <!-- Tornando o jar executável -->
            <manifest>
                <attribute name="Main-Class" value="exemplo.HelloAnt" />
            </manifest>
        </jar>
        <echo>Executa o projeto.</echo>
        <java jar="${basedir}/dist/HelloAnt.jar" fork="true" />
    </target>
</project>