terça-feira, 11 de novembro de 2014

JSF 2 - Eventos

O objetivo desse post é ir um pouco além das categorias de eventos mais utilizadas pelo framework: action listeners e value change listeners.

Action e Value Change Listeners

Como todo mundo que desenvolve JSF deve conhecer, utilizamos action listeners quando queremos executar a lógica de aplicação sem que, no entanto, tenhamos que redirecionar o fluxo das páginas retornando um outcome.

A imagem abaixo mostra o exemplo de um listener:


E o componente (action source) que dispara o evento:


Da mesma mesma forma, sem grandes novidades, utilizamos os value change listeners. Primeiro o código Java:


O script JSF:



O que grande parte dos iniciantes JSF desconhece é que existe outra forma de reproduzir este comportamento implementando os listeners de outra forma - estendendo as interfaces javax.faces.event.ActionListener e javax.faces.event.ValueChangeListener respectivamente. O exemplo a seguir mostra a implementação de um action listener usando a interface proposta:

A interface javax.faces.event.ActionListener especifica o método processAction que se comporta de forma parecida que o método myActionListener do primeiro exemplo. A maior diferença está no fato de que cada vez que uma ação for executada uma instância de MyActionListener será criada.

O botão abaixo dispara um evento que é tratado pela implementação MyActionListener. A maior diferença aqui é que, ao invés de usar o atributo actionListener do h:commandButton, utilizamos a tag f:actionListener especificando o nome totalmente qualificado da classe no atributo type:


Uma das grandes vantagens desta última abordagem é que podemos especificar mais de um action listener para o h:commandButton e eles serão executados na ordem em que forem especificados no corpo do componente:


E é o mesmo no que diz respeito aos value change listeners. Primeiro o código Java:


Depois o JSF:


Os System Events

Os action e value change listener vão resolver a maior parte dos seus problemas de eventos enquanto desenvolvedor JSF. Porém, existem aquelas ocasiões em que precisamos de algo mais. O modelo de componentes do JSF permite associar listener aos componentes em momentos distintos da sua existência. Um bom exemplo é um listener que seria executado no momento imediatamente antes do componente ser renderizado na página. No exemplo a seguir, foi especificado um método listener que recebe um ComponentSystemEvent como parâmetro. O método simplesmente faz o cast do componente que disparou o evento para um UIInput e configura a data atual como o seu valor padrão.


A seguir, o trecho JSF do component que dispara o evento:


A novidade aqui é a tag f:event que especifica o tipo (atributo type) de evento que será disparado e seu respectivo listener (método myPreRenderListener, no managed bean). Outros momentos da existência do componente pode ser observado na doc https://docs.oracle.com/javaee/6/javaserverfaces/2.1/docs/vdldocs/facelets/f/event.html .

Ainda quanto aos System Events, você pode aumentar um pouco mais a capacidade da sua aplicação reagir aos momentos da sua execução. A superclasse de ComponentSystemEvent, SystemEvent, permite que você trate eventos de mais baixo baixo nível, como, por exemplo, a inicialização e a finalização da aplicação. O exemplo a seguir mostra exatamente isso:

A classe acima implementa a interface javax.faces.event.SystemEventListener com o intuito de tratar os eventos derivados da interface javax.faces.event.SystemEvent. A interface provê dois métodos: isListenerForSource, usada para determinar se o evento gerado é do tipo apropriado para ser tratado e o processEvent, onde ele deve ser adequadamente tratado. Para exemplificar, eu irresponsavelmente trataei eventos distintos no mesmo método. O trecho do faces-config.xml a seguir diz para o container que a minha implementação é um listener de eventos do sistema. Todo o código abaixo deve ser inserido entre e
.

O conjunto de eventos que podem ser tratados desta forma está descrito em https://docs.oracle.com/cd/E17802_01/j2ee/javaee/javaserverfaces/2.0/docs/api, na seção "direct subclasses".








terça-feira, 23 de dezembro de 2008

Validação de formulários com jQuery

Requisitos:
jquery-1.2.6.js
Você pode ver o script funcionando aqui:
http://www.infernatica.xpg.com.br///validacao01.html


Esse é um exemplo simples de validação de formulários HTML utilizando jQuery. Parte do princípio que é necessário apenas verificar se os campos foram devidamente preenchidos, mas pode ser facilmente estendido para atender propósitos mais específicos. Vou apresentar os códigos e em seguida discuti-los; acredito que essa seja a maneira mais simples e eficiente para explicá-los.

O formulário HTML é bem simples, dois campos do tipo input text, textarea e uma div para exibir as mensagens de erro.

A figura acima apresenta o código do formulário que deverá ser validado. Trata-se de um simples formulário HTML, composto de três campos, respectivamente nome, sobrenome e observações, sendo os dois primeiros do tipo input text e o último um text-area. Observe que defini dois atributos extras para cada objeto de inserção de dados: label e req. Na verdade, é perfeitamente possível substituir o atributo label pelo próprio name, porém utilizei o label para apresentar informações mais detalhadas para o usuário. O outro atributo, req, serve para definir que o campo é obrigatório. Observe também que há uma div (#divError), configurada para não ser exibida (style=”display:none”), cujo propósito é apresentar as mensagens de erro oriundas da validação.

Resumidamente, a estratégia desta validação é percorrer os campos do formulário e verificar em quais deles está presente e definido como true o atributo req. Os elementos que definem req=true devem possuir pelo menos um caractere preenchido em seu valor (value).
O código entre a linha 8 e 12 serve para fazer a ligação (binding) entre o evento submit do formulário e a função JavaScript validar que criei. A variável canSubmit serve para determinar se o formulário pode ser postado (true) ou não (false). A variável messages irá armazenar todas as mensagens de erro que serão exibidas para o usuário. Observe que ela é iniciada com um elemento do tipo unordered list (<ul>). O código da linha 22 define que a função subseqüente (aquela que lhe é passada como parâmetro) deverá ser executada para todos os elementos que possuir o atributo req definido como true. Na linha 24 é onde se verifica se pelo menos um caractere foi digitado no input (ou no text-area); se detectado um elemento vazio, a variável canSubmit é configurada como false e à variável messages é concatenado o label do elemento que está vazio, entre tags do tipo list item (<li> e </li>), como é exigido pelos elementos list. A execução prossegue para determinar se existem mais campos vazios e, se houver, o procedimento se repete, concatenando mais mensagens de erro à variável messages.
Após todos os elementos que definem req=true terem sido percorridos, o primeiro passo é concatenar, à variável messages, a tag que encerra o unordered list (</ul>). Em seguida é feita uma verificação condicional (if da linha 33) para determinar se o formulário pode ser postado. A verificação consiste, basicamente, em verificar o valor de canSubmit; se falso, as mensagens concatenadas em messages serão inseridas dentro da div cujo id é divError e exibidas com o efeito fadeIn do jQuery, configurado para 300 milissegundos. A última linha da rotina retorna o valor de canSubmit que, se for true, faz com que o formulário seja submetido e, caso contrário, o submit é cancelado.
A figura a seguir ilustra o funcionamento da validação. Você pode testá-la deixando algumas tags sem o atributo req=true. Como eu disse, a partir daí, criar uma validação mais específica não é muito trabalhoso.




O código completo da validação:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Validação com jQuery</title>

<script language="javascript" src="jquery-1.2.6.js"></script>
<script language="javascript">
$(
function(){
$("#mainForm").bind("submit", validar);
}
);

/**
* Executa a verificação
*/
function validar(e){
// determina se o form pode ser submetido ou não
var canSubmit = true;

// acumula as mensagens de erro
var messages = "<ul>";

// faz uma busca por todos elementos que especificam o atributo req=true
$("[req=true]").each(
function(){
if($(this).val().length < 1){
canSubmit = false;
messages += "<li>" + $(this).attr("label") + " é obrigatório</li>";
}
}
);
messages += "</ul>";

// verifica se vai exibir as mensagens de erro
if(canSubmit == false)
$("#divError").html(messages).css("color", "red").fadeIn(300);

return canSubmit;
}
</script>

<style>

p{
margin: 2px;
padding: 2px;
}

</style>

</head>

<body>
<form method="post" id="mainForm">
<!-- div que irá exibir as mensagens de erro -->
<div id="divError" style="display:none"></div>

<p>Nome</p>
<input type="text" name="name" label="nome do usuário" req="true"/>

<p>Sobrenome</p>
<input type="text" name="sobrenome" label="sobrenome do usuário" req="true"/>

<p>Observações</p>
<textarea name="obs" label="observações sobre o usuário" req="true"></textarea>

<br/>
<input type="submit" value="Enviar"/>
</form>
</body>
</html>

sábado, 12 de abril de 2008

Precedência de operadores em Java

Precedência de opereadores em Java
Da maior para a menor

Operador Descrição
. [] ()
(tipo)
Máxima precedência: separador, indexação, parâmetros, conversão de tipo
+ - ~ ! ++ -- Operador unário: positivo, negativo, negação (inversão bit a bit), não (lógico), incremento, decremento
* / % Multiplicação, divisão e módulo (inteiros)
+ - Adição, subtração
<< >>
>>>
Translação (bit a bit) à esquerda, direita sinalizada, e direita não sinalizada (o bit de sinal será 0)
< <= >=
<
Operador relacional: menor, menor ou igual, maior ou igual, maior
== != Igualdade: igual, diferente
& Operador lógico e bit a bit
^ Ou exclusivo (xor) bit a bit
| Operador lógico ou bit a bit
&& Operador lógico e condicional
|| Operador lógico ou condicional
?: Condicional: if-then-else compacto
= op= Atribuição

Considere a expressão:

1 | 2 ^ 3 * 2 & 13 | 2

  1. A análise é feita da esquerda para a direita.
  2. O primeiro cálculo a ser executado é 3 * 2, que resulta em 6.
  3. Em seguida, o resultado anterior é comparado com o 13, uma operação & (E): 6 & 13, que resulta em 4.
  4. Agora é feita uma operação de ^ (Ou exclusivo) com o 2 (mais a esquerda) e o 4 da operação anterior. O resultado é 6.
  5. É executada, então, a operação | (Ou) mais a esquerda: 1 | 6 que resulta em 7.
  6. Por último, é executadada a operação de | (Ou): 7 | 2 que também resulta em 7.
A mesma expressão acima poderia ser escrita da seguinte forma:

((1 | (2 ^ ((3 * 2) & 13))) | 2)

terça-feira, 25 de setembro de 2007

Editor VI - Guia do Usuário

Achei esse texto no site do Aurélio Marinho Jargas (http://aurelio.net) e pensei que seria útil replicá-lo aqui:

Entrar e Sair

  • vi arquivo.txt
  • :q

Entrar, Inserir Texto, Salvar e Sair

  • vi arquivo.txt
  • i
  • Minha primeira frase no VI.
  • :wq

Entrar, Alterar Texto e Sair sem Salvar

  • vi arquivo.txt
  • dd
  • :q!

Entrar, Alterar Texto, Salvar em Outro Arquivo e Sair

  • vi arquivo.txt
  • yy
  • p
  • :w arquivo-novo.txt
  • :q

Configurar o VI

  • vi ~/.vimrc
  • i
  • set vb ru nu
  • set ic is hls scs
  • :wq

Repetir a Primeira Linha 2 Vezes e Apagar a Última

  • vi arquivo.txt
  • gg
  • yy
  • p
  • p
  • G
  • dd

Repetir Comandos

  • vi arquivo.txt
  • A
  • FIM
  • j
  • .
  • j
  • .

Abrir Dois Arquivos Simultaneamente

  • vi arquivo.txt
  • :split ~/.vimrc
  • Ctrl+W
  • Ctrl+W
  • :q
  • :q

Obter Ajuda

  • vi arquivo.txt
  • :help


Comandos de Arquivo
:q Sai do VI
:w Salva alteraçoes feitas
:wq Salva aterações e sai do VI
:q! Sai sem salvar
:w abc Grava arquivo com o nome 'abc'
:r abc Insere o conteúdo do arquivo 'abc'
:e abc Edita o arquivo 'abc'

Modo de Inserção
i Entra no modo de Inserção
a Entra no modo de Inserção, após o cursor
o Entra no modo de Inserção, em uma nova linha
Sai do modo de Inserção

Copiar, Cortar e Colar
yy Copia a linha inteira
5yy Copia as 5 próximas linhas
dd Apaga a linha
5dd Apaga 5 linhas
x Apaga uma letra
5x Apaga 5 letras
p Cola o trecho copiado ou apagado
V Seleção visual de linhas

Pulos
gg Pula para a primeira linha
G Pula para a última linha
44G Pula para a linha número 44
w Pula para a próxima palavra
b Pula para a palavra anterior
{ Pula para o parágrafo anterior
} Pula para o próximo parágrafo
( Pula para a frase anterior
) Pula para a próxima frase
f. Pula até o próximo ponto (.), na mesma linha
`` Desfaz o pulo, volta

Apagando com esperteza
dgg Apaga até o início do arquivo
d0 Apaga até o início da linha atual
dw Apaga a palavra
d4b Apaga as quatro palavras anteriores
df. Apaga até o próximo ponto
d) Apaga até o fim da frase

Outros
J Junta a próxima linha com a atual
u Desfaz o último comando
Ctrl+R Refaz o último comando desfeito
. Repete o comando anterior
hjkl Movimenta o cursor
/ Pesquisa um texto
n Vai para o próximo resultado da pesquisa
:%s/a/b/g Troca 'a' por 'b' em todo o texto
:!cmd Executa o comando externo 'cmd'
:r!cmd Insere o resultado do comando externo 'cmd'

Mais informações em http://aurelio.net/doc/vim

terça-feira, 18 de setembro de 2007

Recuperar senha de root no Slackware

Como alterar a senha de root no Slackware, caso você a tenha perdido:
1. Iniciar o sistema "bootando" pelo CD/DVD do Slackware
2. Criar um diretório qualquer (/temp, por exemplo)
3. Montar a raiz do sistema no diretório criado (mount /dev/hdn /temp, onde hdn é a partição Linux)
4. Executar o comando chroot /temp, considerando /temp é o diretório que você criou
5. Agora é só alterar a senha com o comando passwd

sexta-feira, 14 de setembro de 2007

Normalização de banco de dados

Segundo Heuser (2001), uma forma normal (FN) é uma regra que deve ser obedecida por uma tabela para que ela seja considerada “bem projetada”. Existem inúmeras formas normais, ou seja, diversas regras, cada vez mais rígidas, para verificar tabelas em banco de dados relacionais. No entanto, pelo menos 3 FNs são consideradas essenciais para a construção de um bom projeto de banco de dados.

1FN (Primeira Forma Normal)

Primeira forma normal (1FN) = diz
que uma tabela está na primeira forma normal quando ela não contém tabelas aninhadas

Considere a planilha a seguir:

A planilha acima representada em um modelo relacional não normalizado (ÑN) ficaria assim:

Segundo a definição da 1FN, para normalizar a tabela acima, é necessário decompô-la em duas:

Proj(CodProj, Tipo, Descr);
Emp(CodProj, CodEmp, Nome, Cat, Sal, DataIni, TempAl);

Ou seja:
* As colunas destacadas em cinza compõem as chaves primárias.
** Vale ressaltar que se houvesse a restrição de que um funcionário só pudesse participar de exatamente 1 projeto, a chave-primária da tabela
ProjEmp poderia ser composta unicamente de CodEmp.

2FN (Segunda Forma Normal)

Observando a tabela ProjEmp acima, é possível identificar que os dados do funcionário Mário se repetem em duas tuplas. É esse tipo de redundância que a 2FN visa eliminar.

Segunda Forma Normal (2FN) = uma tabela encontra-se na segunda forma normal, quando, além de estar na 1FN, não contem dependências parciais.

Dependência parcial = uma dependência parcial ocorre quando uma coluna depende apenas de parte de uma chave primária composta.

A partir das definições acima, podemos concluir que a tabela Proj já se encontra na 2FN, pois todos seus atributos dependem exclusivamente de sua chave primária, já a tabela ProjEmp não. Verifique, em ProjEmp, que atributos como Nome, Cat, Sal dependem somente de CodEmp, enquanto que DataIni, TempAl dependem da chave primária composta por inteiro (tal fato se justifica porque pode ser necessário identificar a data em que determinado usuário ingressou em um projeto). Sendo assim, para que a tabela ProjEmp fique de acordo com a 2FN, é necessário decompô-la em duas outras (ProjEmp e Emp). O projeto então fica como segue:


3FN (Terceira Forma Normal)

Observando o modelo gerado aplicando-se as regras da 2FN e supondo que o salário de um empregado é determinado por sua categoria funcional (Cat), podemos notar que ainda restam dados redundantes na tabela Emp; todos os empregados da categoria A1 e A2 possuem salário 4 e B1 possuem salário 9. A 3FN visa eliminar esse tipo de redundância.

Terceira Forma Normal (3FN) = uma tabela encontra-se na terceira forma normal, quando, além de estar na 2FN, não contém dependências transitivas

Dependência transitiva = uma dependência funcional transitiva ocorre quando uma coluna, além de depender da chave primária da tabela, depende de outra coluna ou conjunto de colunas da tabela

Sendo assim, a tabela Emp obtida pela aplicação da 2FN, que contém os dados redundantes, pode ser decomposta em outras duas (Emp e Cat). O modelo fica como segue:

Resumo

1FN

  1. Cria-se uma tabela na 1FN referente à tabela ÑN e que contém apenas colunas com valores atômicos, isto é, sem as tabelas aninhadas;
  2. Para cada tabela aninhada, cria-se uma tabela na 1FN compostas pelas seguintes colunas:
    1. A chave primária de uma das tabelas na qual a tabela em questão está aninhada
    2. As colunas da própria tabela
  3. São definidas as chaves primárias das tabelas na 1FN que correspondem a tabelas aninhadas

2FN

  1. Copiar para a 2FN cada tabela que tenha chave primária simples ou que não tenha colunas além da chave. No caso do exemplo, é o que acontece com a tabela Proj.
  2. Para cada tabela com chave primária composta e com pelo menos uma coluna não chave (no exemplo, a tabela ProjEmp):
    1. Criar na 2FN uma tabela com as chaves primárias da tabela na 1FN
    2. Para cada coluna não chave fazer a seguinte pergunta:
      a coluna depende de toda a chave ou de apenas parte dela”
    3. Caso a coluna dependa de toda a chave
      i. Criar a coluna correspondente na tabela com a chave completa na 2FN
    1. Caso a coluna não dependa apenas de parte da chave
      i. Criar, caso ainda não existir, uma tabela na 2FN que tenha como chave primária a parte da chave que é determinante da coluna em questão
      ii. Criar a coluna dependente dentro da tabela na 2FN

3FN

Copiar para o esquema da 3FN cada tabela que tenha menos de duas colunas não chave, pois neste caso não há como haver dependências transitivas

  1. Para tabelas com duas ou mais colunas não chaves, fazer a seguinte pergunta:
    a coluna depende de alguma outra coluna não chave?”
    1. Caso dependa apenas da chave
      i. Copiar a coluna para a tabela na 3FN
    1. Caso a coluna depender de outra coluna
      i. Criar, caso ainda não exista, uma tabela no esquema na 3FN que tenha como chave primária a coluna na qual há a dependência indireta
      ii. Copiar a coluna dependente para a tabela criada
      iii. A coluna determinante deve permanecer também na tabela original

Conclusão

Quem já trabalhou com banco de dados, acaba percebendo que utilizava as FNs mesmo sem conhecê-las. Para desenvolvedores mais experientes, a eliminação de redundâncias em bancos de dados se configura uma prática essencial para o sucesso do projeto. O material utilizado para a criação deste texto menciona a 4FN, porém, para a maioria dos projetos, a 3FN é suficiente.

Bibliografia

HEUSER, Carlos Alberto. Projeto de Banco de Dados. Porto Alegre, RS: Editora Sagra Luzzatto, 2001.