Como recuperar valores em PhaseListener (JSF)

10 respostas
Alessandro_Lazarotti

Estou tendo problemas para recuperar alguns valores em uma classe que implementa PhaseListener.
Minha intenção é trabalhar com alguns valores retornados de uma af:table (ADF).

Porém os títulos das colunas que é preechido na página com ResourceBundle (f:loadbundle), no outputtext correspondente é retornado null em seu getValue, no phaseListener.

Se faço um teste e coloco como atributo para o título da coluna uma propriedade de um MB (ex: #{usrMB.nome}), eu tenho no “getValue” seu valor correto no phaseListener.

A mesma coisas acontece com o “var” da table, que realiza a iteração nas linhas da tabela. Ao tentar o valor de uma das linhas eu tenho null (Ex: #{var.nome}). Porém se eu coloco um valor que não é o da iteração e sim um valor fixo (ou de um atributo de um MB), ele é lido corretamente.

Resumindo, não consigo recuperar no PhaseListener valores de variáveis definidas na própria página, como as definidas em f:loadbundle e nem em definidas em “var” na iteração de uma table.

Esse comportamento é normal?
Como recuperar no PhaseListener um CoreOutputText quando na página seu value esta adicionado utilizando variáveis que só existem na página? (#bundle.meuTexto, #var.minhaLinha, etc).

OBS: Em getValueBinding do Componente aparece por exemplo “#bundle.meuTexto” … mas no getValue null.

Obrigado

10 Respostas

Alessandro_Lazarotti

DETALHE:

Acabei de perceber que só tenho este comportamento em outputText.
Nas linhas das tabelas onde utilizo commandLink e recupero o valor com getText, eu tenho tudo normal. O problema é no outputtext.getValue.

Ja tentei com HtmlOutputText e com a implementação CoreOutpuText do ADF … e fiquei com o mesmo problema.

O q pode ser?

urubatan

em vez de usar getValue, tenta usar um getValueBinding deve resolver o problema :smiley:

Alessandro_Lazarotti

getValueBinding retorna a string literal como é escrita no value da JSP:

“#{linha.nome}”

:frowning:

urubatan

com isto tu deve conseguir fazer um
vb = FacesContext.currentInstance().getApplication().createValueBinding(…);

Object value = vb.getValue(FacesContext.currentInstance());

ou algo parecido com isto …

sei que é um trabalho do cão, mas funciona :smiley:

Alessandro_Lazarotti

Urubatan, cara não sei o q esta acontecendo mas não funcionou.
Fiz da seguinte forma:

ValueBinding  vb = FacesContext.getCurrentInstance().getApplication().createValueBinding(ot.getValueBinding("value").toString());
String value = vb.getValue(FacesContext.getCurrentInstance());

Mas obtive NULL em value.
O interessante é que depurei o ‘ot.getValueBinding(“value”).toString()’, aquilo me devolve a expressão em literal ‘value=#{lista.nome}’, corretamente.

Mas alguma sugestão? :roll:

Valew pela força

Alessandro_Lazarotti

O interessante que isso acontece no PhaseListener apenas para as expressões que uso variáveis definidas na página, como bundle e var da table…

Alessandro_Lazarotti

Tentei direto tbm e nada !

ot.getValueBinding(“value”).getValue()

PS: ot é meu HtmlOutputText

urubatan

provavelmente então é por que na fase que tu ta rodando o teu phase listener estes valores ainda não estão definidos …
que fase tu ta interceptando?
execution? se não for tenta execution :smiley:

outra coisa, valores de dentro da iteração do dataTable tu não vai conseguir pegar de maneira alguma fora do loop :stuck_out_tongue:

Alessandro_Lazarotti

Eu já tentei rodar em RESTORE_VIEW, UPDATE_MODEL_VALUES e até em RENDER_RESPONSE… e obtive os mesmo resultados.

Pensei nisso que você disse sobre iteração (já que a table faz iteração sobre uma coleção para criar as colunas). Porém no caso da table todas as iterações ficam armazenadas na árvore de componentes,gerando nós para CoreColumns e cada um destes criando filhos com CoreOutputText por exemplo. Tanto é, que com CommandLink no lugar de OutputText, eu recupero todos os valores. O problema é que em alguns casos não poderei usar command, teria que ser texto simples mesmo.

Segue abaixo a codificação da classe.
OBS: Se trata da classe responsável pelo ExcelExport do SandBox do Tomahawk, modificada para funcionar com ADF Faces.

Abraços

package org.apache.myfaces.custom.excelexport;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.faces.component.UIComponent;
import javax.faces.component.html.HtmlOutputText;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.portlet.RenderResponse;
import javax.servlet.http.HttpServletResponse;

import oracle.adf.view.faces.component.core.data.CoreColumn;
import oracle.adf.view.faces.component.core.data.CoreTable;
import oracle.adf.view.faces.component.core.nav.CoreCommandLink;

import org.apache.myfaces.custom.redirectTracker.RedirectTrackerNavigationHandler;
import org.apache.myfaces.custom.util.ComponentUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

/**
 * @author Alesandro Lazarotti 
 */
public class ExcelExportPhaseListener implements PhaseListener {

	public void afterPhase(PhaseEvent phaseEvent) {
			System.out.println(" ----------- Fase -&gt "+ phaseEvent.getPhaseId());
		FacesContext facesContext = phaseEvent.getFacesContext();
		Map map = facesContext.getExternalContext().getRequestParameterMap();

		if (map.containsKey("excelExportTableId")) {
			String tableId = (String) map.get("excelExportTableId");
			CoreTable dataTable = (CoreTable) ComponentUtils.findComponentById(
					facesContext, facesContext.getViewRoot(), tableId);
			HSSFWorkbook generatedExcel = generateExcel(facesContext, dataTable);
			try {
				Object contextResponse = facesContext.getExternalContext()
						.getResponse();
				if (contextResponse instanceof HttpServletResponse)
					writeExcelOutput(generatedExcel,
							(HttpServletResponse) contextResponse);
				else if (contextResponse instanceof RenderResponse)
					writeExcelOutput(generatedExcel,
							(RenderResponse) contextResponse);

				facesContext.getApplication().getStateManager()
						.saveSerializedView(facesContext);
				facesContext.responseComplete();
				RedirectTrackerNavigationHandler x = null;
			} catch (Exception e) {
				throw new RuntimeException(e);

			}
		}
	}

	public void beforePhase(PhaseEvent phaseEvent) {
		// do nothing
	}

	public PhaseId getPhaseId() {
		return PhaseId.RENDER_RESPONSE;
	}
	private void writeExcelOutput(HSSFWorkbook workBook,
			HttpServletResponse response) throws IOException {
		response.setContentType("application/vnd.ms-excel");
		workBook.write(response.getOutputStream());
	}

	private void writeExcelOutput(HSSFWorkbook workBook, RenderResponse response)
			throws IOException {
		response.setContentType("application/vnd.ms-excel");
		workBook.write(response.getPortletOutputStream());
	}

	private List getColumns(CoreTable table) {
		List columns = new ArrayList();
		for (int i = 0; i &lt table.getChildCount(); i++) {
			UIComponent child = (UIComponent) table.getChildren().get(i);
			if (child instanceof CoreColumn) {
				columns.add(child);
			}
		}
		return columns;
	}

	private HSSFWorkbook generateExcel(FacesContext facesContext,
			CoreTable table) {
		HSSFWorkbook workbook = new HSSFWorkbook();
		HSSFSheet sheet = workbook.createSheet(table.getId());
		List columns = getColumns(table);
		int currentRowIndex = table.getRowIndex();

		addColumnHeaders(sheet, columns,facesContext);
		addColumnValues(sheet, columns, table, facesContext);

		table.setRowIndex(currentRowIndex);
		return workbook;
	}

	private void addColumnValue(HSSFRow rowHeader, UIComponent component,
			int index, FacesContext context) {
		HSSFCell cell = rowHeader.createCell((short) index);
		cell.setEncoding(HSSFCell.ENCODING_UTF_16);
		String value = "";
		if (component instanceof HtmlOutputText) {
			HtmlOutputText ot = (HtmlOutputText) component;
				value = ot.getValue().toString();
				cell.setCellValue(value);
				
		} else if (component instanceof CoreCommandLink) {
			cell.setCellValue(((CoreCommandLink) component).getText());
		}
	}

	private void addColumnHeaders(HSSFSheet sheet, List columns, FacesContext facesContext) {
		HSSFRow rowHeader = sheet.createRow(0);

		for (int i = 0; i &lt columns.size(); i++) {
			CoreColumn column = (CoreColumn) columns.get(i);
			addColumnValue(rowHeader, column.getHeader(), i, facesContext);
		}
	}

	private void addColumnValues(HSSFSheet sheet, List columns,
			CoreTable dataTable, FacesContext context) {
		for (int i = 0; i &lt dataTable.getRowCount(); i++) {
			dataTable.setRowIndex(i);
			HSSFRow row = sheet.createRow(i + 1);
			for (int j = 0; j &lt columns.size(); j++) {
				CoreColumn column = (CoreColumn) columns.get(j);
				addColumnValue(row, (UIComponent) column.getChildren().get(0),
						j,context);
			}
		}
	}


}
luisandro

Aproveitando o assunto sobre PhaseListener, gostaria de saber se há uma forma de chamar duas vezes a mesma fase
Exemplo:

No afterPhase da fase 6 RENDER_RESPONSE, fazer com que essa fase seja chamada mais uma vez.

Tem como fazer isso?

Criado 18 de janeiro de 2007
Ultima resposta 27 de fev. de 2007
Respostas 10
Participantes 3