As práticas de gerenciamento e desenvolvimento ágil estão em evidência ultimamente. Uma boa ferramenta trazida por essa metodologia é o uso de Stand up meetings para informação e gerenciamento. Para maiores informações sobre o assunto acesse esse post.
Eclipse Data Source Explorer
13 Julho 2008Apesar de que esse recurso já estava disponível em versões anteriores do Eclipse, só agora na versão 3.4.0 (Ganymede) surgiu uma necessidade real que me obrigou a testa-lo: minha máquina estava sem uma ferramenta de acesso ao banco de dados.
O recurso de Data Source Explorer fornece algumas facilidades bem úteis para desenvolvedores Java que pretende fazer uso de banco de dados. É claro que para utilizar esse recurso é necessário efetuar algumas configurações básicas, vamos aprender como realiza-las:
1. Localize a aba Data Source Explorer geralmente está na parte inferior do Eclipse, caso não encontre clique no menu WINDOW -> SHOW VIEW -> DATA SOURCE EXPLORER;
2. Na aba Data Source Explorer na opção databases clique com o botão direito do mouse e escolha a opção new;
3. Na tela seguinte é só escolher o banco de dados que se deseja acessar. No exemplo escolhi o PostgreSQL (já que é o único que tenho instalado em minha máquina) - ainda não entendi muito bem como instalar um novo banco, se é que existe essa opção;
4. Na tela seguinte é para definir as opções referentes ao banco de dados escolhido (usuário, senha, banco de dados, etc.) - o interessante é que mesmo escolhendo o PostgreSQL o driver JDBC não está disponível;
Depois desse processo concluído esse processo é possível acessar, criar e remover objetos e até mesmo fazer e restaurar “backups” da estrutura e dos dados do banco.
É evidente que o Data Source Explorer não tem a pretensão de substituir as ferramentas de manutenção de banco de dados, mas seus recursos ajudam bastantes os desenvolvedores Java.
Consultas preparadas com JDBC
25 Maio 2008Pode parecer estranho falar em JDBC quando existem os frameworks e as APIs para o mapeamento objeto relacional (ORM), mas sempre é bom lembrar que apesar de ocasionar um maior tempo de desenvolvimento o JDBC, quando usado corretamente, proporciona uma maior velocidade de execução.
Sempre que uma consulta SQL é enviada para um banco de dados sua String passa por um processo de compilação, onde é verificado se existem erros de sintaxe e é gerado um plano de execução que é executado.
O processo de executar uma consulta SQL tem um custo de tempo e processamento, mas quase todos os bancos de dados fornecem um recurso que permite que uma consulta seja enviada para o banco de dados, seu plano de execução seja compilado e esse possa ser executado diversas vezes, sendo necessário apenas passar os parâmetros para a consulta. Esse recurso é chamado de SQL preparada.
O JDBC fornece a interface PreparedStantement que estende Stantement e é a forma de acessar o recurso de consultas preparadas em Java. Vamos observar um exemplo de uso do PreparedStantement:
Situação: é necessário inserir em um banco de dados um arquivo de um sistema legado que possui os dados de 50.000 clientes da empresa.
1. A classe Cliente possui a seguinte implementação:
public class Cliente {
private Integer codigo;
private String nome;
private String telefone;
private String endereco;// Métodos gets e sets
}
2. A classe que acessa os dados do arquivo é uma implementação da interface Iterator:
import java.io.File;
import java.util.Iterator;
public class Dados<Cliente> implements Iterator<Cliente> {
private File arquivo;
public Dados(File arquivo) {
this.arquivo = arquivo;
}
@Override
public boolean hasNext() {
// Informa se existe outro cliente no arquivo;
}
@Override
public Cliente next() {
// código que retorna um cliente;
}
@Override
public void remove() {
throw new RuntimeException(”Não foi implementado.”);
}
}
Ob.: foi implementado Iterator pois não aconselharia a construção de um método que retornasse uma lista com 50.000 clientes - afinal tudo ficaria em memória.
3. Finalmente a classe alvo desse post o DAO que insere os dados dos clientes no banco:
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class ClienteDao {
private Connection connection;
public ClienteDao(Connection connection) {
this.connection = connection;
}public int inserirRegistros(Dados<Cliente> dados)
throws SQLException {PreparedStatement ps = null;
int quantidade = 0;String consulta = “insert into tbcliente(id, nome, ” +
“endereco, telefone) values(?, ?, ? ?)”;ps = connection.prepareStatement(consulta);
while (dados.hasNext()) {
Cliente cliente = dados.next();
ps.setInt(1, cliente.getCodigo());
ps.setString(2, cliente.getNome());
ps.setString(3, cliente.getEndereco());
ps.setString(4, cliente.getTelefone());quantidade += ps.executeUpdate();
ps.clearParameters();
}
return quantidade;
}
}
Na primeira linha a definição da consulta SQL que desejamos executar:
String consulta = “insert into tbcliente(id, nome, endereco, telefone) values(?, ?, ? ?)”;
Em seguida é executado o comando que solicita que a consulta seja compilada:
ps = connection.prepareStatement(consulta);
O while serve para adquirir todos os clientes do arquivo:
while (dados.hasNext()) {
Cliente cliente = dados.next();
…
Os parâmetros são inseridos a cada iteração:
ps.setInt(1, cliente.getCodigo());
ps.setString(2, cliente.getNome());
ps.setString(3, cliente.getEndereco());
ps.setString(4, cliente.getTelefone());
Limpa os parametros depois de inseridos no banco.
ps.clearParameters();
Sempre que possível faça uso das consultas preparadas em seus sistemas afinal os benefícios são grandes.
Referências:
REESE, George. JDBC e Java. Programação para banco de dados. Capítulo 4. JDBC Avançada. Editora Berkeley. 2001.
Internacionalização com a classe Locale
20 Abril 2008Segundo o Wikipédia, Internacionalização é um processo de desenvolvimento (ou adaptação) de um software em que se busca criar um software que se adapte mais facilmente a determinadas características regionais, legais, culturais e técnicas.
A classe java.util.Locale é destinada a representar regiões geográficas, políticas e culturais na plataforma Java. A principal representação de um Locale é:
import java.util.Locale;
public class Main {
public static void main(String args[]) {
Locale[] idiomas = {new Locale(”pt”),
new Locale(”fr”),
new Locale(”ja”),
new Locale(”en”)
};
for (Locale idioma : idiomas) {
System.out.println(”Idioma: ” +
idioma.getDisplayLanguage());
}
}
}
A saída desse código seria:
Idioma: português
Idioma: francês
Idioma: japonês
Idioma: inglês
O exemplo acima mostrou como criar um objeto Locale utilizando apenas o código do idioma desejado. A definição das siglas de cada idioma encontra-se disponível em: http://ftp.ics.uci.edu/pub/ietf/http/related/iso639.txt.
Uma outra opção de utilização do construtor da classe Locale é acrescentar à definição de idioma o código que representa o país:
import java.util.Locale;
public class Main {
public static void main(String args[]) {
Locale[] idiomas = {new Locale(”pt”, “BR”),
new Locale(”pt”, “PT”),
new Locale(”fr”, “CA”),
new Locale(”fr”, “FR”),
new Locale(”en”, “US”),
new Locale(”en”, “GB”)
};
for (Locale idioma : idiomas) {
System.out.println(”Idioma: ” +
idioma.getDisplayLanguage() +
” - País: ” + idioma.getDisplayCountry());
}
}
}
E a saída desse programa é:
Idioma: português - País: Brasil
Idioma: português - País: Portugal
Idioma: francês - País: Canadá
Idioma: francês - País: França
Idioma: inglês - País: Estados Unidos
Idioma: inglês - País: Reino Unido
O segundo exemplo demonstrou o uso do código do país na criação de um objeto Locale. A definição dos códigos dos países está disponível em: http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html.
A última opção de construtor é o que permite adicionar variantes/dialetos específicos:
import java.util.Locale;
public class Main {
public static void main(String args[]) {
Locale portugues = new Locale(”pt”, “BR”, “WIN”);
System.out.println(portugues.getDisplayName());
}
}
Agora um exemplo com uma classe que tem suporte à localização: a classe DateFormat:
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Locale;
public class Main {
public static void main(String args[]) {
Locale[] idiomas = {new Locale(”pt”, “BR”),
new Locale(”fr”, “FR”),
new Locale(”en”, “US”),
new Locale(”ja”, “JP”),
new Locale(”ko”, “KP”),
new Locale(”de”, “DE”)
};
Calendar c = Calendar.getInstance();
DateFormat dt = null;
for (Locale idioma : idiomas) {
dt = DateFormat.getDateInstance(DateFormat.FULL,
idioma);
System.out.println(idioma.getDisplayName()
+ ” - ” + dt.format(c.getTime()));
}
}
}
Como resultado:
português (Brasil) - Sábado, 19 de Abril de 2008
francês (França) - samedi 19 avril 2008
inglês (Estados Unidos) - Saturday, April 19, 2008
japonês (Japão) - 2008?4?19?
coreano (Coréia do Norte) - 2008? 4? 19? ???
alemão (Alemanha) - Samstag, 19. April 2008
É interessante observar que nós idiomas coreano e japonês existem caracteres não disponíveis.
É importante lembrar que a classe Locale não faz o trabalho sozinha, para tirar proveito da localização é necessário utilizar classes com esse suporte. Boa internacionalização.
Referências:
JANDL, Peter Jr. Mais Java, Internacionalização, Cap: 2. São Paulo: Futura, 2003.
SIERRA, Kathy & BATES, Bert. Certificação Sun para Programador JAVA 5 - Guia de Estudo (Exame 310-055). Alta Books, 2ª. Edição, 2006.
JavaDoc, Locale, disponível em http://java.sun.com/j2se/1.4.2/docs/api/java/util/Locale.html no dia 19/04/2008.
Wikipédia, Internacionalização, disponível em http://pt.wikipedia.org/wiki/Internacionalização no dia 19/04/2008.
Formatação de datas com Java
13 Abril 2008Todos que trabalham com datas não linguagem Java um dia precisarão apresentá-las. O post Formatação de datas usando Java ensina a utilização da classe DateFormat para essa tarefa.
O NetBeans é uma boa opção
31 Março 2008É muito comum observar em fóruns a dúvida de iniciantes sobre qual IDE utilizar, Eclipse ou NetBeans. Construí esse post para expressar/explicar a minha opinião sobre o assunto.
Trabalho com o Eclipse há quase 2 anos, mas sou entusiasta do NetBeans desde a versão 4 e tenho acompanhado atentamente evolução dessa IDE. Procurei escolher a minha IDE favorita de uma forma bem racional.
A idéia da IBM com a construção do Eclipse foi criar uma plataforma de desenvolvimento baseada em plug-ins, dessa forma se uma funcionalidade não existir na IDE qualquer desenvolvedor pode criar um plug-in para a mesma. Logo, o Eclipse na verdade é um contêiner de plug-ins.
Hoje, o Eclipse é a IDE mais usada do mercado, mas esse quadro tende a mudar.
A história do NetBeans começou com a IDE Xelfi construída por dois estudantes da Republica Tcheca, A IDE Xelfi pretendia ser como Delphi para a linguagem Java. A Sun gostou da idéia e comprou a empresa. O nome NetBeans veio da idéia de reutilização de componentes. Em Java os componentes são JavaBeans.
Como IDE, o NetBeans prioriza facilitar o desenvolvimento em Java através de facilidades para implementação de padrões. Como por exemplo:
Desenvolvimento Swing – o Matisse, em minha opinião é sem dúvida nenhuma a melhor ferramenta para desenvolvimento de aplicativos desktop/swing em Java;
Desenvolvimento Web – o NetBeans possuí plug-ins nativos para desenvolvimento em Struts, Google Web ToolKit, JMaki e Para JSF sendo que esse último existe a possibilidade de criar as páginas em modo visual. Como se não fosse não fosse bastante o NetBeans tem um fantástico editor CSS e agora tem facilidades de edição de código JavaScript – somente lembrando, todos esses plug-ins são nativos do projeto NetBeans no máximo é necessário baixar o plug-in pelo auto update;
Persistência de dados – do JNDI ao JPA o NetBeans tem suporte a criação de tabelas, views, índices, chaves estrangeiras e a consultas em modo gráfico (ajuda até quem sabe fazer consultas SQL). Lembrando que no JPA o NetBeans é imbatível.
Outra característica que chama atenção no NetBeans é o suporte ao idioma português do Brasil, apesar do inglês não ser um problema para a maioria dos desenvolvedores esse suporte ajuda muito quem está iniciando.
O NetBeans tem muitas facilidades além das listadas nesse post, porém eu não as conheço suficientemente para comenta-las. Para mais informações visite http://www.netbeans.org/ e http://www.eclipse.org/.
Ao que parece o NetBeans é um projeto em plena atividade e o numero de facilidades que a IDE proporciona aumentou bastante nos últimos anos, se esse quadro se mantiver o NetBeans tende a se tornar a IDE mais utilizada para desenvolvimento em Java.
Programação utilizando Java Assert
19 Março 2008A palavra reservada assert (premissa) representa um recurso que permite ao desenvolvedor testar condições que deveriam ser verdadeiras. Esse recurso foi introduzido na versão 1.4 do Java e apesar de bastante interessante ainda é pouco utilizado.
Existem duas sintaxes possíveis sintaxes para o comando assert:
assert expressão1; - Essa é a sintaxe resumida, para a expressão1 é permitido apenas operações que retorne um valor booleano;
assert expressão1: expressão2; - Na sintaxe completa a expressão1 segue o mesmo princípio da sintaxe resumida, mas, a expressão2 deve retornar um valor que será impresso caso a expressão1 seja falsa.
Uso indicados do comando assert:
Para forçar restrições de parâmetros em métodos privados – não existe a indicação do uso de assertions para validação de métodos públicos, já que nesses, podem receber “qualquer valor” de outros objetos.
Checar saídas de métodos – de acordo com a entrada passada a um método um valor de saída é esperado, essa é uma boa situação para a utilização de um assertion.
Abaixo um exemplo da utilização de uma assertion:
private boolean candidato(String nome, int idade) {
assert (idade 45): “Idade inválida.”;
//restante do código do método
return true;
}
Quando esse método private boolean candidato(String nome, int idade) for chamado com o software em produção os parâmetros já estariam validados por outras classes da regra de negócio, portanto, o desenvolvedor supõe que o método candidato nunca teria idade fora do intervalo entre 18 e 45 anos, porém no desenvolvimento é interessante efetuar essa verificação debug.
Sempre que um código com assert é executado e a expressão1 é falsa é lançado um AssertionError que é a indicação de um problema na “premissa” utilizada pelo programador. Um AssertionError nunca deve ser capturado pelo programador.
A checagem de assertions está desabilitada por padrão, as linhas com as instruções de assert são inseridas no código compilado são executadas somente se passado o parâmetro enabledassertions no interpretador Java.
Somente lembrando, Assertions não são mecanismos de tratamento de erros, seu propósito é melhorar a disciplina na fase de desenvolvimento.
Utilizando a classe Robot
16 Março 2008Depois de mais uma das intermináveis discussões sobre o que dá para se fazer em java e o que não dá para fazer em java. Fui obrigado a pesquisar a classe java.awt.Robot.
A classe Robot está presente no Java desde a versão 1.4.2 e segundo a definição no JavaDoc essa classe é utilizada para gerar input no sistema operacional nativo. Como possível uso o JavaDoc indica a automação de tarefas, apresentação de demos de sistemas e geração de testes.
A classe Robot possui um construtor padrão e outro onde é possível determinar qual o dispositivo de saída padrão (geralmente é o vídeo mas pode ser a impressora). Essa classe possui 15 métodos que eu classificaria da seguinte forma:
Eventos de Teclado:
void keyPress(int keycode) – utilizado para simular o pressionamento de uma tecla;
void keyRelease(int keycode) – remove o status de pressionada de uma tecla utilizada pelo método keyRelease;
Eventos de Mouse:
void mouseMove(int x, int y) – move o mouse para o posição x,y;
void mousePress(int buttons) – pressiona um dos botões do mouse;
void mouseRelease(int buttons) – remove a pressão efetuada pelo método mouseRelease(int buttons);
void mouseWheel(int wheelAmt) – Indica o número de vezes que o scroll será utilizado (aceita valores negativos).
Eventos de Vídeo:
BufferedImage createScreenCapture(Rectangle screenRect) – Captura a imagem existente na tela (na verdade no dispositivo padrão de saída);
Color getPixelColor(int x, int y) – captura a cor do pixel na posição x,y;
Métodos Acessórios:
void delay(int ms) – deixa o a instância de Robot parada (sleeping) por int milisegundos;
void setAutoDelay(int ms) – informa o tempo que a instância da classe Robot deve esperar depois de gerar um evento;
int getAutoDelay() – obtém o valor do autodeley da instância de Robot;
void waitForIdle() – Aguarda até que todos os eventos que estão na fila sejam processados;
void setAutoWaitForIdle(boolean isOn) – define se a instância sempre deve aguardar se todos os eventos da fila sejam processados;
boolean isAutoWaitForIdle() – verifica o estado do autoWaitForIdle;
String toString() – esse método dispensa comentários.
Agora vamos a um exemplo de utilização dessa classe – O exemplo de código abaixo abre a calculadora digita 25+12= e copia o resultado abre o bloco de notas e cola o resultado:
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.io.IOException;
public class Robo {
private Robot robot;
public Robo() throws AWTException {
robot = new Robot();
}
/**
* Executa um comando no SO..
*/
public void execute(String comando) throws IOException {
Runtime.getRuntime().exec(comando);
robot.delay(5000); // Tempo para o programa abrir
}
/**
* Copia os dados para a área de transferência.
*/
public void copiar() {
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_C);
robot.keyRelease(KeyEvent.VK_C);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.delay(2000);
}
/**
* Cola os dados que estão na área de transferência.
*/
public void colar() {
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.delay(2000);
}
/**
* Executa a digitação de uma sequência de caracteres.
*/
public void executeTeclas(int... keys) {
if (keys != null) {
for (int key : keys) {
robot.keyPress(key);
robot.keyRelease(key);
}
}
robot.delay(2000); // tempo para o usuário ver o que foi digitado
}
public static void main(String[] args) throws AWTException, IOException {
Robo robo = new Robo();
// Número 25 seguido do sinal +
int[] primeira = { KeyEvent.VK_2, KeyEvent.VK_5, KeyEvent.VK_ADD };
// Número 12 seguido do sinal =
int[] segunda = { KeyEvent.VK_1, KeyEvent.VK_2, KeyEvent.VK_EQUALS };
robo.execute("calc");
robo.executeTeclas(primeira);
robo.executeTeclas(segunda);
robo.copiar();
robo.execute("notepad");
robo.colar();
}
}
Em outro post apresentarei um exemplo utilizando eventos do mouse e da saída padrão.
Aplicações com Agendamento Utilizando Java
3 Março 2008Precisando construir um sistema de monitoração fui apresentado a uma nova necessidade: Agendamento de tarefas utilizando o Java. Para implementação de agendamento de tarefas em Java basta o conhecimento de duas classes:
java.util.TimerTask – Classe abstrata que implementa a interface Runnable. Para criar uma Instância dessa classe é necessário sobrescrever o método run().
java.util.Timer – Essa classe permite que uma instância da classe abstrata TimerTask sejam agendadas e executada como uma Thread ou um daemon.
Chega de teoria, vamos à prática:
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
class Task extends TimerTask {
int i = 1;
public void run() {
System.out.println(i + " - " + new Date());
if (i++ == 5) {
System.exit(0);}
}
}
public class Main {
public static void main(String[] args) {
int inicioApos = 20000;int tempoParaProximaExecucao = 15000;Timer timer = new Timer();timer.scheduleAtFixedRate(new Task(), inicioApos, tempoParaProximaExecucao);}
}
No código anterior, foi implementada uma Task que é iniciada após 20 segundos do inicio do programa e que roda a cada 15 segundos.
Uma opção para obter o mesmo resultado é utilizar:
timer.schedule(new Task(), new Date() + 20000, 15000);
Mas o método schedule, com a assinatura acima permite que uma tarefa seja executada qualquer data, basta passar uma instância de java.util.Date com o dia e hora desejado.
Somente as classe padrões para agendamento de tarefas em Java foram úteis para as min as minhas necessidades, mas, para agendamentos mais drásticos existe o Quartz Enterprise Job scheduler (http://www.opensymphony.com/quartz/).
Java tem ponteiros!?
9 Fevereiro 2008Java tem ponteiros? Você pode até achar que não, mas, esse post mostra que a linguagem possui ponteiros e explica esse fato.
Escrito por Evandro Rosa Santos