quinta-feira, 24 de abril de 2008

Criando Evento Excluir em ADFTable através da Lixeira

Vamos lá pessoal,
Hoje é uma dica bastante interessante, pois é muito utilizada nos aplicativos Oracle (EBS).
Iremos criar uma Página nos padrões web, adicionando uma ADFTable e suas respectivas colunas, onde uma das colunas irá conter o evento "Excluir" que será exibido no formato de "Lixeira".

1º Passo: Adicionar em nossa página uma Table baseada no VO.
2º Passo: Adicionar uma coluna a Table chama "Excluir".
3º Passo: Arrastar a operação "Deletar" para coluna que foi criada em forma de CommandLink.
4º Passo: Criaremos um BackingBean (java Class) que irá conter as seguintes variáveis e métodos:
/*
private OperationBinding actionBindingToExecute;
private OperationBinding commitBinding;
private Object key;//respectivos getters e setters…

public String executeActionBinding() {
actionBindingToExecute.execute();
if (actionBindingToExecute.getErrors().size() == 0) commitBinding.execute();
return "";
}
*/
Dica: para as telas onde tenha as mesma caracterista e funcionalidades, ex.: Consulta com link na table e lixeirinha, aconselhamos a criar um backingBean genérico (ClasseBeanUtils.java).

5º Passo: Criar no CommandLink da Table dois setActionListener com as seguintes propriedades:
* From: #{row.rowKeyStr}
* To: #{ClasseBeanUtils.key} // Chave que criamos no BackingBean

* From: #{bindings.Delete} // Ação de Delete que foi adicionada a página (PageDef).
* To: #{ClasseBeanUtils.actionBindingToExecute} // Chamando método do BackingBean.

6º Passo: O Source da Coluna de nossa Table irá ficar da seguinte forma:

Note que no código acima eu adicionei uma imagem "deleteicon_enabled.gif" que é a Lixeira.
Sua página ficá assim:

7º Passo: Na PageDefinition, crie na seção de "Bindings" duas "Action" baseada no VO da página:
1º: "Commit".
2º: "setCurrentRowWithKey" com os seguintes dados:
· Name ex.: rowKey
· Type ex.: Java.lang.String
· Value ex.: #{ClasseBeanUtils.key}
8º Passo: Precisaremos adicionar nosso BackingBean no "Faces-Config". No faces-config tem a aba "overview" que será criado o "Managed Beans" com o seguintes dados:
· Name ex.: ClasseBeanUtils
· Class ex.: br.com.empresa.view.backing.ClasseBeanUtils
· Scope ex.: request
Após criaremos o "Manager Properties" vinculado ao nosso "Managed Beans" com os seguintes dados:
· Name ex.: commitBinding – ele tem que ter o mesmo nome do backingBean para fazer a injeção de dependência.
· Value ex.: #{bindings.Commit}
Assim nosso exemplo um pouco extenso irá funcionar. Lembrando a todos que esse BackingBean que foi criado podemos utilizar para todas as páginas e eventos parecido, ou seja, o trabalho é feito uma vez na apliação, depois é só o reuso.
Um grande abraço e até a próxima.

quinta-feira, 17 de abril de 2008

Deployment de ADF 10.1.3 para IAS 10.1.2

Olá Pessoal!

Uma situação que costuma causar algum trabalho é quando o cliente utiliza a versão do Oracle AS 10.1.2 (que vem com a versão 10.1.2 do J2EE Container da Oracle, o OC4J) e quer instalar aplicações ADF feitas no JDeveloper 10.1.3.3. Tal situação pede alguma atenção por parte da equipe de desenvolvimento. Seguem portanto alguns problemas que podem ocorrer e a respectiva solução:

Problema: O Servidor 10.1.2 é compatível com a spec J2EE 1.3, e o ADF 10.1.3 por padrão é aderente à J2EE 1.4. Podem ocorrer problemas com o formato dos arquivos de configuração J2EE (web.xml, data-sources.xml, application.xml) que na versão 1.3 usam DTD e na versão 1.4 usam XML Schemas para determinar o formato do XML.
Solução: O wizard de criação destes arquivos no JDeveloper permite que você escolha o formato 1.3 para os mesmos, resolvendo o problema. Ao criar um projeto pelo Wizard, tomem cuidado pois alguns arquivos são auto-gerado, precisamos deletá-los e gerar novamente para termos a opção citada acima.

Problema: O 10.1.2 é compativel com JDK 1.4.2, e o 10.1.3 por padrão é baseado no JDK 1.5. Dará problemas de UnsupportedVersionError ao executar.
Solução: Instale o JDK 1.4.2 na sua estação e configure um novo J2SE Definition dentro do JDeveloper, no menu Tools -> Manage Libraries, aba J2SE Definition. apontando para o arquivo java.exe existente no diretório de instalação do 1.4.2 ele pega o resto. Em seguida, vamos nas propriedades do(s) nosso(s) projeto(s) (botão direito -> Project Properties -> Aba Libraries) e mudamos o J2SE Definition que está lá para 1.4.2. Quando fizermos o rebuild do projeto, já estará compilando na versão antiga.

Problema: O ADF 10.1.3 precisa que estejam instalados no servidor algumas bibliotecas, principalmente pertinentes ao ADF BC e ao Toplink, que estão em uma versão mais antiga no 10.1.2. A aplicação não funcionará.
Solução: Executar o ADF Runtime installer, um programa que automatiza a cópia das bibliotecas do ADF, no servidor 10.1.2. Este instalador está disponível em: http://www.oracle.com/technology/software/products/jdev/htdocs/adfinstaller.html

Problema: Mesmo após executar o ADF Installer, ele está dando erros de NoClassDefFoundError para várias classes...
Solução: O ADF Runtime installer faz apenas parte do trabalho. A Oracle identificou diversos JARs que ficaram faltando, para saber quais devem ser copiados veja os notes no metalink (Notes:358791.1 e 412844.1) que dizem o que deve ser feito no servidor para colocar o ADF 10.1.3 para funcionar no OC4J 10.1.2.

É isso pessoal! Um abraço!

quarta-feira, 9 de abril de 2008

O Componente Shuttle - Parte Final

Olá Pessoal!
Neste post final, ficam só algumas dicas sobre o componente Shuttle:

1) A tag da Shuttle possui um facet chamado filter ([f:facet name="filter"]). Tudo o que for colocado dentro deste facet aparecerá logo acima da lista Heading. Um uso interessante para este facet é quando queremos, por exemplo, colocar um drop-down com uma lista de valores que, quando selecionados, filtram os valores exibidos dentro da Shuttle, como no caso de selecionarmos um departamento no drop-down para que a shuttle contenha apenas os empregados daquele departamento.
Para conseguir isto, se os seus selectItems forem derivados de um View Object, podemos criar um parâmetro de bind nele:
SELECT * FROM Emp EmployeeEO where EmployeeEO.deptno = :dept;
Aí criamos um method binding no Page Definition da página, apontando para o método ExecuteWithParams, e amarramos o parâmetro nomeado "dept" com um af:selectOneChoice, que colocaremos dentro da facet Filter da Shuttle. Feito isso, só precisamos que o componente drop-down submeta a página quando for alterado, o que conseguimos setando o atributo AutoSubmit do componente para verdadeiro.

2) Além da Shuttle comum (af:selectManyShuttle) temos o componente estendido chamado Ordered Shuttle (af:selectOrderShuttle). O funcionamento deste componente é estritamente igual ao da Shuttle comum, com a exceção que na Ordered Shuttle são disponibilizados setas de ordenação do lado direito da Trailing List, de modo que o usuário pode, após selecionar os valores e movê-los para a direita, ordenar estes valores dentro da lista, o que é refletido para a lista resultado montada pela shuttle.

Por hoje é só pessoal! Bom ADF pra vocês!

segunda-feira, 31 de março de 2008

Chamando Páginas como Popups

Boa Tarde Galera,
Hoje o post é referente a chamada de páginas como Popups.

Iremos usar o cenário bem simples com duas páginas, onde a Pagina1.jspx chamará a Pagina2.jspx atravez de um botão ou Link. A ação desse botão ou link é explodir a Pagina1.jspx em formato de Popup conforme imagem abaixo.

A ligação entre as duas páginas é feito atravez do "JSF Navigation Case" que obrigatóriamente terá a propriedade "From OutCome" chamada "dialog:". o "dialog" indica que a página é um popup.

A página1.jspx terá um botão ou Link que irá chamar a outra página atravéz da Action "dialog:". Precisaremos adicionar as seguintes informações nas propriedades:

* UseWindow = true

* Window Height = 300 // tamanho do popup referente a altura da Pagina2.jspx.

* Window Widht = 600 // tamanho do popup referente a largura da Pagina2.jspx.

A Pagina2.jspx irá conter um botão, link ou coisa parecida para retornar a Pagina1.jspx. Nesse componente de retorno será criado um "returnActionListener" com a propriedade "Value" null, assim ao clicar nesse componente o retorno é imediato.

Um grande abraço e até a próxima.

quinta-feira, 27 de março de 2008

O componente Shuttle - Parte 2

Oi Pessoal!

Continuando com a série sobre a Shuttle, vamos destrinchar um pouco melhor o funcionamento detalhado do componente JSF que a monta.

O componente af:selectManyShuttle precisa saber quais são os itens que devem ser renderizados nas listas leading e trailing. Isto é feito gerando uma lista de objetos da classe javax.faces.view.SelectItem, ou através de uma tag [f:selectItems] ou através de um loop [f:forEach] que imprima uma sequência de [f:selectItem].
Todo objeto SelectItem tem um valor ("value") e uma descrição. Para informar a shuttle quais valores devem estar do lado trailing (selecionados), montamos uma lista contendo os códigos dos itens selecionados, que devem ser equivalentes ao atributo "value" dos selectItems existentes na Shuttle, e informamos no atributo "value" da própria Shuttle a referÊncia para esta lista no managed bean. Exemplo de shuttle baseada inteiramente no Backing Bean:

[af:selectManyShuttle value="#{ShuttleControl.shuttleValues}"]
[f:selectItems value="#{ShuttleControl.shuttleElements}"]
[/af:selectManyShuttle]

Código do Backing Bean:
public class ShuttleControl {
private int[] shuttleValues; (Lista de códigos, pode ser trocado para List)
private SelectItem[] shuttleElements; (Também pode virar List)

//Getters e Setters omitidos.
}

Exemplo baseado em um ADF Table Binding, usando forEach pra popular os itens (mantendo o backing bean inalterado):

[af:selectManyShuttle value="#{ShuttleControl.shuttleValues}"]
[af:forEach var="li" value="#{bindings.ShuttleElements.rangeSet}"]
[f:selectItem value="#{li.Cod}" description="#{li.Desc}"]
[/af:forEach]
[/af:selectManyShuttle]

PageDefinition desta página:
...
[bindings]
[table iterator="ShuttleVOIter" Id="ShuttleElements"]
[attributes]
[Item name="Cod"/]
[Item name="Desc"/]
[/attributes]
[/table]
[/bindings]


Com esta configuração, podemos colocar um botão na página que a submeta, apontando para um método do Backing Bean da Shuttle. Neste método, a lista com os códigos movidos pelo usuário da leading pra trailing estará disponível no Bean no atributo shuttleValues. Podemos passá-lo para um método do Application Module que faça a inserção programática dos registros no View Object.

Exemplo:
[af:commandButton value="Submeter" action="#{ShuttleControl.onSubmitShuttle}"/]
Método no Backing Bean:
public String onSubmitShuttle() {
OperationBinding method = FacesContext.getCurrentInstance().getValue("#{bindings.applyShuttleValues}");
method.getParamsMap().put("nomeDoparametroList", shuttleValues");
method.execute();
return null; //fica na mesma página
}

Método no Application Module:
public void applyShuttleValues(List nomeDoParametroList) {
ViewObjectImpl view = getShuttleVO();
for (Iterator it = nomeDoParametroList.iterator(); it.hasNext();) {
Integer i = (Integer) it.next();
Row r = view.createRow();
r.setAttribute("Cod", i);
view.insertRow(r);
r.setStatus(Row.STATUS_INITIALIZED);
}
}

No próximo Post vamos demonstrar algumas maneiras de incrementar esta shuttle. Até lá!