Category: JSF

How to capture programmatically (Java – Adf Faces) an attribute from payload task (Human Task Form)

Hi Guys,

This is an useful code that capture the value of an attribute inside of payload from Human Task generated automatically from bpel.

Here is a list of attributes that exists in your human task form.

With this code, you can capture the value of any attribute.

You can to call this method this way: getValueAttributeFromHumanTask(“numeroPedido”)


import oracle.adf.model.BindingContext;
import oracle.adf.view.rich.context.AdfFacesContext;
import oracle.binding.AttributeBinding;
import oracle.binding.BindingContainer;
import oracle.bpel.services.datacontrol.data.DataObject;

public String getValueAttributeFromHumanTask(String attributeName){
    String response = "";
    BindingContainer bindings = BindingContext.getCurrent().getCurrentBindingsEntry();
    AttributeBinding attr = (AttributeBinding)bindings.getControlBinding(attributeName);
    DataObject data = null;
    if(attr != null){
        data = (DataObject)attr.getInputValue();
    }
    if(data != null){
        response = data.getValue();
    }
    return response;
}

How to set recursively component properties using Java Server Faces (JSF)

Hello,

I am using a piece of code that setting disabled=true and readonly=true to all components inside of a Form, but you can use this in other situations:

In your .jspx File:

<f:view beforePhase="#{someController.makeFormReadOnly}">

In your .java File:


import javax.faces.application.Application;
import javax.faces.context.FacesContext;
import javax.faces.component.UIComponent;
import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import java.lang.reflect.Method;

public void makeFormReadOnly(FacesContext facesContext, UIComponent component) {
    try {
        Method[] methods = component.getClass().getMethods();
        for (Method method : methods) {
            if (method.getName().equals("getChildren")) {
                List<UIComponent> listaComp = (List<UIComponent>)method.invoke(component);
                for (UIComponent comp : listaComp) {
                    makeFormReadOnly(facesContext, comp);
                }
            }
        }
        component.setValueExpression("readOnly", getValueExpression(facesContext, "#{true}"));
        component.setValueExpression("disabled", getValueExpression(facesContext, "#{true}"));
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

private ValueExpression getValueExpression(FacesContext facesContext, String name) {
    Application app = facesContext.getApplication();
    ExpressionFactory elFactory = app.getExpressionFactory();
    ELContext elContext = facesContext.getELContext();
    return elFactory.createValueExpression(elContext, name, Object.class);
}

How to propagate FacesMessage between two jsf pages

Hello,

The JSF don’t propagate a FacesMessage between two jsf pages, i discovery this when i trying to make something like this:

1 –
User click in a Jsf Button

2 – Call the action method in the Managed Bean, something like this:

	public String someMethod(){
		// Execute some code
		FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "", "Something message");
		FacesContext.getCurrentInstance().addMessage(null, msg);
		return "otherPage";
	}

3 – Suppose that the string “otherPage” cause a normal redirect to other Jsf page, through faces-config.xml, in this exact point the FacesMessage is losted.

Resolution: For resolve this problem, follow this steps, basically this will affect all lifecycle of your jsf application:

1 – In your faces-config.xml, put this code:

  <lifecycle>
    <phase-listener>com.somepackage.MultiPageMessagesSupport</phase-listener>  
  </lifecycle>

2 – Put the below java class in the package specified above:

import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;

/**
 * Enables messages to be rendered on different pages from which they were set.
 * To produce this behaviour, this class acts as a <code>PhaseListener</code>.
 * 
 * This is performed by moving the FacesMessage objects:
 * <li>After each phase where messages may be added, this moves the messages
 * from the page-scoped FacesContext to the session-scoped session map.
 * <li>Before messages are rendered, this moves the messages from the
 * session-scoped session map back to the page-scoped FacesContext.
 * 
 * Only messages that are not associated with a particular component are ever
 * moved. These are the only messages that can be rendered on a page that is
 * different from where they originated. * To enable this behaviour, add a
 * <code>lifecycle</code> block to your faces-config.xml file. That block
 * should contain a single <code>phase-listener</code> block containing the
 * fully-qualified classname of this file.
 * 
 * @author <a href="mailto:jesse@odel.on.ca">Jesse Wilson</a>
 * 
 * @version This version have the bug corrected: The bug was:
 * In the same page, the FacesMessage was displayed many times,
 * with this patch, only different messages is added into new context.
 */
public class MultiPageMessagesSupport implements PhaseListener {

	private static final long serialVersionUID = 3328743500652081238L;

	/** a name to save messages in the session under */
	private static final String sessionToken = "MULTI_PAGE_MESSAGES_SUPPORT";

	/**
	 * Return the identifier of the request processing phase during which this
	 * listener is interested in processing PhaseEvent events.
	 */
	public PhaseId getPhaseId() {
		return PhaseId.ANY_PHASE;
	}

	/**
	 * Handle a notification that the processing for a particular phase of the
	 * request processing lifecycle is about to begin.
	 */
	public void beforePhase(PhaseEvent event) {
		if (event.getPhaseId() == PhaseId.RENDER_RESPONSE) {
			FacesContext facesContext = event.getFacesContext();
			restoreMessages(facesContext);
		}
	}

	/**
	 * Handle a notification that the processing for a particular phase has just
	 * been completed.
	 */
	public void afterPhase(PhaseEvent event) {
		if (event.getPhaseId() == PhaseId.APPLY_REQUEST_VALUES
				|| event.getPhaseId() == PhaseId.PROCESS_VALIDATIONS
				|| event.getPhaseId() == PhaseId.INVOKE_APPLICATION) {
			FacesContext facesContext = event.getFacesContext();
			saveMessages(facesContext);
		}
	}

	/**
	 * Remove the messages that are not associated with any particular component
	 * from the faces context and store them to the user's session.
	 * 
	 * @return the number of removed messages.
	 */
	@SuppressWarnings("unchecked")
	private int saveMessages(FacesContext facesContext) {
		// remove messages from the context
		Set<FacesMessage> messages = new HashSet<FacesMessage>();
		for (Iterator i = facesContext.getMessages(null); i.hasNext();) {
			FacesMessage msg = (FacesMessage) i.next();
			messages.add(msg);
			i.remove();
		}
		// store them in the session
		if (messages.size() == 0)
			return 0;
		Map sessionMap = facesContext.getExternalContext().getSessionMap();
		// if there already are messages
		Set<FacesMessage> existingMessages = (Set<FacesMessage>) sessionMap
				.get(sessionToken);
		if (existingMessages != null) {
			existingMessages.addAll(messages);
			// if these are the first messages
		} else {
			sessionMap.put(sessionToken, messages);
		}
		return messages.size();
	}

	/**
	 * Remove the messages that are not associated with any particular component
	 * from the user's session and add them to the faces context.
	 * 
	 * @return the number of removed messages.
	 */
	@SuppressWarnings("unchecked")
	private int restoreMessages(FacesContext facesContext) {
		// remove messages from the session
		Map sessionMap = facesContext.getExternalContext().getSessionMap();
		Set<FacesMessage> messages = (Set<FacesMessage>) sessionMap
				.remove(sessionToken);
		// store them in the context
		if (messages == null)
			return 0;
		int restoredCount = messages.size();

		// set that contains wich messages already exists in the FacesContext
		Set<FacesMessage> facesContextMessages = new HashSet<FacesMessage>();
		for (Iterator i = facesContext.getMessages(null); i.hasNext();) {
			FacesMessage msg = (FacesMessage) i.next();
			facesContextMessages.add(msg);
			i.remove();
		}

		// add the messages that aren't in the FacesContext 
		for (FacesMessage facesMessage : messages) {
			if (!facesContextMessages.contains(facesMessage))
				facesContext.addMessage(null, facesMessage);
		}
		return restoredCount;
	}
}