Author: nbelaevski
Date: 2010-04-14 17:48:59 -0400 (Wed, 14 Apr 2010)
New Revision: 16761
Modified:
root/framework/trunk/impl/src/main/java/org/richfaces/context/PartialViewContextFactoryImpl.java
root/framework/trunk/impl/src/main/java/org/richfaces/context/PartialViewContextImpl.java
Log:
https://jira.jboss.org/jira/browse/RF-8589
Modified:
root/framework/trunk/impl/src/main/java/org/richfaces/context/PartialViewContextFactoryImpl.java
===================================================================
---
root/framework/trunk/impl/src/main/java/org/richfaces/context/PartialViewContextFactoryImpl.java 2010-04-14
17:18:38 UTC (rev 16760)
+++
root/framework/trunk/impl/src/main/java/org/richfaces/context/PartialViewContextFactoryImpl.java 2010-04-14
21:48:59 UTC (rev 16761)
@@ -21,14 +21,10 @@
package org.richfaces.context;
-import java.util.Map;
-
import javax.faces.context.FacesContext;
import javax.faces.context.PartialViewContext;
import javax.faces.context.PartialViewContextFactory;
-import org.ajax4jsf.renderkit.AjaxRendererUtils;
-
/**
* @author Nick Belaevski
* @since 4.0
@@ -44,15 +40,7 @@
@Override
public PartialViewContext getPartialViewContext(final FacesContext context) {
- Map<String, String> requestParameterMap =
context.getExternalContext().getRequestParameterMap();
- String activatorComponentId =
requestParameterMap.get(AjaxRendererUtils.AJAX_COMPONENT_ID_PARAMETER);
- if (activatorComponentId != null) {
- String behaviorEvent =
requestParameterMap.get(AjaxRendererUtils.BEHAVIOR_EVENT_PARAMETER);
-
- return new PartialViewContextImpl(context, activatorComponentId,
behaviorEvent);
- } else {
- return parentFactory.getPartialViewContext(context);
- }
+ return new PartialViewContextImpl(parentFactory.getPartialViewContext(context),
context);
}
@Override
Modified:
root/framework/trunk/impl/src/main/java/org/richfaces/context/PartialViewContextImpl.java
===================================================================
---
root/framework/trunk/impl/src/main/java/org/richfaces/context/PartialViewContextImpl.java 2010-04-14
17:18:38 UTC (rev 16760)
+++
root/framework/trunk/impl/src/main/java/org/richfaces/context/PartialViewContextImpl.java 2010-04-14
21:48:59 UTC (rev 16761)
@@ -21,10 +21,7 @@
*/
package org.richfaces.context;
-import static org.ajax4jsf.renderkit.AjaxRendererUtils.ALL;
-
import java.io.IOException;
-import java.io.Writer;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
@@ -58,20 +55,19 @@
private static final Logger LOG = RichfacesLogger.CONTEXT.getLogger();
- private static final String FACES_REQUEST_HEADER = "Faces-Request";
- private static final String PARTIAL_AJAX = "partial/ajax";
- private static final String PARTIAL_PROCESS = "partial/process";
-
private static final String ORIGINAL_WRITER =
"org.richfaces.PartialViewContextImpl.ORIGINAL_WRITER";
+ private enum ContextMode {
+ WRAPPED, DIRECT
+ }
+
+ private ContextMode contextMode = null;
+
private FacesContext facesContext;
- private PartialResponseWriter partialResponseWriter;
private Collection<String> executeIds = null;
private Collection<String> renderIds = null;
- private Boolean ajaxRequest = null;
- private Boolean partialRequest = null;
private Boolean renderAll = null;
private String activatorComponentId = null;
@@ -81,187 +77,167 @@
private boolean limitRender = false;
- public PartialViewContextImpl(FacesContext facesContext, String activatorComponentId,
String behaviorEvent) {
+ private PartialViewContext wrappedViewContext;
+
+ public PartialViewContextImpl(PartialViewContext wrappedViewContext, FacesContext
facesContext) {
super();
+ this.wrappedViewContext = wrappedViewContext;
this.facesContext = facesContext;
-
- //activatorComponentId should not be null
- this.activatorComponentId = activatorComponentId;
- this.behaviorEvent = behaviorEvent;
}
@Override
public Collection<String> getExecuteIds() {
assertNotReleased();
- if (executeIds == null) {
- executeIds = new LinkedHashSet<String>();
- setupExecuteIds(executeIds);
- }
+ if (detectContextMode() == ContextMode.DIRECT) {
+ if (executeIds == null) {
+ executeIds = new LinkedHashSet<String>();
+ setupExecuteIds(executeIds);
+ }
- return executeIds;
+ return executeIds;
+ } else {
+ return wrappedViewContext.getExecuteIds();
+ }
}
@Override
public Collection<String> getRenderIds() {
assertNotReleased();
- if (renderIds == null) {
- renderIds = new LinkedHashSet<String>();
- }
+ if (detectContextMode() == ContextMode.DIRECT) {
+ if (renderIds == null) {
+ renderIds = new LinkedHashSet<String>();
+ }
- return renderIds;
+ return renderIds;
+ } else {
+ return wrappedViewContext.getRenderIds();
+ }
}
@Override
public boolean isAjaxRequest() {
assertNotReleased();
- if (ajaxRequest == null) {
- Map<String, String> requestHeaderMap =
facesContext.getExternalContext().getRequestHeaderMap();
- ajaxRequest =
PARTIAL_AJAX.equals(requestHeaderMap.get(FACES_REQUEST_HEADER));
- }
-
- return ajaxRequest.booleanValue();
+ return wrappedViewContext.isAjaxRequest();
}
@Override
public boolean isPartialRequest() {
assertNotReleased();
- if (partialRequest == null) {
- if (isAjaxRequest()) {
- partialRequest = true;
- } else {
- Map<String, String> requestHeaderMap =
facesContext.getExternalContext().getRequestHeaderMap();
- partialRequest =
PARTIAL_PROCESS.equals(requestHeaderMap.get(FACES_REQUEST_HEADER));
- }
- }
-
- return partialRequest.booleanValue();
+ return wrappedViewContext.isPartialRequest();
}
@Override
public void setPartialRequest(boolean isPartialRequest) {
assertNotReleased();
- partialRequest = isPartialRequest;
+ wrappedViewContext.setPartialRequest(isPartialRequest);
}
@Override
public boolean isExecuteAll() {
assertNotReleased();
- return getExecuteIds().contains(ALL);
+ if (detectContextMode() == ContextMode.DIRECT) {
+ return getExecuteIds().contains(AjaxRendererUtils.ALL);
+ } else {
+ return wrappedViewContext.isExecuteAll();
+ }
}
@Override
public boolean isRenderAll() {
assertNotReleased();
- if (renderAll == null) {
- renderAll = getRenderIds().contains(ALL);
- }
+ if (detectContextMode() == ContextMode.DIRECT) {
+ if (renderAll != null) {
+ return renderAll.booleanValue();
+ }
- return renderAll;
+ return getRenderIds().contains(AjaxRendererUtils.ALL);
+ } else {
+ return wrappedViewContext.isRenderAll();
+ }
}
@Override
public void setRenderAll(boolean isRenderAll) {
assertNotReleased();
- renderAll = isRenderAll;
+ if (detectContextMode() == ContextMode.DIRECT) {
+ renderAll = isRenderAll;
+ } else {
+ wrappedViewContext.setRenderAll(isRenderAll);
+ }
}
@Override
public PartialResponseWriter getPartialResponseWriter() {
- assertNotReleased();
-
- if (partialResponseWriter == null) {
- partialResponseWriter = new
PartialDelayedInitializationResponseWriter(facesContext);
- }
-
- return partialResponseWriter;
+ return wrappedViewContext.getPartialResponseWriter();
}
@Override
public void processPartial(PhaseId phaseId) {
+ if (detectContextMode() == ContextMode.DIRECT && phaseId ==
PhaseId.RENDER_RESPONSE) {
+ processPartialRenderPhase();
+ } else {
+ wrappedViewContext.processPartial(phaseId);
+ }
+ }
+
+ protected void processPartialRenderPhase() {
PartialViewContext pvc = facesContext.getPartialViewContext();
UIViewRoot viewRoot = facesContext.getViewRoot();
+ Collection<String> phaseIds = pvc.getRenderIds();
+ setupRenderIds(phaseIds);
- Collection<String> executeIds = pvc.getExecuteIds();
- Collection<String> renderIds = pvc.getRenderIds();
+ try {
+ PartialResponseWriter writer = pvc.getPartialResponseWriter();
+ ResponseWriter orig = facesContext.getResponseWriter();
+ facesContext.getAttributes().put(ORIGINAL_WRITER, orig);
+ facesContext.setResponseWriter(writer);
- if (phaseId == PhaseId.APPLY_REQUEST_VALUES
- || phaseId == PhaseId.PROCESS_VALIDATIONS
- || phaseId == PhaseId.UPDATE_MODEL_VALUES) {
-
- // Skip this processing if "none" is specified in the render list,
- // or there were no execute phase client ids.
- if (executeIds == null || executeIds.isEmpty()) {
- // RELEASE_PENDING LOG ERROR OR WARNING
+ ExternalContext exContext = facesContext.getExternalContext();
+ exContext.setResponseContentType("text/xml");
+ exContext.addResponseHeader("Cache-Control",
"no-cache");
+ writer.startDocument();
+ if (isRenderAll()) {
+ renderAll(facesContext, viewRoot);
+ renderState(facesContext);
+ writer.endDocument();
return;
}
- try {
- processComponents(viewRoot, phaseId, executeIds, facesContext);
- } catch (Exception e) {
- LOG.error(e.getMessage(), e);
- }
+ // Skip this processing if "none" is specified in the render list,
+ // or there were no render phase client ids.
+ if ((phaseIds != null && !phaseIds.isEmpty()) ||
+ (!limitRender &&
PartialViewContextAjaxOutputTracker.hasNestedAjaxOutputs(viewRoot))) {
- // If we have just finished APPLY_REQUEST_VALUES phase, install the
- // partial response writer. We want to make sure that any content
- // or errors generated in the other phases are written using the
- // partial response writer.
- //
- if (phaseId == PhaseId.APPLY_REQUEST_VALUES) {
- PartialResponseWriter writer = pvc.getPartialResponseWriter();
- facesContext.setResponseWriter(writer);
+ EnumSet<VisitHint> hints = EnumSet.of(VisitHint.SKIP_UNRENDERED);
+ VisitContext visitContext = new ExtendedPartialVisitContext(facesContext,
phaseIds, hints, limitRender);
+ VisitCallback visitCallback = new RenderVisitCallback(facesContext);
+ viewRoot.visitTree(visitContext, visitCallback);
}
- } else if (phaseId == PhaseId.RENDER_RESPONSE) {
- setupRenderIds(renderIds);
- try {
- PartialResponseWriter writer = pvc.getPartialResponseWriter();
- ResponseWriter orig = facesContext.getResponseWriter();
- facesContext.getAttributes().put(ORIGINAL_WRITER, orig);
- facesContext.setResponseWriter(writer);
+ renderState(facesContext);
- ExternalContext exContext = facesContext.getExternalContext();
- exContext.setResponseContentType("text/xml");
- exContext.addResponseHeader("Cache-Control",
"no-cache");
- writer.startDocument();
- if (isRenderAll()) {
- renderAll(facesContext, viewRoot);
- renderState(facesContext);
- writer.endDocument();
- return;
- }
+ //TODO - render extensions for renderAll?
+ renderExtensions(facesContext, viewRoot);
- // Skip this processing if "none" is specified in the render
list,
- // or there were no render phase client ids.
- if ((renderIds != null && !renderIds.isEmpty()) ||
- (!limitRender &&
PartialViewContextAjaxOutputTracker.hasNestedAjaxOutputs(viewRoot))) {
- processComponents(viewRoot, phaseId, renderIds, facesContext);
- }
-
- renderState(facesContext);
-
- //TODO - render extensions for renderAll?
- renderExtensions(facesContext, viewRoot);
-
- writer.endDocument();
- } catch (IOException ex) {
- ex.printStackTrace();
- //TODO - review?
- this.cleanupAfterView();
- } catch (RuntimeException ex) {
- //TODO - review?
- this.cleanupAfterView();
- // Throw the exception
- throw ex;
- }
+ writer.endDocument();
+ } catch (IOException ex) {
+ this.cleanupAfterView();
+ //TODO - review?
+ ex.printStackTrace();
+ } catch (RuntimeException ex) {
+ //TODO - review?
+ this.cleanupAfterView();
+ // Throw the exception
+ throw ex;
}
}
@@ -271,7 +247,7 @@
if (visitActivatorComponent(activatorComponentId, callback)) {
ids.addAll(callback.getComponentIds());
- if (!ids.contains(ALL)) {
+ if (!ids.contains(AjaxRendererUtils.ALL)) {
addImplicitExecuteIds(ids);
}
} else {
@@ -288,8 +264,8 @@
ids.addAll(callback.getComponentIds());
limitRender = callback.isLimitRender();
- if (!Boolean.TRUE.equals(renderAll) && !ids.contains(ALL)) {
- addImplicitRenderIds(ids, callback.isLimitRender());
+ if (!Boolean.TRUE.equals(renderAll) &&
!ids.contains(AjaxRendererUtils.ALL)) {
+ addImplicitRenderIds(ids, limitRender);
//TODO - review
AjaxContext ajaxContext = AjaxContext.getCurrentInstance();
@@ -303,31 +279,6 @@
}
}
- // Process the components specified in the phaseClientIds list
- private void processComponents(UIComponent component, PhaseId phaseId,
- Collection<String> phaseClientIds, FacesContext
context) throws IOException {
-
- // We use the tree visitor mechanism to locate the components to
- // process. Create our (partial) VisitContext and the
- // VisitCallback that will be invoked for each component that
- // is visited. Note that we use the SKIP_UNRENDERED hint as we
- // only want to visit the rendered subtree.
- EnumSet<VisitHint> hints = EnumSet.of(VisitHint.SKIP_UNRENDERED);
-
- VisitCallback visitCallback;
- VisitContext visitContext;
-
- if (PhaseId.RENDER_RESPONSE.equals(phaseId)) {
- visitContext = new ExtendedPartialVisitContext(facesContext, phaseClientIds,
hints, limitRender);
- visitCallback = new RenderVisitCallback(facesContext);
- } else {
- visitContext = VisitContext.createVisitContext(facesContext, phaseClientIds,
hints);
- visitCallback = new PhaseAwareExecuteVisitCallback(facesContext, phaseId);
- }
-
- component.visitTree(visitContext, visitCallback);
- }
-
private void renderAll(FacesContext context, UIViewRoot viewRoot) throws IOException
{
// If this is a "render all via ajax" request,
// make sure to wrap the entire page in a <render> elemnt
@@ -370,19 +321,20 @@
released = true;
+ wrappedViewContext.release();
+ wrappedViewContext = null;
+
facesContext = null;
- partialResponseWriter = null;
+ renderAll = null;
executeIds = null;
renderIds = null;
- ajaxRequest = null;
- partialRequest = null;
- renderAll = null;
limitRender = false;
activatorComponentId = null;
behaviorEvent = null;
+ contextMode = null;
}
protected void addImplicitExecuteIds(Collection<String> ids) {
@@ -427,40 +379,20 @@
facesContext.setResponseWriter(orig);
}
- private static final class PhaseAwareExecuteVisitCallback implements VisitCallback {
+ protected ContextMode detectContextMode() {
+ if (contextMode == null) {
+ Map<String, String> requestParameterMap =
facesContext.getExternalContext().getRequestParameterMap();
+ activatorComponentId =
requestParameterMap.get(AjaxRendererUtils.AJAX_COMPONENT_ID_PARAMETER);
- private PhaseId curPhase;
- private FacesContext ctx;
-
- private PhaseAwareExecuteVisitCallback(FacesContext ctx, PhaseId curPhase) {
- this.ctx = ctx;
- this.curPhase = curPhase;
- }
-
- public VisitResult visit(VisitContext context, UIComponent comp) {
- if (curPhase == PhaseId.APPLY_REQUEST_VALUES) {
-
- // RELEASE_PENDING handle immediate request(s)
- // If the user requested an immediate request
- // Make sure to set the immediate flag here.
-
- comp.processDecodes(ctx);
- } else if (curPhase == PhaseId.PROCESS_VALIDATIONS) {
- comp.processValidators(ctx);
- } else if (curPhase == PhaseId.UPDATE_MODEL_VALUES) {
- comp.processUpdates(ctx);
+ if (activatorComponentId != null) {
+ contextMode = ContextMode.DIRECT;
+ behaviorEvent =
requestParameterMap.get(AjaxRendererUtils.BEHAVIOR_EVENT_PARAMETER);
} else {
- throw new IllegalStateException("I18N: Unexpected "
- + "PhaseId passed to PhaseAwareContextCallback: " +
curPhase.toString());
+ contextMode = ContextMode.WRAPPED;
}
-
- // Once we visit a component, there is no need to visit
- // its children, since processDecodes/Validators/Updates and
- // encodeAll() already traverse the subtree. We return
- // VisitResult.REJECT to supress the subtree visit.
- return VisitResult.REJECT;
}
+ return contextMode;
}
private static final class RenderVisitCallback implements VisitCallback {
@@ -507,56 +439,4 @@
return VisitResult.REJECT;
}
}
-
- private static final class PartialDelayedInitializationResponseWriter extends
PartialResponseWriter {
-
- private FacesContext facesContext;
-
- private ResponseWriter responseWriter;
-
- /**
- * @param facesContext
- */
- public PartialDelayedInitializationResponseWriter(FacesContext facesContext) {
- super(null);
- this.facesContext = facesContext;
- ExternalContext externalContext = facesContext.getExternalContext();
- externalContext.setResponseContentType("text/xml");
-
externalContext.setResponseCharacterEncoding(externalContext.getRequestCharacterEncoding());
- }
-
- /* (non-Javadoc)
- * @see javax.faces.context.PartialResponseWriter#getWrapped()
- */
- @Override
- public ResponseWriter getWrapped() {
- if (responseWriter == null) {
- responseWriter = createResponseWriter();
- }
-
- return responseWriter;
- }
-
- private ResponseWriter createResponseWriter() {
- ExternalContext externalContext = facesContext.getExternalContext();
- String characterEncoding = externalContext.getRequestCharacterEncoding();
- externalContext.setResponseCharacterEncoding(characterEncoding);
-
- Writer outputWriter = null;
- try {
- outputWriter = externalContext.getResponseOutputWriter();
- } catch (IOException e) {
- LOG.error("Error creating partial context response writer: " +
e.getMessage(), e);
- }
-
- if (outputWriter != null) {
- ResponseWriter newResponseWriter = facesContext.getRenderKit().
- createResponseWriter(outputWriter, "text/xml",
characterEncoding);
-
- return newResponseWriter;
- }
-
- return null;
- }
- }
}