package org.hdiv.components; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.faces.FacesException; import javax.faces.component.UIComponent; import javax.faces.component.UIParameter; import javax.faces.component.html.HtmlOutcomeTargetLink; import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; import javax.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hdiv.config.HDIVConfig; import org.hdiv.dataComposer.IDataComposer; import org.hdiv.helper.OutcomeTargetComponentHelper; import org.hdiv.util.Constants; import org.hdiv.util.HDIVUtil; import org.hdiv.util.RequestUtilsHDIV; /** * Extends HtmlOutcomeTargetLink in order to secure component * * @author gillarramendi * */ public class HtmlOutcomeTargetLinkExtension extends HtmlOutcomeTargetLink { private static Log log = LogFactory.getLog(HtmlOutcomeTargetLinkExtension.class); /** * Helper for creating component's url */ private OutcomeTargetComponentHelper helper = new OutcomeTargetComponentHelper(); /* * (non-Javadoc) * * @see * javax.faces.component.UIComponentBase#encodeBegin(javax.faces.context * .FacesContext) */ public void encodeBegin(FacesContext context) throws IOException { if (log.isDebugEnabled()) { log.debug("encodeBegin"); } try { ExternalContext externalContext = context.getExternalContext(); HttpServletRequest request = (HttpServletRequest) externalContext.getRequest(); String url = this.helper.getUrl(context, this); // Component creates internal links, so HDIV state must always be created HDIVConfig hdivConfig = HDIVUtil.getHDIVConfig(request.getSession().getServletContext()); // if url has not got parameters, we do not have to include HDIV's // state if (!hdivConfig.isValidationInUrlsWithoutParamsActivated() && !url.contains("?") && !this.helper.hasUIParamChilds(this)) { super.encodeBegin(context); return; } // Check if url points to a resource that doesn't need to be secured, // as an image if (RequestUtilsHDIV.isResourceUrl(hdivConfig, url)) { if (log.isDebugEnabled()) { log.debug("is resource url"); } super.encodeBegin(context); return; } // Get DataComposer object from request IDataComposer dataComposer = HDIVUtil.getDataComposer(request); // Confidentiality is disabled, so url doesn't change String encodedUrl = RequestUtilsHDIV.composeURL(request, dataComposer, url); // HDIV's state id, just created String requestId = dataComposer.endRequest(); String hdivParameter = (String) externalContext.getSessionMap().get(Constants.HDIV_PARAMETER); // Add a children UIParam component with HDIV state UIParameter paramComponent = (UIParameter) context.getApplication().createComponent( UIParameter.COMPONENT_TYPE); paramComponent.setName(hdivParameter); paramComponent.setValue(requestId); this.getChildren().add(paramComponent); } catch (FacesException e) { log.error("Error en HtmlOutputLinkExtension: " + e.getMessage()); throw e; } super.encodeBegin(context); } /* * (non-Javadoc) * * @see javax.faces.component.UIComponentBase#encodeEnd(javax.faces.context. * FacesContext) */ public void encodeEnd(FacesContext context) throws IOException { super.encodeEnd(context); // Remove the component with the HDIV state, we don't want to store // it in the state String hdivParameter = (String) context.getExternalContext().getSessionMap().get(Constants.HDIV_PARAMETER); Iterator it = this.getChildren().iterator(); List<Integer> toRemoveList = new ArrayList<Integer>(); while (it.hasNext()) { UIComponent comp = (UIComponent) it.next(); if (comp instanceof UIParameter) { UIParameter param = (UIParameter) comp; String name = param.getName(); if (name != null && name.equals(hdivParameter)) { Integer index = this.getChildren().indexOf(param); toRemoveList.add(index); } } } for (Integer index : toRemoveList) { this.getChildren().remove(index.intValue()); } } }