Então gente, o problema é o seguinte: eu tenho uma tabela cuja colunas possuem regras para renderizar. A renderização vai dempender de dois parâmetros: o que o objeto pode exibir e ou que o usuário escolhe para exibir.
Quando eu rodo o código, e uma informação o usuário escolhe exibir mas o objeto não pode exibir, o JSF renderiza o título da coluna e não renderiza o corpo. Nesse caso, o certo seria não renderizar a coluna inteira.
Vamos aos exemplos:
Suponhamos que exista um objeto abstrato(OA) com os seguintes retorno: R1, R2, R3. E que exista 3 objetos que estendem OA: O1, O2 e O3. E além dos retornos de OA, cada objeto implementa seus próprios métodos:
O1: R1, R2, R3, R4, R5;
O2: R1, R2, R3, R5, R6;
O3: R1, R2, R3, R7, R8;
Bom, para a tabela exibir todos os dados, ela deve ser capaz de exibir: R1, R2, R3, R4, R5, R6, R7, R8. Obviamente, se eu simplesmente mandar exibir isso na tabela, eu vou receber um erro.
Então eu implementei o seguinte método de decisão:
private void decidirExibicao(OA o)
{
if (o instanceof O1)
oe = new objExibir(true,true,false,false,false);
else if (o instanceof O2)
oe = new objExibir(false,true,true,false,false);
else if (o instanceof O3)
oe = new objExibir(false,false,false,true,true);
}
Oe é um objeto que guarda o que deve ser exibido. Funciona assim, os retorno comuns, não precisam ser testados, mas os especificos sim. Esse objeto então possui algumas propriedades booleana que representa esses métodos específicos.
Bom, como a tabela é dinámica, esses objetos (O1, O2, O3) deve ser colocados numa lista e só devem ser exibidos os retornos comuns. Acontece, que o usuário pode selecionar várias instâncias de um objetos, por exemplo O1, ou selecionar cada instância de um objeto diferente, O1 ou O2 ou O3.
Bom, após o método descobrir quais dados o JSF poderá imprimir na tela, existe um outro fator: a escolha do usuário (EU).
Suponhamos que o usuário decida exibir todos os dados. E que chamaremos de DE a deciçãa de exibição e EU a escolha do usuário.
Pelo exemplo, os retornos R1, R2 e R3 são comuns a todos os objetos, logo, a regra de exibição será:
public boolean isR1()
{
return EU.exibirR1();
}
Isso porque a exibição de R1 só depende da vontade do usuário.
Mas se o usuário quer também ver R8?
Nesse caso, a implementação fica:
public boolean isR8()
{
return DE.exibirR8() && EU.exibirR8();
}
Bom, se o objeto selecionado for O3, logo o retorno do método acima será TRUE, porquer ED.exibirR8() = TRUE e EU.exibirR8() tb é TRUE.
Mas se o objeto selecionado pelo usuário for O1, então o retorno será FALSE poquer ED.exibirR8() = false e EU.exibirR8 = true. Então, TRUE && FALSE == FALSE.
Com isso, a coluna referente ao R8 não será exibida.
Esse é o comportamento esperado. Porém, quando acontece um FALSE && TRUE, o título da coluna é exibido e o corpo, suprimido.
Ao verificar o log, verifico um comportamento estranho do tipo:
isR8() == true;
isR8() == true;
isR8() == true;
isR8() == true;
isR8() == false;
isR8() == false;
isR8() == false;
isR8() == false;
Isso, mesmo, o método é invocado 8 vezes, sendo as 4 primeiras no valor errado e as 4 últimas no valor correto.
Como o objeto é um parâmetro, eu verifiquei que o parâmetro não está sendo processado nas 4 primeira iterações que o JSF faz. Por isso o TRUE. Mas é processado nas 4 últimas, e ai o valor correto FALSE.
O resultado disso é que o JSF imprime o título da tabela e não o corpo. Como se os renderes fossem processados antes de processar o resto do ManagerBean.
A minha coluna foi codificada assim:
<h:column rendered="#{obj.r8}">
<f:facet name="header">
<h:outputText value="Título"/>
</f:facet>
<h:outputText value="#{var.algumValor}">
</h:column>
Como vocês podem ver, a regra da renderezação está na definição da coluna, logo, se alguma coisa é exibida, toda a coluna deve ser exibida.
E os dados não são apenas suprimidos ou não exibem por não existir, o corpo da coluna é suprimido, tanto que a tabela gerada fica deformada.
O que pode está acontecendo com esse JSF? Algum problema quando ao ciclo de vida? O que pode ser?
Lembrando, no método isR8() eu verifico se o parâmetro passado é null, se sim, eu o capturo da sessão.
Novamente, o que pode ser? Por onde eu posso procurar a solução. Se tiver que mandar e-mail para alguém, para quem pode? Alguém tem alguma indicação de fórum, de técnico, alguma coisa?
Qualquer coisa serve!
Obrigado.