You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ef...@apache.org on 2007/07/15 18:29:59 UTC
svn commit: r556424 - in
/myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/ppr:
PPRPanelGroup.java PPRPanelGroupRenderer.java PPRPhaseListener.java
Author: efastl
Date: Sun Jul 15 09:29:54 2007
New Revision: 556424
URL: http://svn.apache.org/viewvc?view=rev&rev=556424
Log:
Fix for TOMAHAWK-1052 (render transient components in PPR updates) + long overdue JavaDoc
Modified:
myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/ppr/PPRPanelGroup.java
myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/ppr/PPRPanelGroupRenderer.java
myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/ppr/PPRPhaseListener.java
Modified: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/ppr/PPRPanelGroup.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/ppr/PPRPanelGroup.java?view=diff&rev=556424&r1=556423&r2=556424
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/ppr/PPRPanelGroup.java (original)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/ppr/PPRPanelGroup.java Sun Jul 15 09:29:54 2007
@@ -18,145 +18,168 @@
*/
package org.apache.myfaces.custom.ppr;
-import org.apache.myfaces.component.html.ext.HtmlPanelGroup;
-import org.apache.myfaces.shared_tomahawk.util._ComponentUtils;
-
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
+import org.apache.myfaces.component.html.ext.HtmlPanelGroup;
+import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
+
/**
+ * AJAX component which supports updating its children via AJAX calls. These
+ * updates can occur regularly or based on triggering input components.
+ *
* @author Ernst Fastl
*/
public class PPRPanelGroup extends HtmlPanelGroup {
- public static final String COMPONENT_TYPE = "org.apache.myfaces.PPRPanelGroup";
+ public static final String COMPONENT_TYPE = "org.apache.myfaces.PPRPanelGroup";
- public static final String COMPONENT_FAMILY = "org.apache.myfaces.PPRPanelGroup";
+ public static final String COMPONENT_FAMILY = "org.apache.myfaces.PPRPanelGroup";
- public static final String DEFAULT_RENDERER_TYPE = "org.apache.myfaces.PPRPanelGroup";
+ public static final String DEFAULT_RENDERER_TYPE = "org.apache.myfaces.PPRPanelGroup";
- private String _partialTriggers;
+ private String _partialTriggers;
- private Integer _periodicalUpdate;
+ private Integer _periodicalUpdate;
private String _periodicalTriggers;
private String _partialTriggerPattern;
- private String _inlineLoadingMessage;
-
- private Boolean _showDebugMessages = new Boolean(false);
+ private String _inlineLoadingMessage;
- private Boolean _stateUpdate = new Boolean(true);
+ private Boolean _showDebugMessages = new Boolean(false);
- public PPRPanelGroup() {
- setRendererType(DEFAULT_RENDERER_TYPE);
- }
+ private Boolean _stateUpdate = new Boolean(true);
- public String getFamily() {
- return COMPONENT_FAMILY;
- }
-
- public String getPartialTriggers() {
- if (_partialTriggers != null)
- return _partialTriggers;
- ValueBinding vb = getValueBinding("partialTriggers");
- return vb != null ? _ComponentUtils.getStringValue(getFacesContext(), vb) : null;
- }
-
- public void setPartialTriggers(String partialTriggers) {
- this._partialTriggers = partialTriggers;
- }
-
- public Integer getPeriodicalUpdate() {
- if (_periodicalUpdate != null)
- return _periodicalUpdate;
- ValueBinding vb = getValueBinding("periodicalUpdate");
- return (vb != null) ? (Integer) vb.getValue(getFacesContext()) : null;
- }
-
- public void setPeriodicalUpdate(Integer periodicalUpdate) {
- _periodicalUpdate = periodicalUpdate;
- }
-
- public String getPeriodicalTriggers() {
- if (_periodicalTriggers != null)
- return _periodicalTriggers;
- ValueBinding vb = getValueBinding("periodicalTriggers");
- return (vb != null) ? (String) vb.getValue(getFacesContext()) : null;
- }
-
- public void setPeriodicalTriggers(String periodicalTriggers) {
- _periodicalTriggers = periodicalTriggers;
- }
-
- public String getPartialTriggerPattern() {
- if (_partialTriggerPattern != null)
- return _partialTriggerPattern;
- ValueBinding vb = getValueBinding("partialTriggerPattern");
- return vb != null ? _ComponentUtils.getStringValue(getFacesContext(), vb) : null;
- }
-
- public void setPartialTriggerPattern(String partialTriggerPattern) {
- this._partialTriggerPattern = partialTriggerPattern;
- }
-
- public String getInlineLoadingMessage() {
- if (_inlineLoadingMessage != null)
- return _inlineLoadingMessage;
- ValueBinding vb = getValueBinding("inlineLoadingMessage");
- return vb != null ? _ComponentUtils.getStringValue(getFacesContext(), vb) : null;
- }
-
- public void setInlineLoadingMessage(String inlineLoadingMessage) {
- this._inlineLoadingMessage = inlineLoadingMessage;
- }
-
- public Boolean getShowDebugMessages() {
- if (_showDebugMessages != null) {
- return _showDebugMessages;
- }
- ValueBinding vb = getValueBinding("showDebugMessages");
- return vb != null ? (Boolean) vb.getValue(getFacesContext()) : null;
- }
-
- public void setShowDebugMessages(Boolean showDebugMessages) {
- _showDebugMessages = showDebugMessages;
- }
-
- public Boolean getStateUpdate() {
- if (_stateUpdate != null) {
- return _stateUpdate;
- }
- ValueBinding vb = getValueBinding("stateUpdate");
- return vb != null ? (Boolean) vb.getValue(getFacesContext()) : null;
- }
-
- public void setStateUpdate(Boolean stateUpdate) {
- _stateUpdate = stateUpdate;
- }
-
- public void restoreState(FacesContext context, Object state) {
-
- Object[] values = (Object[]) state;
- super.restoreState(context, values[0]);
- _partialTriggers = (String) values[1];
- _partialTriggerPattern = (String) values[2];
- _periodicalUpdate = (Integer) values[3];
- _periodicalTriggers = (String) values[4];
- _showDebugMessages = (Boolean) values[5];
- _stateUpdate = (Boolean) values[6];
-
- }
-
- public Object saveState(FacesContext context) {
- Object[] values = new Object[7];
- values[0] = super.saveState(context);
- values[1] = _partialTriggers;
- values[2] = _partialTriggerPattern;
- values[3] = _periodicalUpdate;
- values[4] = _periodicalTriggers;
- values[5] = _showDebugMessages;
- values[6] = _stateUpdate;
- return values;
- }
+ public PPRPanelGroup()
+ {
+ setRendererType(DEFAULT_RENDERER_TYPE);
+ }
+
+ public String getFamily()
+ {
+ return COMPONENT_FAMILY;
+ }
+
+ public String getPartialTriggers()
+ {
+ if (_partialTriggers != null)
+ return _partialTriggers;
+ ValueBinding vb = getValueBinding("partialTriggers");
+ return vb != null ? RendererUtils.getStringValue(getFacesContext(), vb) : null;
+ }
+
+ public void setPartialTriggers(String partialTriggers)
+ {
+ this._partialTriggers = partialTriggers;
+ }
+
+ public Integer getPeriodicalUpdate()
+ {
+ if (_periodicalUpdate != null)
+ return _periodicalUpdate;
+ ValueBinding vb = getValueBinding("periodicalUpdate");
+ return (vb != null) ? (Integer) vb.getValue(getFacesContext()) : null;
+ }
+
+ public void setPeriodicalUpdate(Integer periodicalUpdate)
+ {
+ _periodicalUpdate = periodicalUpdate;
+ }
+
+ public String getPeriodicalTriggers()
+ {
+ if (_periodicalTriggers != null)
+ return _periodicalTriggers;
+ ValueBinding vb = getValueBinding("periodicalTriggers");
+ return (vb != null) ? (String) vb.getValue(getFacesContext()) : null;
+ }
+
+ public void setPeriodicalTriggers(String periodicalTriggers)
+ {
+ _periodicalTriggers = periodicalTriggers;
+ }
+
+ public String getPartialTriggerPattern()
+ {
+ if (_partialTriggerPattern != null)
+ return _partialTriggerPattern;
+ ValueBinding vb = getValueBinding("partialTriggerPattern");
+ return vb != null ? RendererUtils.getStringValue(getFacesContext(), vb) : null;
+ }
+
+ public void setPartialTriggerPattern(String partialTriggerPattern)
+ {
+ this._partialTriggerPattern = partialTriggerPattern;
+ }
+
+ public String getInlineLoadingMessage()
+ {
+ if (_inlineLoadingMessage != null)
+ return _inlineLoadingMessage;
+ ValueBinding vb = getValueBinding("inlineLoadingMessage");
+ return vb != null ? RendererUtils.getStringValue(getFacesContext(), vb) : null;
+ }
+
+ public void setInlineLoadingMessage(String inlineLoadingMessage)
+ {
+ this._inlineLoadingMessage = inlineLoadingMessage;
+ }
+
+ public Boolean getShowDebugMessages()
+ {
+ if (_showDebugMessages != null)
+ {
+ return _showDebugMessages;
+ }
+ ValueBinding vb = getValueBinding("showDebugMessages");
+ return vb != null ? (Boolean) vb.getValue(getFacesContext()) : null;
+ }
+
+ public void setShowDebugMessages(Boolean showDebugMessages)
+ {
+ _showDebugMessages = showDebugMessages;
+ }
+
+ public Boolean getStateUpdate()
+ {
+ if (_stateUpdate != null)
+ {
+ return _stateUpdate;
+ }
+ ValueBinding vb = getValueBinding("stateUpdate");
+ return vb != null ? (Boolean) vb.getValue(getFacesContext()) : null;
+ }
+
+ public void setStateUpdate(Boolean stateUpdate)
+ {
+ _stateUpdate = stateUpdate;
+ }
+
+ public void restoreState(FacesContext context, Object state)
+ {
+
+ Object[] values = (Object[]) state;
+ super.restoreState(context, values[0]);
+ _partialTriggers = (String) values[1];
+ _partialTriggerPattern = (String) values[2];
+ _periodicalUpdate = (Integer) values[3];
+ _periodicalTriggers = (String) values[4];
+ _showDebugMessages = (Boolean) values[5];
+ _stateUpdate = (Boolean) values[6];
+
+ }
+
+ public Object saveState(FacesContext context)
+ {
+ Object[] values = new Object[7];
+ values[0] = super.saveState(context);
+ values[1] = _partialTriggers;
+ values[2] = _partialTriggerPattern;
+ values[3] = _periodicalUpdate;
+ values[4] = _periodicalTriggers;
+ values[5] = _showDebugMessages;
+ values[6] = _stateUpdate;
+ return values;
+ }
}
Modified: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/ppr/PPRPanelGroupRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/ppr/PPRPanelGroupRenderer.java?view=diff&rev=556424&r1=556423&r2=556424
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/ppr/PPRPanelGroupRenderer.java (original)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/ppr/PPRPanelGroupRenderer.java Sun Jul 15 09:29:54 2007
@@ -43,248 +43,353 @@
* @author Ernst Fastl
*/
public class PPRPanelGroupRenderer extends HtmlGroupRenderer {
- public static final String PPR_INITIALIZED = "org.apache.myfaces.ppr.INITIALIZED";
+ public static final String PPR_INITIALIZED = "org.apache.myfaces.ppr.INITIALIZED";
- public static final String PPR_RESPONSE = "org.apache.myfaces.ppr.RESPONSE";
+ private static Log log = LogFactory.getLog(PPRPanelGroupRenderer.class);
- private static Log log = LogFactory.getLog(PPRPanelGroupRenderer.class);
-
- private static final String ADD_PARTIAL_TRIGGER_FUNCTION = "addPartialTrigger";
+ private static final String ADD_PARTIAL_TRIGGER_FUNCTION = "addPartialTrigger";
private static final String ADD_PERIODICAL_TRIGGER_FUNCTION = "addPeriodicalTrigger";
private static final String ADD_PARTIAL_TRIGGER_PATTERN_FUNCTION = "addPartialTriggerPattern";
- private static final String ADD_INLINE_LOADING_MESSAGE_FUNCTION = "addInlineLoadingMessage";
+ private static final String ADD_INLINE_LOADING_MESSAGE_FUNCTION = "addInlineLoadingMessage";
+
+ private static final String PPR_JS_FILE = "ppr.js";
- private static final String PPR_JS_FILE = "ppr.js";
+ private static final String MY_FACES_PPR_INIT_CODE = "new org.apache.myfaces.PPRCtrl";
- private static final String MY_FACES_PPR_INIT_CODE = "new org.apache.myfaces.PPRCtrl";
private static final String DISABLE_RENDER_CHILDREN = "org.apache.myfaces.PPRPanelGroup.disableRenderChildren";
- public void encodeJavaScript(FacesContext facesContext, PPRPanelGroup pprGroup) throws IOException {
-
- final ExternalContext externalContext = facesContext.getExternalContext();
-
- final Map requestMap = externalContext.getRequestMap();
-
- //Do not render the JavaScript if answering to a PPR response
- if (requestMap.containsKey(PPR_RESPONSE)) {
- return;
- }
+ public static final String TRANSIENT_MARKER_ATTRIBUTE = "org.apache.myfaces.PPRPanelGroup.transientComponent";
- FormInfo fi = RendererUtils.findNestingForm(pprGroup, facesContext);
- if (fi == null) {
- throw new FacesException("PPRPanelGroup must be embedded in a form.");
- }
+ /**
+ * Renders the start of a span element. Iterates over all child
+ * components and sets transient components to transient=false. Those
+ * components are marked with the TRANSIENT_MARKER_ATTRIBUTE so the
+ * {@link PPRPhaseListener} can reset them to transient in the next
+ * non-PPR Request
+ *
+ * @param facesContext
+ * the current {@link FacesContext}
+ * @param uiComponent
+ * the {@link PPRPanelGroup} to render
+ */
+ public void encodeBegin(FacesContext facesContext, UIComponent uiComponent) throws IOException
+ {
+ if (uiComponent.getId() == null || uiComponent.getId().startsWith(UIViewRoot.UNIQUE_ID_PREFIX))
+ {
+ throw new IllegalArgumentException("'id' is a required attribute for the PPRPanelGroup");
+ }
- if (!requestMap.containsKey(PPR_INITIALIZED)) {
- requestMap.put(PPR_INITIALIZED, Boolean.TRUE);
+ // todo: in 1.2, better use a combo of
+ // invokeComponent/RendererUtils.renderChildren() instead
+ uiComponent.getAttributes().put(DISABLE_RENDER_CHILDREN, Boolean.TRUE);
+
+ // Iterate over the transient child components and set transient to
+ // false
+ // This is necessary to have those components available for PPR
+ // responses later on
+ for (Iterator iter = uiComponent.getChildren().iterator(); iter.hasNext();)
+ {
+ UIComponent child = (UIComponent) iter.next();
+ if (child.isTransient())
+ {
+ child.setTransient(false);
+ child.getAttributes().put(TRANSIENT_MARKER_ATTRIBUTE, Boolean.TRUE);
+ }
+ }
- String javascriptLocation = (String) pprGroup.getAttributes().get(JSFAttr.JAVASCRIPT_LOCATION);
- AddResource addResource = AddResourceFactory.getInstance(facesContext);
- DojoUtils.addMainInclude(facesContext, pprGroup, javascriptLocation, new DojoConfig());
- DojoUtils.addRequire(facesContext, pprGroup, "dojo.io.*");
- DojoUtils.addRequire(facesContext, pprGroup, "dojo.event.*");
- addResource.addJavaScriptAtPosition(facesContext, AddResource.HEADER_BEGIN, PPRPanelGroup.class, PPR_JS_FILE);
- }
+ super.encodeBegin(facesContext, uiComponent);
+ }
- StringBuffer script = new StringBuffer();
+ /**
+ * todo: in 1.2, better use a combo of
+ * invokeComponent/RendererUtils.renderChildren() instead
+ *
+ * @param context
+ * @param component
+ * @throws IOException
+ */
+ public void encodeChildren(FacesContext context, UIComponent component) throws IOException
+ {
+ Boolean disableRenderChildren = (Boolean) component.getAttributes().get(DISABLE_RENDER_CHILDREN);
- // all JS is put inside a function passed to dojoOnLoad
- //this is necessary in order to be able to replace all button onClick handlers
+ if (disableRenderChildren != null && disableRenderChildren.booleanValue() == false)
+ RendererUtils.renderChildren(context, component);
+ }
- script.append("dojo.addOnLoad( function(){ ");
+ /**
+ * Encodes the end of the span-element and afterwards the inline
+ * JavaScript for the client side initialization of the
+ * {@link PPRPanelGroup}.
+ *
+ * @param facesContext
+ * the current {@link FacesContext}
+ * @param uiComponent
+ * the {@link PPRPanelGroup} to render
+ */
+ public void encodeEnd(FacesContext facesContext, UIComponent uiComponent) throws IOException
+ {
+ // Render the span end element
+ super.encodeEnd(facesContext, uiComponent);
+ if (uiComponent instanceof PPRPanelGroup)
+ {
+ PPRPanelGroup pprGroup = (PPRPanelGroup) uiComponent;
+
+ final String triggers = pprGroup.getPartialTriggers();
+ final String triggerPattern = pprGroup.getPartialTriggerPattern();
+
+ // Check if triggers, a pattern or a periodical update is
+ // defined
+ if ((triggers != null && triggers.length() > 0) || (triggerPattern != null && triggerPattern.length() > 0)
+ || pprGroup.getPeriodicalUpdate() != null)
+ {
+ // encode the initialization inline JavaScript
+ encodeJavaScript(facesContext, pprGroup);
+ }
+ }
+ // todo: in 1.2, better use a combo of
+ // invokeComponent/RendererUtils.renderChildren() instead
+ uiComponent.getAttributes().put(DISABLE_RENDER_CHILDREN, Boolean.FALSE);
+ }
- final String formName = fi.getFormName();
-
- String pprCtrlReference = "dojo.byId('" + formName + "').myFacesPPRCtrl";
+ /**
+ * Renders inline JavaScript registering an onLoad function for:
+ * <ul>
+ * <li>Initializing the PPRCtrl for the current Form</li>
+ * <li>Registering partialTriggers</li>
+ * <li>Registering partialTriggerPatterns</li>
+ * <li>Starting periodical updates</li>
+ * <li>Registering inline Loading messages</li>
+ * </ul>
+ *
+ * @param facesContext
+ * the current {@link FacesContext}
+ * @param pprGroup
+ * the currently rendered {@link PPRPanelGroup}
+ * @throws IOException
+ * if the underlying Layer throws an {@link IOException}
+ * it is passed through
+ */
+ private void encodeJavaScript(FacesContext facesContext, PPRPanelGroup pprGroup) throws IOException
+ {
- if (!requestMap.containsKey(PPR_INITIALIZED + "." + formName)) {
- requestMap.put(PPR_INITIALIZED + "." + formName, Boolean.TRUE);
+ final ExternalContext externalContext = facesContext.getExternalContext();
- script.append(pprCtrlReference + "=" + MY_FACES_PPR_INIT_CODE + "('" + formName + "',"
- + pprGroup.getShowDebugMessages().booleanValue() + "," + pprGroup.getStateUpdate().booleanValue() + ");\n");
+ final Map requestMap = externalContext.getRequestMap();
- if (pprGroup.getPeriodicalUpdate() != null) {
- script.append(pprCtrlReference + ".registerOnSubmitInterceptor();");
- }
+ // Do not render the JavaScript if answering to a PPR response
+ if (PPRPhaseListener.isPartialRequest(facesContext))
+ {
+ return;
+ }
- }
+ FormInfo fi = RendererUtils.findNestingForm(pprGroup, facesContext);
+ if (fi == null)
+ {
+ throw new FacesException("PPRPanelGroup must be embedded in a form.");
+ }
- String clientId = pprGroup.getClientId(facesContext);
+ //Initialize the client side PPR engine
+ if (!requestMap.containsKey(PPR_INITIALIZED))
+ {
+ requestMap.put(PPR_INITIALIZED, Boolean.TRUE);
+
+ String javascriptLocation = (String) pprGroup.getAttributes().get(JSFAttr.JAVASCRIPT_LOCATION);
+ AddResource addResource = AddResourceFactory.getInstance(facesContext);
+ DojoUtils.addMainInclude(facesContext, pprGroup, javascriptLocation, new DojoConfig());
+ DojoUtils.addRequire(facesContext, pprGroup, "dojo.io.*");
+ DojoUtils.addRequire(facesContext, pprGroup, "dojo.event.*");
+ addResource.addJavaScriptAtPosition(facesContext, AddResource.HEADER_BEGIN, PPRPanelGroup.class,
+ PPR_JS_FILE);
+ }
- if (pprGroup.getPeriodicalUpdate() != null) {
- String periodicalTriggers = pprGroup.getPeriodicalTriggers();
- //If no periodicalTriggers are set just start the periodical update
- if (periodicalTriggers == null || periodicalTriggers.trim().length() <= 0) {
- script.append(pprCtrlReference + ".startPeriodicalUpdate(" + pprGroup.getPeriodicalUpdate() + ",'" + clientId
- + "');");
- }
- //Otherwise start it when the trigger happens
- else {
- List partialTriggers = (new PartialTriggerParser()).parse(periodicalTriggers);
- String periodicalTriggerId;
- String periodicalTriggerClientId;
- UIComponent periodicalTriggerComponent;
- for (int i=0; i<partialTriggers.size();i++) {
- PartialTriggerParser.PartialTrigger trigger = (PartialTriggerParser.PartialTrigger) partialTriggers.get(i);
- periodicalTriggerId = trigger.getPartialTriggerId();
- periodicalTriggerComponent = pprGroup.findComponent(periodicalTriggerId);
- if (periodicalTriggerComponent == null) {
- periodicalTriggerComponent = facesContext.getViewRoot().findComponent(periodicalTriggerId);
- }
-
- //Component found
- if (periodicalTriggerComponent != null) {
- periodicalTriggerClientId = periodicalTriggerComponent.getClientId(facesContext);
- script.append(pprCtrlReference + "." + ADD_PERIODICAL_TRIGGER_FUNCTION + "('" + periodicalTriggerClientId + "',"+
- encodeArray(trigger.getEventHooks())+",'"
- + clientId + "', " + pprGroup.getPeriodicalUpdate() + ");");
-
-
- //Component missing
- } else {
- if (log.isDebugEnabled()) {
- log.debug("PPRPanelGroupRenderer Component with id " + periodicalTriggerId + " not found!");
- }
- }
- }
- }
- }
+ StringBuffer script = new StringBuffer();
- String partialTriggerId;
- String partialTriggerClientId;
- UIComponent partialTriggerComponent;
-
- String partialTriggers = pprGroup.getPartialTriggers();
-
- String partialTriggerPattern = pprGroup.getPartialTriggerPattern();
- if (partialTriggerPattern != null && partialTriggerPattern.trim().length() > 0) {
- script.append(pprCtrlReference + "." + ADD_PARTIAL_TRIGGER_PATTERN_FUNCTION + "('" + partialTriggerPattern
- + "','" + clientId + "');");
- }
+ // all JS is put inside a function passed to dojoOnLoad
+ // this is necessary in order to be able to replace all button onClick
+ // handlers
- String inlineLoadingMessage = pprGroup.getInlineLoadingMessage();
+ script.append("dojo.addOnLoad( function(){ ");
- if (inlineLoadingMessage != null && inlineLoadingMessage.trim().length() > 0) {
- script.append(pprCtrlReference + "." + ADD_INLINE_LOADING_MESSAGE_FUNCTION + "('" + inlineLoadingMessage + "','"
- + clientId + "');");
- }
+ final String formName = fi.getFormName();
+
+ String pprCtrlReference = "dojo.byId('" + formName + "').myFacesPPRCtrl";
+
+ //Each form containing PPRPanelGroups has its own PPRCtrl
+ if (!requestMap.containsKey(PPR_INITIALIZED + "." + formName))
+ {
+ requestMap.put(PPR_INITIALIZED + "." + formName, Boolean.TRUE);
+
+ script.append(pprCtrlReference + "=" + MY_FACES_PPR_INIT_CODE + "('" + formName + "',"
+ + pprGroup.getShowDebugMessages().booleanValue() + "," + pprGroup.getStateUpdate().booleanValue()
+ + ");\n");
+
+ if (pprGroup.getPeriodicalUpdate() != null)
+ {
+ script.append(pprCtrlReference + ".registerOnSubmitInterceptor();");
+ }
- if (partialTriggers != null && partialTriggers.trim().length() > 0) {
- List partialTriggerIds = (new PartialTriggerParser()).parse(partialTriggers);
- for (int i=0; i<partialTriggerIds.size();i++) {
- PartialTriggerParser.PartialTrigger trigger = (PartialTriggerParser.PartialTrigger) partialTriggerIds.get(i);
- partialTriggerId = trigger.getPartialTriggerId();
- partialTriggerComponent = pprGroup.findComponent(partialTriggerId);
- if (partialTriggerComponent == null) {
- partialTriggerComponent = facesContext.getViewRoot().findComponent(partialTriggerId);
- }
- if (partialTriggerComponent != null) {
- partialTriggerClientId = partialTriggerComponent.getClientId(facesContext);
- script.append(pprCtrlReference + "." + ADD_PARTIAL_TRIGGER_FUNCTION + "('" + partialTriggerClientId + "',"+encodeArray(trigger.getEventHooks())+",'"
- + clientId + "');");
- } else {
- if (log.isDebugEnabled()) {
- log.debug("PPRPanelGroupRenderer Component with id " + partialTriggerId + " not found!");
- }
- }
+ }
+
+ String clientId = pprGroup.getClientId(facesContext);
+
+ //Handle periodical updates
+ if (pprGroup.getPeriodicalUpdate() != null)
+ {
+ String periodicalTriggers = pprGroup.getPeriodicalTriggers();
+ // If no periodicalTriggers are set just start the periodical
+ // update
+ if (periodicalTriggers == null || periodicalTriggers.trim().length() <= 0)
+ {
+ script.append(pprCtrlReference + ".startPeriodicalUpdate(" + pprGroup.getPeriodicalUpdate() + ",'"
+ + clientId + "');");
+ }
+ // Otherwise start it when the trigger happens
+ else
+ {
+ List partialTriggers = (new PartialTriggerParser()).parse(periodicalTriggers);
+ String periodicalTriggerId;
+ String periodicalTriggerClientId;
+ UIComponent periodicalTriggerComponent;
+ for (int i = 0; i < partialTriggers.size(); i++)
+ {
+ PartialTriggerParser.PartialTrigger trigger = (PartialTriggerParser.PartialTrigger) partialTriggers
+ .get(i);
+ periodicalTriggerId = trigger.getPartialTriggerId();
+ periodicalTriggerComponent = pprGroup.findComponent(periodicalTriggerId);
+ if (periodicalTriggerComponent == null)
+ {
+ periodicalTriggerComponent = facesContext.getViewRoot().findComponent(periodicalTriggerId);
+ }
+
+ // Component found
+ if (periodicalTriggerComponent != null)
+ {
+ periodicalTriggerClientId = periodicalTriggerComponent.getClientId(facesContext);
+ script.append(pprCtrlReference + "." + ADD_PERIODICAL_TRIGGER_FUNCTION + "('"
+ + periodicalTriggerClientId + "'," + encodeArray(trigger.getEventHooks()) + ",'"
+ + clientId + "', " + pprGroup.getPeriodicalUpdate() + ");");
+
+ // Component missing
+ } else
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("PPRPanelGroupRenderer Component with id " + periodicalTriggerId + " not found!");
}
+ }
}
+ }
+ }
- //closing the dojo.addOnLoad call
- script.append("});");
- renderInlineScript(facesContext, pprGroup, script.toString());
- }
-
- private String encodeArray(List eventHooks) {
- if(eventHooks==null || eventHooks.size()==0) {
- return "null";
- }
- else{
- StringBuffer buf = new StringBuffer();
- buf.append("[");
-
- for (int i = 0; i < eventHooks.size(); i++) {
- if(i>0)
- buf.append(",");
- String eventHook = (String) eventHooks.get(i);
- buf.append("'");
- buf.append(eventHook);
- buf.append("'");
- }
- buf.append("]");
-
- return buf.toString();
- }
- }
-
- public void encodeBegin(FacesContext facesContext, UIComponent uiComponent) throws IOException {
- if (uiComponent.getId() == null || uiComponent.getId().startsWith(UIViewRoot.UNIQUE_ID_PREFIX)) {
- throw new IllegalArgumentException("'id' is a required attribute for the PPRPanelGroup");
- }
+ String partialTriggerId;
+ String partialTriggerClientId;
+ UIComponent partialTriggerComponent;
+
+ String partialTriggers = pprGroup.getPartialTriggers();
+
+ String partialTriggerPattern = pprGroup.getPartialTriggerPattern();
+
+ //handle partial trigger patterns
+ if (partialTriggerPattern != null && partialTriggerPattern.trim().length() > 0)
+ {
+ script.append(pprCtrlReference + "." + ADD_PARTIAL_TRIGGER_PATTERN_FUNCTION + "('" + partialTriggerPattern
+ + "','" + clientId + "');");
+ }
- //todo: in 1.2, better use a combo of invokeComponent/RendererUtils.renderChildren() instead
- uiComponent.getAttributes().put(DISABLE_RENDER_CHILDREN,Boolean.TRUE);
+ String inlineLoadingMessage = pprGroup.getInlineLoadingMessage();
- super.encodeBegin(facesContext, uiComponent);
+ //handle inline loading messages
+ if (inlineLoadingMessage != null && inlineLoadingMessage.trim().length() > 0)
+ {
+ script.append(pprCtrlReference + "." + ADD_INLINE_LOADING_MESSAGE_FUNCTION + "('" + inlineLoadingMessage
+ + "','" + clientId + "');");
}
- /** todo: in 1.2, better use a combo of invokeComponent/RendererUtils.renderChildren() instead
- *
- * @param context
- * @param component
- * @throws IOException
- */
- public void encodeChildren(FacesContext context, UIComponent component)
- throws IOException
- {
- Boolean disableRenderChildren = (Boolean) component.getAttributes().get(DISABLE_RENDER_CHILDREN);
-
- if(disableRenderChildren!=null && disableRenderChildren.booleanValue()==false)
- RendererUtils.renderChildren(context, component);
- }
-
- public void encodeEnd(FacesContext facesContext, UIComponent uiComponent) throws IOException {
- super.encodeEnd(facesContext, uiComponent);
- if (uiComponent instanceof PPRPanelGroup) {
- PPRPanelGroup pprGroup = (PPRPanelGroup) uiComponent;
-
- final String triggers = pprGroup.getPartialTriggers();
- final String triggerPattern = pprGroup.getPartialTriggerPattern();
-
- if ((triggers != null && triggers.length() > 0)
- || (triggerPattern != null && triggerPattern.length() > 0)
- || pprGroup.getPeriodicalUpdate() != null) {
- encodeJavaScript(facesContext, pprGroup);
- }
+ //handle partial triggers
+ if (partialTriggers != null && partialTriggers.trim().length() > 0)
+ {
+ List partialTriggerIds = (new PartialTriggerParser()).parse(partialTriggers);
+ for (int i = 0; i < partialTriggerIds.size(); i++)
+ {
+ PartialTriggerParser.PartialTrigger trigger = (PartialTriggerParser.PartialTrigger) partialTriggerIds
+ .get(i);
+ partialTriggerId = trigger.getPartialTriggerId();
+ partialTriggerComponent = pprGroup.findComponent(partialTriggerId);
+ if (partialTriggerComponent == null)
+ {
+ partialTriggerComponent = facesContext.getViewRoot().findComponent(partialTriggerId);
+ }
+ if (partialTriggerComponent != null)
+ {
+ partialTriggerClientId = partialTriggerComponent.getClientId(facesContext);
+ script.append(pprCtrlReference + "." + ADD_PARTIAL_TRIGGER_FUNCTION + "('" + partialTriggerClientId
+ + "'," + encodeArray(trigger.getEventHooks()) + ",'" + clientId + "');");
+ } else
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("PPRPanelGroupRenderer Component with id " + partialTriggerId + " not found!");
+ }
}
+ }
+ }
- //todo: in 1.2, better use a combo of invokeComponent/RendererUtils.renderChildren() instead
- uiComponent.getAttributes().put(DISABLE_RENDER_CHILDREN,Boolean.FALSE);
+ // closing the dojo.addOnLoad call
+ script.append("});");
+
+ //Really render the script
+ renderInlineScript(facesContext, pprGroup, script.toString());
}
- /**
- * Helper to write an inline javascript at the exact resource location of the
- * call.
- *
- * @param facesContext
- * The current faces-context.
- * @param component
- * The component for which the script is written.
- * @param script
- * The script to be written.
- * @throws IOException
- * A forwarded exception from the underlying renderer.
- */
- private static void renderInlineScript(FacesContext facesContext, UIComponent component, String script)
- throws IOException {
- ResponseWriter writer = facesContext.getResponseWriter();
- writer.startElement(HTML.SCRIPT_ELEM, component);
- writer.writeAttribute(HTML.TYPE_ATTR, HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT, null);
- writer.write(script);
- writer.endElement(HTML.SCRIPT_ELEM);
+ private String encodeArray(List eventHooks)
+ {
+ if (eventHooks == null || eventHooks.size() == 0)
+ {
+ return "null";
+ } else
+ {
+ StringBuffer buf = new StringBuffer();
+ buf.append("[");
+
+ for (int i = 0; i < eventHooks.size(); i++)
+ {
+ if (i > 0)
+ buf.append(",");
+ String eventHook = (String) eventHooks.get(i);
+ buf.append("'");
+ buf.append(eventHook);
+ buf.append("'");
+ }
+ buf.append("]");
+
+ return buf.toString();
}
+ }
+
+ /**
+ * Helper to write an inline javascript at the exact resource location
+ * of the call.
+ *
+ * @param facesContext
+ * The current faces-context.
+ * @param component
+ * The component for which the script is written.
+ * @param script
+ * The script to be written.
+ * @throws IOException
+ * A forwarded exception from the underlying renderer.
+ */
+ private static void renderInlineScript(FacesContext facesContext, UIComponent component, String script)
+ throws IOException
+ {
+ ResponseWriter writer = facesContext.getResponseWriter();
+ writer.startElement(HTML.SCRIPT_ELEM, component);
+ writer.writeAttribute(HTML.TYPE_ATTR, HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT, null);
+ writer.write(script);
+ writer.endElement(HTML.SCRIPT_ELEM);
+ }
}
Modified: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/ppr/PPRPhaseListener.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/ppr/PPRPhaseListener.java?view=diff&rev=556424&r1=556423&r2=556424
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/ppr/PPRPhaseListener.java (original)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/ppr/PPRPhaseListener.java Sun Jul 15 09:29:54 2007
@@ -18,11 +18,11 @@
*/
package org.apache.myfaces.custom.ppr;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
-import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlResponseWriterImpl;
-import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.StringTokenizer;
import javax.faces.FacesException;
import javax.faces.application.StateManager;
@@ -35,143 +35,287 @@
import javax.faces.event.PhaseListener;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.Map;
-import java.util.StringTokenizer;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlResponseWriterImpl;
/**
+ * Before RenderResponse PhaseListener for processing Ajax requests from
+ * {@link PPRPanelGroup}. It also participates in handling transient components
+ * in PPR Requests
+ *
* @author Ernst Fastl
*/
public class PPRPhaseListener implements PhaseListener {
- private static Log log = LogFactory.getLog(PPRPhaseListener.class);
+ private static Log log = LogFactory.getLog(PPRPhaseListener.class);
- private static final String PPR_PARAMETER = "org.apache.myfaces.PPRCtrl.ajaxRequest";
+ /**
+ * Request parameter which marks a request as PPR request
+ */
+ private static final String PPR_PARAMETER = "org.apache.myfaces.PPRCtrl.ajaxRequest";
+
+ /**
+ * Request parameter containing a comma separated list of component IDs
+ * of the to be updated components
+ */
+ private static final String TRIGGERED_COMPONENTS_PARAMETER = "org.apache.myfaces.PPRCtrl.triggeredComponents";
- private static final String TRIGGERED_COMPONENTS_PARAMETER = "org.apache.myfaces.PPRCtrl.triggeredComponents";
+ private static final String XML_HEADER = "<?xml version=\"1.0\"?>\n";
- private static final String XML_HEADER = "<?xml version=\"1.0\"?>\n";
+ public void afterPhase(PhaseEvent phaseEvent)
+ {
+ }
- public void afterPhase(PhaseEvent phaseEvent) {
+ /**
+ * Determines wether the currently processed request is a PPR request
+ * (by searching for PPR_PARAMETER in the request parameter map) or an
+ * ordinary HTTP request. If the request is a PPR request the triggered
+ * components are encoded. Otherwise transient components which have
+ * previously been marked not transient by the
+ * {@link PPRPanelGroupRenderer} are set to transient again
+ */
+ public void beforePhase(PhaseEvent event)
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("In PPRPhaseListener beforePhase");
}
- public void beforePhase(PhaseEvent event) {
- if (log.isDebugEnabled()) {
- log.debug("In PPRPhaseListener beforePhase");
- }
+ final FacesContext context = event.getFacesContext();
+ final ExternalContext externalContext = context.getExternalContext();
- final FacesContext context = event.getFacesContext();
- final ExternalContext externalContext = context.getExternalContext();
- Map externalRequestMap = externalContext.getRequestParameterMap();
+ Map requestMap = externalContext.getRequestMap();
- Map requestMap = externalContext.getRequestMap();
+ if (isPartialRequest(context))
+ {
+ processPartialPageRequest(context, externalContext, requestMap);
+ } else
+ {
+ // Iterate over the component tree and set all previously
+ // transient components to transient again
+ resetTransientComponents(context.getViewRoot());
+ }
+ }
- if (externalRequestMap.containsKey(PPR_PARAMETER)) {
- processPartialPageRequest(context, externalContext, requestMap);
- }
+ /**
+ * if the provided component was marked transient in the last request
+ * set it to transient. Recursively do the same for all children
+ *
+ * @param comp
+ * the component to reset
+ */
+ private void resetTransientComponents(UIComponent comp)
+ {
+ if (comp.getAttributes().containsKey(PPRPanelGroupRenderer.TRANSIENT_MARKER_ATTRIBUTE))
+ {
+ comp.setTransient(true);
}
+ for (Iterator iter = comp.getChildren().iterator(); iter.hasNext();)
+ {
+ UIComponent child = (UIComponent) iter.next();
+ resetTransientComponents(child);
+ }
+ }
- private void processPartialPageRequest(FacesContext context, final ExternalContext externalContext, Map requestMap) {
- //If the PhaseListener is invoked the second time do nothing
- if(requestMap.containsKey(PPRPanelGroupRenderer.PPR_RESPONSE))
- return;
- requestMap.put(PPRPanelGroupRenderer.PPR_RESPONSE, Boolean.TRUE);
-
- ServletResponse response = (ServletResponse) externalContext.getResponse();
- ServletRequest request = (ServletRequest) externalContext.getRequest();
-
- UIViewRoot viewRoot = context.getViewRoot();
- final String characterEncoding = request.getCharacterEncoding();
- String contentType = getContentType("text/xml", characterEncoding);
- response.setContentType(contentType);
- response.setLocale(viewRoot.getLocale());
- String triggeredComponents = getTriggeredComponents(context);
-
- try {
- PrintWriter out = response.getWriter();
- context.setResponseWriter(new HtmlResponseWriterImpl(out, contentType, characterEncoding));
- out.print(XML_HEADER);
- out.print("<response>\n");
- encodeTriggeredComponents(out, triggeredComponents, viewRoot, context);
- out.print("</response>");
- out.flush();
- } catch (IOException e) {
- throw new FacesException(e);
- }
+ /**
+ * Checks if the currently processed Request is an AJAX request from a
+ * PPRPanelGroup
+ *
+ * @param context
+ * the current {@link FacesContext}
+ * @return true if a PPR request is being processed , false otherwise
+ */
+ public static boolean isPartialRequest(FacesContext context)
+ {
+ return context.getExternalContext().getRequestParameterMap().containsKey(PPR_PARAMETER);
+ }
- context.responseComplete();
+ /**
+ * Respond to an AJAX request from a {@link PPRPanelGroup}. The
+ * triggered components are determined by reading the
+ * TRIGGERED_COMPONENTS_PARAMETER from either the RequestParameterMap or
+ * the Request Map. Those componenets are encoded into an XML response.
+ * The lifecycle is quit afterwards.
+ *
+ * @param context
+ * the current {@link FacesContext}
+ * @param externalContext
+ * the current {@link ExternalContext}
+ * @param requestMap
+ * Map containing the request attributes
+ */
+ private void processPartialPageRequest(FacesContext context, final ExternalContext externalContext, Map requestMap)
+ {
+
+ ServletResponse response = (ServletResponse) externalContext.getResponse();
+ ServletRequest request = (ServletRequest) externalContext.getRequest();
+
+ UIViewRoot viewRoot = context.getViewRoot();
+
+ // Set Character encoding, contentType and locale for the response
+ final String characterEncoding = request.getCharacterEncoding();
+ String contentType = getContentType("text/xml", characterEncoding);
+ response.setContentType(contentType);
+ response.setLocale(viewRoot.getLocale());
+
+ // Fetch the comma-separated list of triggered components
+ String triggeredComponents = getTriggeredComponents(context);
+
+ try
+ {
+ PrintWriter out = response.getWriter();
+ context.setResponseWriter(new HtmlResponseWriterImpl(out, contentType, characterEncoding));
+ out.print(XML_HEADER);
+ out.print("<response>\n");
+ encodeTriggeredComponents(out, triggeredComponents, viewRoot, context);
+ out.print("</response>");
+ out.flush();
+ } catch (IOException e)
+ {
+ throw new FacesException(e);
}
- private static String getTriggeredComponents(FacesContext fc) {
- String triggeredComponents = (String) fc.getExternalContext().getRequestMap().get(TRIGGERED_COMPONENTS_PARAMETER);
+ context.responseComplete();
+ }
- if(triggeredComponents == null) {
- triggeredComponents = (String) fc.getExternalContext().getRequestParameterMap().get(TRIGGERED_COMPONENTS_PARAMETER);
- }
-
- return triggeredComponents;
- }
-
- public static void addTriggeredComponent(FacesContext fc, String triggeredComponentClientId) {
- String triggeredComponents = getTriggeredComponents(fc);
-
- if(triggeredComponents == null || triggeredComponents.trim().length()==0) {
- triggeredComponents = new String();
- }
- else {
- triggeredComponents = triggeredComponents+",";
- }
-
- triggeredComponents = triggeredComponents+triggeredComponentClientId;
-
- fc.getExternalContext().getRequestMap().put(TRIGGERED_COMPONENTS_PARAMETER, triggeredComponents);
- }
-
- private String getContentType(String contentType, String charset) {
- if (charset == null || charset.trim().length() == 0)
- return contentType;
- else
- return contentType + ";charset=" + charset;
- }
-
- private void encodeTriggeredComponents(PrintWriter out, String triggeredComponents, UIViewRoot viewRoot,
- FacesContext context) {
- StringTokenizer st = new StringTokenizer(triggeredComponents, ",", false);
- String clientId;
- UIComponent component;
- while (st.hasMoreTokens()) {
- clientId = st.nextToken();
- component = viewRoot.findComponent(clientId);
- if (component != null) {
- out.print("<component id=\"" + component.getClientId(context) + "\"><![CDATA[");
- boolean oldValue = HtmlRendererUtils.isAllowedCdataSection(context);
- HtmlRendererUtils.allowCdataSection(context, false);
- try {
- component.encodeChildren(context);
- } catch (IOException e) {
- throw new FacesException(e);
- }
- HtmlRendererUtils.allowCdataSection(context, oldValue);
- out.print("]]></component>");
- } else {
- log.debug("PPRPhaseListener component with id" + clientId + "not found!");
- }
- }
- out.print("<state>");
- FacesContext facesContext = FacesContext.getCurrentInstance();
- StateManager stateManager = facesContext.getApplication().getStateManager();
- StateManager.SerializedView serializedView = stateManager.saveSerializedView(facesContext);
- try {
- stateManager.writeState(facesContext, serializedView);
- } catch (IOException e) {
- throw new FacesException(e);
- }
+ /**
+ * Fetch the comma-separated list of triggered components. They are
+ * either obtained from the Request Parameter Map where they had
+ * previously been set using
+ * {@link PPRPhaseListener#addTriggeredComponent(FacesContext, String))
+ * or from the request parameter map.
+ *
+ * @param fc
+ * the current {@link FacesContext}
+ * @return a comma separated list of component IDs of the components
+ * which are to be updated
+ */
+ private static String getTriggeredComponents(FacesContext fc)
+ {
+ String triggeredComponents = (String) fc.getExternalContext().getRequestMap().get(
+ TRIGGERED_COMPONENTS_PARAMETER);
+
+ if (triggeredComponents == null)
+ {
+ triggeredComponents = (String) fc.getExternalContext().getRequestParameterMap().get(
+ TRIGGERED_COMPONENTS_PARAMETER);
+ }
- out.print("</state>");
+ return triggeredComponents;
+ }
+ /**
+ * API method for adding triggeredComponents programmatically.
+ *
+ * @param fc
+ * the current {@link FacesContext}
+ * @param triggeredComponentClientId
+ * client ID of the component which is to be updated in
+ * case of a PPR Response
+ */
+ public static void addTriggeredComponent(FacesContext fc, String triggeredComponentClientId)
+ {
+ String triggeredComponents = getTriggeredComponents(fc);
+
+ if (triggeredComponents == null || triggeredComponents.trim().length() == 0)
+ {
+ triggeredComponents = new String();
+ } else
+ {
+ triggeredComponents = triggeredComponents + ",";
}
- public PhaseId getPhaseId() {
- return PhaseId.RENDER_RESPONSE;
+ triggeredComponents = triggeredComponents + triggeredComponentClientId;
+
+ fc.getExternalContext().getRequestMap().put(TRIGGERED_COMPONENTS_PARAMETER, triggeredComponents);
+ }
+
+ /**
+ * Generate content-type String either containing only the mime-type or
+ * mime-type and character enconding.
+ *
+ * @param contentType
+ * the contentType/mimeType
+ * @param charset
+ * the character set
+ * @return the content-type String to be used in an HTTP response
+ */
+ private String getContentType(String contentType, String charset)
+ {
+ if (charset == null || charset.trim().length() == 0)
+ return contentType;
+ else
+ return contentType + ";charset=" + charset;
+ }
+
+ /**
+ * Writes the XML elements for the triggered components to the provided
+ * {@link PrintWriter}. Also encode the current state in a separate XML
+ * element.
+ *
+ * @param out
+ * the output Writer
+ * @param triggeredComponents
+ * comma-separated list of component IDs
+ * @param viewRoot
+ * the current ViewRoot
+ * @param context
+ * the current {@link FacesContext}
+ */
+ private void encodeTriggeredComponents(PrintWriter out, String triggeredComponents, UIViewRoot viewRoot,
+ FacesContext context)
+ {
+ StringTokenizer st = new StringTokenizer(triggeredComponents, ",", false);
+ String clientId;
+ UIComponent component;
+ // Iterate over the individual client IDs
+ while (st.hasMoreTokens())
+ {
+ clientId = st.nextToken();
+ component = viewRoot.findComponent(clientId);
+ if (component != null)
+ {
+ // Write a component tag which contains a CDATA section whith
+ // the rendered HTML
+ // of the component children
+ out.print("<component id=\"" + component.getClientId(context) + "\"><![CDATA[");
+ boolean oldValue = HtmlRendererUtils.isAllowedCdataSection(context);
+ HtmlRendererUtils.allowCdataSection(context, false);
+ try
+ {
+ component.encodeChildren(context);
+ } catch (IOException e)
+ {
+ throw new FacesException(e);
+ }
+ HtmlRendererUtils.allowCdataSection(context, oldValue);
+ out.print("]]></component>");
+ } else
+ {
+ log.debug("PPRPhaseListener component with id" + clientId + "not found!");
+ }
+ }
+ // Write the serialized state into a separate XML element
+ out.print("<state>");
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ StateManager stateManager = facesContext.getApplication().getStateManager();
+ StateManager.SerializedView serializedView = stateManager.saveSerializedView(facesContext);
+ try
+ {
+ stateManager.writeState(facesContext, serializedView);
+ } catch (IOException e)
+ {
+ throw new FacesException(e);
}
+
+ out.print("</state>");
+
+ }
+
+ public PhaseId getPhaseId()
+ {
+ return PhaseId.RENDER_RESPONSE;
+ }
}