package com.softwaremill.common.faces.navigation; import com.softwaremill.common.cdi.util.BeanInject; import com.softwaremill.common.faces.messages.FacesMessages; import javax.faces.application.FacesMessage; import javax.faces.component.UIComponent; import javax.faces.component.UIViewParameter; import javax.faces.component.UIViewRoot; import javax.faces.context.FacesContext; import javax.faces.event.PhaseEvent; import javax.faces.event.PhaseId; import javax.faces.event.PhaseListener; import javax.faces.view.ViewDeclarationLanguage; import javax.faces.view.ViewMetadata; import java.io.IOException; /** * @author Adam Warski (adam at warski dot org) */ public class RequiredViewParameterPhaseListener implements PhaseListener { public void beforePhase(PhaseEvent event) { // Getting the current view id FacesContext ctx = event.getFacesContext(); if (ctx.isPostback()) { return; } String viewId = ctx.getViewRoot().getViewId(); // Getting the metadata facet ViewDeclarationLanguage vdl = ctx.getApplication().getViewHandler().getViewDeclarationLanguage(ctx, viewId); ViewMetadata viewMetadata = vdl.getViewMetadata(ctx, viewId); UIViewRoot viewRoot = viewMetadata.createMetadataView(ctx); UIComponent metadataFacet = viewRoot.getFacet(UIViewRoot.METADATA_FACET_NAME); if (metadataFacet != null) { // Checking each parameter for (UIComponent child : metadataFacet.getChildren()) { if (child instanceof UIViewParameter) { UIViewParameter viewParameter = (UIViewParameter) child; // Checking if the parameter is required but has an empty value if (viewParameter.getRequiredMessage() != null && isEmpty(viewParameter.getStringValue(ctx))) { // Adding the message FacesMessages messages = BeanInject.lookup(FacesMessages.class); messages.addEL(viewParameter.getRequiredMessage(), FacesMessage.SEVERITY_ERROR); // Redirecting to the error page NavBase nav = BeanInject.lookup(NavBase.class); String url = ctx.getApplication().getViewHandler().getActionURL(ctx, nav.getError().s()); try { ctx.getExternalContext().redirect(ctx.getExternalContext().encodeActionURL(url)); } catch (IOException e) { throw new RuntimeException(e); } ctx.responseComplete(); return; } } } } } public void afterPhase(PhaseEvent event) { } private boolean isEmpty(String s) { return s == null || "".equals(s.trim()); } @Override public PhaseId getPhaseId() { return PhaseId.RENDER_RESPONSE; } }