Author: nbelaevski
Date: 2009-11-04 19:47:56 -0500 (Wed, 04 Nov 2009)
New Revision: 15827
Modified:
root/framework/trunk/api/src/main/java/org/ajax4jsf/context/AjaxContext.java
root/framework/trunk/impl/src/main/java/org/ajax4jsf/context/AjaxContextImpl.java
root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/AjaxRendererUtils.java
root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/RendererUtils.java
root/framework/trunk/impl/src/main/java/org/richfaces/context/ComponentCallback.java
root/framework/trunk/impl/src/main/java/org/richfaces/context/ExecuteComponentCallback.java
root/framework/trunk/impl/src/main/java/org/richfaces/context/PartialViewContextFactoryImpl.java
root/framework/trunk/impl/src/main/java/org/richfaces/context/PartialViewContextImpl.java
root/framework/trunk/impl/src/main/java/org/richfaces/context/RenderComponentCallback.java
root/framework/trunk/impl/src/main/java/org/richfaces/resource/AnimatedTestResource.java
root/framework/trunk/impl/src/main/resources/META-INF/resources/richfaces.js
root/framework/trunk/impl/src/test/resources/javascript/4_0_0.html
root/ui/trunk/components/core/src/main/java/org/ajax4jsf/renderkit/AjaxBehaviorRenderer.java
Log:
https://jira.jboss.org/jira/browse/RF-7823
Modified: root/framework/trunk/api/src/main/java/org/ajax4jsf/context/AjaxContext.java
===================================================================
---
root/framework/trunk/api/src/main/java/org/ajax4jsf/context/AjaxContext.java 2009-11-05
00:45:08 UTC (rev 15826)
+++
root/framework/trunk/api/src/main/java/org/ajax4jsf/context/AjaxContext.java 2009-11-05
00:47:56 UTC (rev 15827)
@@ -65,6 +65,10 @@
public abstract Object getOncomplete();
+ public abstract void setOnbeforedomupdate(Object onbeforedomupdateFunction);
+
+ public abstract Object getOnbeforedomupdate();
+
public abstract void setViewIdHolder(ViewIdHolder viewIdHolder);
public abstract ViewIdHolder getViewIdHolder();
Modified:
root/framework/trunk/impl/src/main/java/org/ajax4jsf/context/AjaxContextImpl.java
===================================================================
---
root/framework/trunk/impl/src/main/java/org/ajax4jsf/context/AjaxContextImpl.java 2009-11-05
00:45:08 UTC (rev 15826)
+++
root/framework/trunk/impl/src/main/java/org/ajax4jsf/context/AjaxContextImpl.java 2009-11-05
00:47:56 UTC (rev 15827)
@@ -23,23 +23,10 @@
package org.ajax4jsf.context;
-import org.ajax4jsf.Messages;
-import org.ajax4jsf.application.AjaxViewHandler;
-import org.ajax4jsf.renderkit.AjaxContainerRenderer;
-import org.ajax4jsf.renderkit.AjaxRendererUtils;
-import org.ajax4jsf.renderkit.RendererUtils;
-import org.ajax4jsf.renderkit.RendererUtils.HTML;
-
-import org.richfaces.log.RichfacesLogger;
-
-import org.slf4j.Logger;
-
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
-
import java.lang.reflect.Method;
-
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -60,10 +47,18 @@
import javax.faces.context.ResponseWriter;
import javax.faces.render.RenderKit;
import javax.faces.render.RenderKitFactory;
-
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
+import org.ajax4jsf.Messages;
+import org.ajax4jsf.application.AjaxViewHandler;
+import org.ajax4jsf.renderkit.AjaxContainerRenderer;
+import org.ajax4jsf.renderkit.AjaxRendererUtils;
+import org.ajax4jsf.renderkit.RendererUtils;
+import org.ajax4jsf.renderkit.RendererUtils.HTML;
+import org.richfaces.log.RichfacesLogger;
+import org.slf4j.Logger;
+
/**
* This class incapsulated
*
@@ -80,6 +75,7 @@
boolean ajaxRequest = false;
String ajaxSingleClientId = null;
Object oncomplete = null;
+ Object onbeforedomupdate = null;
boolean selfRender = false;
String submittedRegionClientId = null;
ViewIdHolder viewIdHolder = null;
@@ -589,4 +585,20 @@
public void setOncomplete(Object oncomplete) {
this.oncomplete = oncomplete;
}
+
+ /* (non-Javadoc)
+ * @see org.ajax4jsf.context.AjaxContext#getOnbeforedomupdate()
+ */
+ @Override
+ public Object getOnbeforedomupdate() {
+ return onbeforedomupdate;
+ }
+
+ /* (non-Javadoc)
+ * @see org.ajax4jsf.context.AjaxContext#setOnbeforedomupdate(java.lang.Object)
+ */
+ @Override
+ public void setOnbeforedomupdate(Object onbeforedomupdateFunction) {
+ this.onbeforedomupdate = onbeforedomupdateFunction;
+ }
}
Modified:
root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/AjaxRendererUtils.java
===================================================================
---
root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/AjaxRendererUtils.java 2009-11-05
00:45:08 UTC (rev 15826)
+++
root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/AjaxRendererUtils.java 2009-11-05
00:47:56 UTC (rev 15827)
@@ -23,30 +23,10 @@
package org.ajax4jsf.renderkit;
-import org.ajax4jsf.Messages;
-import org.ajax4jsf.component.AjaxClientBehavior;
-import org.ajax4jsf.component.AjaxComponent;
-import org.ajax4jsf.component.AjaxContainer;
-import org.ajax4jsf.component.AjaxLoadBundleComponent;
-import org.ajax4jsf.component.AjaxViewRoot;
-import org.ajax4jsf.context.AjaxContext;
-import org.ajax4jsf.javascript.JSFunction;
-import org.ajax4jsf.javascript.JSFunctionDefinition;
-import org.ajax4jsf.javascript.JSReference;
-import org.ajax4jsf.renderkit.RendererUtils.HTML;
-import org.ajax4jsf.util.ServicesUtils;
-
-import org.richfaces.log.RichfacesLogger;
-
-import org.slf4j.Logger;
-
import java.io.IOException;
-
import java.lang.reflect.Method;
-
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Locale;
@@ -59,9 +39,23 @@
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
-
import javax.servlet.http.HttpServletResponse;
+import org.ajax4jsf.Messages;
+import org.ajax4jsf.component.AjaxClientBehavior;
+import org.ajax4jsf.component.AjaxComponent;
+import org.ajax4jsf.component.AjaxContainer;
+import org.ajax4jsf.component.AjaxLoadBundleComponent;
+import org.ajax4jsf.component.AjaxViewRoot;
+import org.ajax4jsf.context.AjaxContext;
+import org.ajax4jsf.javascript.JSFunction;
+import org.ajax4jsf.javascript.JSFunctionDefinition;
+import org.ajax4jsf.javascript.JSReference;
+import org.ajax4jsf.renderkit.RendererUtils.HTML;
+import org.ajax4jsf.util.ServicesUtils;
+import org.richfaces.log.RichfacesLogger;
+import org.slf4j.Logger;
+
/**
* @author shura
*
@@ -87,12 +81,13 @@
public static final String AJAX_SINGLE_PARAMETER_NAME = "ajaxSingle";
public static final String ALL = "@all";
public static final String FORM = "@form";
+ public static final String THIS = "@this";
+ public static final String NONE = "@none";
/**
* Attribute to keep
*/
public static final String LIMITRENDER_ATTR_NAME = "limitRender";
- public static final String NONE = "@none";
/**
* Attribute for keep JavaScript function name for call before updating
@@ -118,11 +113,11 @@
* Attribute for keep clientId of status component
*/
public static final String STATUS_ATTR_NAME = "status";
- public static final String THIS = "@this";
public static final String VALUE_ATTR = "value";
- public static final Collection<String> NONE_SET = Collections.singleton(NONE);
- public static final Collection<String> ALL_SET = Collections.singleton(ALL);
+ public static final String AJAX_COMPONENT_ID_PARAMETER =
"org.richfaces.ajax.component";
+ public static final String BEHAVIOR_EVENT_PARAMETER =
"javax.faces.behavior.event";
+
private static final RendererUtils RENDERER_UTILS = RendererUtils.getInstance();
private static final Class<?> OBJECT_ARRAY_CLASS = (new Object[0]).getClass();
private static final Logger LOG = RichfacesLogger.RENDERKIT.getLogger();
Modified:
root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/RendererUtils.java
===================================================================
---
root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/RendererUtils.java 2009-11-05
00:45:08 UTC (rev 15826)
+++
root/framework/trunk/impl/src/main/java/org/ajax4jsf/renderkit/RendererUtils.java 2009-11-05
00:47:56 UTC (rev 15827)
@@ -891,6 +891,25 @@
}
/**
+ * @param ids
+ * @param keyword
+ * @since 4.0
+ *
+ * @return
+ */
+ private static boolean checkKeyword(Collection<String> ids, String keyword) {
+ if (ids.contains(keyword)) {
+ if (ids.size() != 1) {
+ //TODO log
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
* @param context
* @param component
* @param shortIds
@@ -902,17 +921,23 @@
// TODO - implement
// TODO add support for @*
- Set<String> result = new LinkedHashSet<String>();
+ Set<String> result = new LinkedHashSet<String>(shortIds.size());
- for (String id : shortIds) {
- if (AjaxRendererUtils.THIS.equals(id)) {
- result.add(component.getClientId(context));
- } else if (AjaxRendererUtils.FORM.equals(id)) {
- result.add(getNestingForm(context, component).getClientId(context));
- } else {
- UIComponent foundComponent = findComponentFor(component, id);
+ if (checkKeyword(shortIds, AjaxRendererUtils.ALL)) {
+ result.add(AjaxRendererUtils.ALL);
+ } else if (checkKeyword(shortIds, AjaxRendererUtils.NONE)) {
+ //do nothing, use empty set
+ } else {
+ for (String id : shortIds) {
+ if (AjaxRendererUtils.THIS.equals(id)) {
+ result.add(component.getClientId(context));
+ } else if (AjaxRendererUtils.FORM.equals(id)) {
+ result.add(getNestingForm(context, component).getClientId(context));
+ } else {
+ UIComponent foundComponent = findComponentFor(component, id);
- result.add((foundComponent != null) ? foundComponent.getClientId(context)
: id);
+ result.add((foundComponent != null) ?
foundComponent.getClientId(context) : id);
+ }
}
}
Modified:
root/framework/trunk/impl/src/main/java/org/richfaces/context/ComponentCallback.java
===================================================================
---
root/framework/trunk/impl/src/main/java/org/richfaces/context/ComponentCallback.java 2009-11-05
00:45:08 UTC (rev 15826)
+++
root/framework/trunk/impl/src/main/java/org/richfaces/context/ComponentCallback.java 2009-11-05
00:47:56 UTC (rev 15827)
@@ -23,10 +23,6 @@
package org.richfaces.context;
-import org.ajax4jsf.component.AjaxClientBehavior;
-import org.ajax4jsf.renderkit.AjaxRendererUtils;
-import org.ajax4jsf.renderkit.RendererUtils;
-
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
@@ -39,24 +35,31 @@
import javax.faces.component.visit.VisitResult;
import javax.faces.context.FacesContext;
+import org.ajax4jsf.component.AjaxClientBehavior;
+import org.ajax4jsf.renderkit.AjaxRendererUtils;
+import org.ajax4jsf.renderkit.RendererUtils;
+
/**
* User: akolonitsky
* Date: Oct 13, 2009
*/
abstract class ComponentCallback implements VisitCallback {
- private Collection<String> componentIds = new LinkedHashSet<String>();
- private final String behaviorEvent;
- private boolean handleAll;
- private boolean handleNone;
-
- ComponentCallback(String behaviorEvent, boolean handleNone, boolean handleAll) {
+
+ private Collection<String> componentIds = new LinkedHashSet<String>();
+
+ private final String behaviorEvent;
+ private final String defaultIdAttribute;
+
+ ComponentCallback(String behaviorEvent, String defaultIdAttribute) {
super();
+
this.behaviorEvent = behaviorEvent;
- this.handleNone = handleNone;
- this.handleAll = handleAll;
+ this.defaultIdAttribute = defaultIdAttribute;
}
- protected void addDefaultComponents(Collection<String> ids) {}
+ protected String getDefaultComponentId() {
+ return null;
+ }
private AjaxClientBehavior findBehavior(UIComponent target) {
if ((behaviorEvent == null) || !(target instanceof ClientBehaviorHolder)) {
@@ -94,36 +97,18 @@
attributeObject = getBehaviorAttributeValue(behavior);
}
+ //TODO - unit tests check for "@none" element
Collection<String> attributeIds =
AjaxRendererUtils.asSet(attributeObject);
-
- if ((attributeIds == null) || attributeIds.isEmpty()) {
- return;
+ if (attributeIds == null) {
+ attributeIds = new LinkedHashSet<String>();
}
-
- if (attributeIds.contains(AjaxRendererUtils.ALL)) {
- if (!AjaxRendererUtils.ALL_SET.equals(attributeIds)) {
-
- // TODO: log
- }
-
- handleAll = true;
- } else {
- handleAll = false;
-
- if (attributeIds.contains(AjaxRendererUtils.NONE)) {
- if (!AjaxRendererUtils.NONE_SET.equals(attributeIds)) {
-
- // TODO: log
- }
-
- handleNone = true;
- } else {
-
- // asSet() returns copy of original set and we're free to modify it
- addDefaultComponents(attributeIds);
-
componentIds.addAll(RendererUtils.getInstance().findComponentsFor(context, target,
attributeIds));
- }
+
+ if (attributeIds.isEmpty() && defaultIdAttribute != null) {
+ // asSet() returns copy of original set and we're free to modify it
+ attributeIds.add(defaultIdAttribute);
}
+
+ componentIds.addAll(RendererUtils.getInstance().findComponentsFor(context,
target, attributeIds));
}
public final VisitResult visit(VisitContext visitContext, UIComponent target) {
@@ -142,11 +127,4 @@
return componentIds;
}
- public boolean isHandleAll() {
- return handleAll;
- }
-
- public boolean isHandleNone() {
- return handleNone;
- }
}
Modified:
root/framework/trunk/impl/src/main/java/org/richfaces/context/ExecuteComponentCallback.java
===================================================================
---
root/framework/trunk/impl/src/main/java/org/richfaces/context/ExecuteComponentCallback.java 2009-11-05
00:45:08 UTC (rev 15826)
+++
root/framework/trunk/impl/src/main/java/org/richfaces/context/ExecuteComponentCallback.java 2009-11-05
00:47:56 UTC (rev 15827)
@@ -19,33 +19,24 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
-
package org.richfaces.context;
+import javax.faces.component.UIComponent;
+
import org.ajax4jsf.component.AjaxClientBehavior;
import org.ajax4jsf.renderkit.AjaxRendererUtils;
-import java.util.Collection;
-
-import javax.faces.component.UIComponent;
-
/**
* @author akolonitsky
* @since Oct 13, 2009
*/
class ExecuteComponentCallback extends ComponentCallback {
- ExecuteComponentCallback(String behaviorEvent) {
- super(behaviorEvent, false, true);
+
+ ExecuteComponentCallback(String behaviorEvent) {
+ super(behaviorEvent, AjaxRendererUtils.ALL);
}
@Override
- protected void addDefaultComponents(Collection<String> ids) {
- super.addDefaultComponents(ids);
- ids.add(AjaxRendererUtils.THIS);
- }
-
- @Override
public Object getAttributeValue(UIComponent component) {
return component.getAttributes().get("execute");
}
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 2009-11-05
00:45:08 UTC (rev 15826)
+++
root/framework/trunk/impl/src/main/java/org/richfaces/context/PartialViewContextFactoryImpl.java 2009-11-05
00:47:56 UTC (rev 15827)
@@ -23,16 +23,20 @@
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
*/
public class PartialViewContextFactoryImpl extends PartialViewContextFactory {
- public static final String RICHFACES_AJAX = "RICHFACES_AJAX";
+
private PartialViewContextFactory parentFactory;
public PartialViewContextFactoryImpl(PartialViewContextFactory parentFactory) {
@@ -42,14 +46,15 @@
@Override
public PartialViewContext getPartialViewContext(final FacesContext context) {
- PartialViewContext partialViewContext =
parentFactory.getPartialViewContext(context);
- String clientId =
context.getExternalContext().getRequestParameterMap().get(RICHFACES_AJAX);
-
- if (clientId != null) {
- partialViewContext = new PartialViewContextImpl(partialViewContext,
clientId);
+ 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 partialViewContext;
}
@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 2009-11-05
00:45:08 UTC (rev 15826)
+++
root/framework/trunk/impl/src/main/java/org/richfaces/context/PartialViewContextImpl.java 2009-11-05
00:47:56 UTC (rev 15827)
@@ -1,220 +1,570 @@
-/**
- * License Agreement.
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
*
- * Rich Faces - Natural Ajax for Java Server Faces (JSF)
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
*
- * Copyright (C) 2007 Exadel, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
+ * This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
*/
+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;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
-package org.richfaces.context;
-
-import org.ajax4jsf.component.AjaxOutput;
-
import javax.faces.component.UIComponent;
+import javax.faces.component.UIViewRoot;
+import javax.faces.component.visit.VisitCallback;
import javax.faces.component.visit.VisitContext;
import javax.faces.component.visit.VisitHint;
+import javax.faces.component.visit.VisitResult;
+import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
+import javax.faces.context.PartialResponseWriter;
import javax.faces.context.PartialViewContext;
-import javax.faces.context.PartialViewContextWrapper;
+import javax.faces.context.ResponseWriter;
import javax.faces.event.PhaseId;
-import java.util.*;
+import org.ajax4jsf.component.AjaxOutput;
+import org.ajax4jsf.context.AjaxContext;
+import org.ajax4jsf.javascript.ScriptUtils;
+import org.ajax4jsf.renderkit.RendererUtils.HTML;
+import org.richfaces.log.RichfacesLogger;
+import org.slf4j.Logger;
/**
* @author Nick Belaevski
* @since 4.0
*/
-public class PartialViewContextImpl extends PartialViewContextWrapper {
- public static final String BEHAVIOR_EVENT_PARAMETER =
"javax.faces.behavior.event";
- private String behaviorEvent = null;
- private boolean hasProcessedExecute = false;
- private boolean executeAll = true;
- private final String activatorId;
- private final PartialViewContext wrappedContext;
+public class PartialViewContextImpl extends PartialViewContext {
- public PartialViewContextImpl(PartialViewContext wrappedContext, String activatorId)
{
- super();
- this.wrappedContext = wrappedContext;
- this.activatorId = activatorId;
- }
+ 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 final static String EXTENSION_ID = "richfaces.extensions";
+
+ private static final String BEFOREDOMUPDATE_ELEMENT_NAME = "beforedomupdate";
+ private static final String COMPLETE_ELEMENT_NAME = "complete";
+ private static final String DATA_ELEMENT_NAME = "data";
+
+ private static final String ORIGINAL_WRITER =
"org.richfaces.PartialViewContextImpl.ORIGINAL_WRITER";
+
+ private FacesContext facesContext;
+ private PartialResponseWriter partialResponseWriter;
- @Override
- public PartialViewContext getWrapped() {
- return wrappedContext;
- }
+ private Set<String> executeIds = null;
+ private Set<String> renderIds = null;
+
+ private Boolean ajaxRequest = null;
+ private Boolean partialRequest = null;
+ private Boolean renderAll = null;
- private VisitContext createVisitContext(FacesContext facesContext) {
- return VisitContext.createVisitContext(facesContext,
Collections.singleton(activatorId),
- Collections.singleton(VisitHint.SKIP_UNRENDERED));
- }
+ private String activatorComponentId = null;
+ private String behaviorEvent = null;
+
+ private boolean released = false;
- // TODO: data table support
- private static Collection<String> getAjaxOutputComponentIds(FacesContext
facesContext) {
- List<String> ids = new ArrayList<String>();
- Collection<AjaxOutput> ajaxOutputComponentsSet =
-
PartialViewContextAjaxOutputTracker.getAjaxOutputComponentsSet(facesContext);
+ public PartialViewContextImpl(FacesContext facesContext, String activatorComponentId,
String behaviorEvent) {
+ super();
+
+ this.facesContext = facesContext;
+
+ //activatorComponentId should not be null
+ this.activatorComponentId = activatorComponentId;
+ this.behaviorEvent = behaviorEvent;
+ }
+
+ @Override
+ public Collection<String> getExecuteIds() {
+ assertNotReleased();
- for (AjaxOutput ajaxOutput : ajaxOutputComponentsSet) {
- if (ajaxOutput.isAjaxRendered()) {
- UIComponent ajaxOutputComponent = (UIComponent) ajaxOutput;
+ if (executeIds == null) {
+ executeIds = new LinkedHashSet<String>();
+
+ setupExecuteIds(executeIds);
+ }
- ids.add(ajaxOutputComponent.getClientId(facesContext));
- }
- }
+ return executeIds;
+ }
- return ids;
- }
+ @Override
+ public Collection<String> getRenderIds() {
+ assertNotReleased();
- private void decodeBehaviorEvent(FacesContext context) {
- Map<String, String> requestParameterMap =
context.getExternalContext().getRequestParameterMap();
+ if (renderIds == null) {
+ renderIds = new LinkedHashSet<String>();
+ }
- this.behaviorEvent = requestParameterMap.get(BEHAVIOR_EVENT_PARAMETER);
- }
+ return renderIds;
+ }
- private void processExecute(PartialViewContext partialViewContext) {
- if (hasProcessedExecute) {
- return;
- }
+ @Override
+ public boolean isAjaxRequest() {
+ assertNotReleased();
- hasProcessedExecute = true;
+ if (ajaxRequest == null) {
+ Map<String, String> requestHeaderMap =
facesContext.getExternalContext().getRequestHeaderMap();
+ ajaxRequest = PARTIAL_AJAX.equals(requestHeaderMap.get(FACES_REQUEST_HEADER));
+ }
+
+ return ajaxRequest.booleanValue();
+ }
- FacesContext facesContext = FacesContext.getCurrentInstance();
+ @Override
+ public boolean isPartialRequest() {
+ assertNotReleased();
- decodeBehaviorEvent(facesContext);
+ 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();
+ }
- ComponentCallback executeCallback = new ExecuteComponentCallback(behaviorEvent);
- boolean visitResult =
facesContext.getViewRoot().visitTree(createVisitContext(facesContext), executeCallback);
+ @Override
+ public void setPartialRequest(boolean isPartialRequest) {
+ assertNotReleased();
- if (!visitResult) {
+ partialRequest = isPartialRequest;
+ }
- // TODO:
- }
- executeAll = executeCallback.isHandleAll();
+ @Override
+ public boolean isExecuteAll() {
+ assertNotReleased();
- if (executeAll) {
- return;
- }
+ return getExecuteIds().contains(ALL);
+ }
- Collection<String> executeIds = partialViewContext.getExecuteIds();
+ @Override
+ public boolean isRenderAll() {
+ assertNotReleased();
- executeIds.clear();
+ if (renderAll == null) {
+ renderAll = getRenderIds().contains(ALL);
+ }
+
+ return renderAll;
+ }
- if (!executeCallback.isHandleNone()) {
- executeIds.addAll(executeCallback.getComponentIds());
+ @Override
+ public void setRenderAll(boolean isRenderAll) {
+ assertNotReleased();
- // TODO ids from wrapped object?
- }
- }
+ renderAll = isRenderAll;
+ }
- private void processRender(PartialViewContext partialViewContext) {
- FacesContext facesContext = FacesContext.getCurrentInstance();
+ @Override
+ public PartialResponseWriter getPartialResponseWriter() {
+ assertNotReleased();
- if (partialViewContext.isRenderAll()) {
- return;
- }
+ if (partialResponseWriter == null) {
+ partialResponseWriter = new PartialDelayedInitializationResponseWriter(facesContext);
+ }
+
+ return partialResponseWriter;
+ }
- RenderComponentCallback renderCallback = new
RenderComponentCallback(behaviorEvent);
- boolean visitResult =
facesContext.getViewRoot().visitTree(createVisitContext(facesContext), renderCallback);
+ @Override
+ public void processPartial(PhaseId phaseId) {
+ UIViewRoot viewRoot = facesContext.getViewRoot();
- if (!visitResult) {
+ if (phaseId == PhaseId.APPLY_REQUEST_VALUES ||
+ phaseId == PhaseId.PROCESS_VALIDATIONS ||
+ phaseId == PhaseId.UPDATE_MODEL_VALUES) {
- // TODO:
- }
+ Collection<String> ids = getExecuteIds();
- boolean renderAll = renderCallback.isHandleAll();
+ // Skip this processing if "none" is specified in the render list,
+ // or there were no execute phase client ids.
+ if (ids == null || ids.isEmpty()) {
+ // RELEASE_PENDING LOG ERROR OR WARNING
+ return;
+ }
+
+ try {
+ processComponents(viewRoot, phaseId, ids, facesContext);
+ } catch (Exception e) {
+ // RELEASE_PENDING LOG EXCEPTION
+ }
- partialViewContext.setRenderAll(renderAll);
+ // 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 = getPartialResponseWriter();
+ facesContext.setResponseWriter(writer);
+ }
+ } else if (phaseId == PhaseId.RENDER_RESPONSE) {
+ Collection<String> ids = getRenderIds();
+ setupRenderIds(ids);
+
+ try {
+ PartialResponseWriter writer = getPartialResponseWriter();
+ ResponseWriter orig = facesContext.getResponseWriter();
+ facesContext.getAttributes().put(ORIGINAL_WRITER, orig);
+ facesContext.setResponseWriter(writer);
- if (renderAll) {
- return;
- }
+ 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;
+ }
+
+ // Skip this processing if "none" is specified in the render
list,
+ // or there were no render phase client ids.
+ if (ids == null || ids.isEmpty()) {
+ } else {
+ processComponents(viewRoot, phaseId, ids, facesContext);
+ }
- Collection<String> renderIds = partialViewContext.getRenderIds();
+ //TODO - render extensions for renderAll?
+ renderExtensions(facesContext, viewRoot);
- renderIds.clear();
+ renderState(facesContext);
+
+ writer.endDocument();
+ } catch (IOException ex) {
+ //TODO - review?
+ this.cleanupAfterView();
+ } catch (RuntimeException ex) {
+ //TODO - review?
+ this.cleanupAfterView();
+ // Throw the exception
+ throw ex;
+ }
+ }
+ }
+
+ private void setupExecuteIds(Collection<String> ids) {
+ ExecuteComponentCallback callback = new ExecuteComponentCallback(behaviorEvent);
- if (!renderCallback.isHandleNone()) {
- renderIds.addAll(renderCallback.getComponentIds());
+ if (visitActivatorComponent(activatorComponentId, callback)) {
+ ids.addAll(callback.getComponentIds());
+
+ if (!ids.contains(ALL)) {
+ addImplicitExecuteIds(ids);
+ }
+ } else {
+ //TODO - log or exception?
+ //TODO - process default execute value
+ }
+ }
+
+ private void setupRenderIds(Collection<String> ids) {
+ if (!isRenderAll()) {
+ RenderComponentCallback callback = new RenderComponentCallback(behaviorEvent);
+
+ if (visitActivatorComponent(activatorComponentId, callback)) {
+ ids.addAll(callback.getComponentIds());
- if (!renderCallback.isLimitRender()) {
- Collection<String> ajaxOutputComponentIds =
getAjaxOutputComponentIds(facesContext);
+ if (!Boolean.TRUE.equals(renderAll) && !ids.contains(ALL)) {
+ addImplicitRenderIds(ids, callback.isLimitRender());
+ }
+ } else {
+ //TODO - the same as for "execute"
+ }
+ }
+ }
+
+ // Process the components specified in the phaseClientIds list
+ private void processComponents(UIComponent component, PhaseId phaseId,
+ Collection<String> phaseClientIds, FacesContext context) throws IOException
{
- renderIds.addAll(ajaxOutputComponentIds);
-
- // TODO ids from wrapped object?
- }
- }
+ // 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);
+ VisitContext visitContext = VisitContext.createVisitContext(facesContext,
phaseClientIds, hints);
+ PhaseAwareVisitCallback visitCallback = new PhaseAwareVisitCallback(facesContext,
phaseId);
+ component.visitTree(visitContext, visitCallback);
}
- @Override
- public void processPartial(PhaseId phaseId) {
- PartialViewContext wrapped = getWrapped();
+ private void renderAll(FacesContext context, UIComponent component) throws
IOException {
+ // If this is a "render all via ajax" request,
+ // make sure to wrap the entire page in a <render> elemnt
+ // with the special id of VIEW_ROOT_ID. This is how the client
+ // JavaScript knows how to replace the entire document with
+ // this response.
+ PartialResponseWriter writer = getPartialResponseWriter();
+ writer.startUpdate(PartialResponseWriter.RENDER_ALL_MARKER);
- if (PhaseId.APPLY_REQUEST_VALUES.equals(phaseId)) {
- processExecute(wrapped);
- } else if (PhaseId.RENDER_RESPONSE.equals(phaseId)) {
- processRender(wrapped);
+ Iterator<UIComponent> itr = component.getFacetsAndChildren();
+ while (itr.hasNext()) {
+ UIComponent kid = itr.next();
+ kid.encodeAll(context);
}
- wrapped.processPartial(phaseId);
+ writer.endUpdate();
}
- @Override
- public void setPartialRequest(boolean isPartialRequest) {
- getWrapped().setPartialRequest(isPartialRequest);
+ private void renderState(FacesContext context) throws IOException {
+
+ // Get the view state and write it to the response..
+ PartialResponseWriter writer = getPartialResponseWriter();
+ writer.startUpdate(PartialResponseWriter.VIEW_STATE_MARKER);
+ String state = context.getApplication().getStateManager().getViewState(context);
+ writer.write(state);
+ writer.endUpdate();
+
}
/*
- * (non-Javadoc)
- * @see javax.faces.context.PartialViewContextWrapper#getRenderIds()
- */
- @Override
- public Collection<String> getRenderIds() {
- return getWrapped().getRenderIds();
- }
+ * (non-Javadoc)
+ *
+ * @see javax.faces.context.PartialViewContext#release()
+ */
+ @Override
+ public void release() {
+ assertNotReleased();
- /*
- * (non-Javadoc)
- * @see javax.faces.context.PartialViewContextWrapper#getExecuteIds()
- */
- @Override
- public Collection<String> getExecuteIds() {
- return getWrapped().getExecuteIds();
+ released = true;
+
+ facesContext = null;
+ partialResponseWriter = null;
+
+ executeIds = null;
+ renderIds = null;
+
+ ajaxRequest = null;
+ partialRequest = null;
+ renderAll = null;
+
+ activatorComponentId = null;
+ behaviorEvent = null;
+ }
+
+ protected void addImplicitExecuteIds(Collection<String> ids) {
+ if (!ids.isEmpty()) {
+ UIViewRoot root = facesContext.getViewRoot();
+ if (root.getFacetCount() > 0) {
+ if (root.getFacet(UIViewRoot.METADATA_FACET_NAME) != null) {
+ ids.add(UIViewRoot.METADATA_FACET_NAME);
+ }
+ }
+ }
+ }
+
+ protected void addImplicitRenderIds(Collection<String> ids, boolean limitRender)
{
+ if (!limitRender) {
+ // TODO: data table support
+ Collection<AjaxOutput> ajaxOutputComponentsSet =
+
PartialViewContextAjaxOutputTracker.getAjaxOutputComponentsSet(facesContext);
+
+ for (AjaxOutput ajaxOutput : ajaxOutputComponentsSet) {
+ if (ajaxOutput.isAjaxRendered()) {
+ UIComponent ajaxOutputComponent = (UIComponent) ajaxOutput;
+
+ ids.add(ajaxOutputComponent.getClientId(facesContext));
+ }
+ }
+ }
+ }
+
+ protected void renderExtensions(FacesContext context, UIComponent component) throws
IOException {
+ AjaxContext ajaxContext = AjaxContext.getCurrentInstance(facesContext);
+ Map<String, String> attributes = Collections.singletonMap(HTML.ID_ATTRIBUTE,
+ context.getExternalContext().encodeNamespace(EXTENSION_ID));
+ PartialResponseWriter writer = getPartialResponseWriter();
+
+ writer.startExtension(attributes);
+
+ Object onbeforedomupdate = ajaxContext.getOnbeforedomupdate();
+ if (onbeforedomupdate != null) {
+ writer.startElement(BEFOREDOMUPDATE_ELEMENT_NAME, component);
+ writer.writeText(onbeforedomupdate, null);
+ writer.endElement(BEFOREDOMUPDATE_ELEMENT_NAME);
+ }
+
+ Object oncomplete = ajaxContext.getOncomplete();
+ if (oncomplete != null) {
+ writer.startElement(COMPLETE_ELEMENT_NAME, component);
+ writer.writeText(oncomplete, null);
+ writer.endElement(COMPLETE_ELEMENT_NAME);
+ }
+
+ Object responseData = ajaxContext.getResponseData();
+ if (responseData != null) {
+ writer.startElement(DATA_ELEMENT_NAME, component);
+ writer.writeText(ScriptUtils.toScript(responseData), null);
+ writer.endElement(DATA_ELEMENT_NAME);
+ }
+
+ writer.endExtension();
+ }
+
+ private void assertNotReleased() {
+ if (released) {
+ throw new IllegalStateException("PartialViewContext already released!");
+ }
+ }
+
+ private boolean visitActivatorComponent(String componentActivatorId, VisitCallback
visitCallback) {
+ Set<String> idsToVisit = Collections.singleton(componentActivatorId);
+ Set<VisitHint> visitHints = EnumSet.of(VisitHint.SKIP_UNRENDERED);
+ VisitContext visitContext = VisitContext.createVisitContext(facesContext, idsToVisit,
visitHints);
+
+ boolean visitResult = facesContext.getViewRoot().visitTree(visitContext,
visitCallback);
+ return visitResult;
+ }
+
+ private void cleanupAfterView() {
+ ResponseWriter orig = (ResponseWriter)
facesContext.getAttributes().get(ORIGINAL_WRITER);
+ assert (null != orig);
+ // move aside the PartialResponseWriter
+ facesContext.setResponseWriter(orig);
}
- /*
- * (non-Javadoc)
- * @see javax.faces.context.PartialViewContextWrapper#isExecuteAll()
- */
- @Override
- public boolean isExecuteAll() {
- processExecute(getWrapped());
+ private static class PhaseAwareVisitCallback implements VisitCallback {
- return executeAll;
+ private PhaseId curPhase;
+ private FacesContext ctx;
+
+ private PhaseAwareVisitCallback(FacesContext ctx, PhaseId curPhase) {
+ this.ctx = ctx;
+ this.curPhase = curPhase;
+ }
+
+
+ public VisitResult visit(VisitContext context, UIComponent comp) {
+ try {
+ 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);
+ } else if (curPhase == PhaseId.RENDER_RESPONSE) {
+
+ PartialResponseWriter writer =
ctx.getPartialViewContext().getPartialResponseWriter();
+
+ writer.startUpdate(comp.getClientId(ctx));
+ try {
+ // do the default behavior...
+ comp.encodeAll(ctx);
+ }
+ catch (Exception ce) {
+ if (LOG.isErrorEnabled()) {
+ LOG.error(ce.getMessage());
+ }
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(ce.getMessage(), ce);
+ }
+ }
+ writer.endUpdate();
+ }
+ else {
+ throw new IllegalStateException("I18N: Unexpected " +
+ "PhaseId passed to " +
+ " PhaseAwareContextCallback: " +
+ curPhase.toString());
+ }
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+
+ // 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;
+ }
}
- /*
- * (non-Javadoc)
- * @see javax.faces.context.PartialViewContextWrapper#isRenderAll()
- */
- @Override
- public boolean isRenderAll() {
- return getWrapped().isRenderAll();
- }
+
+ private static final class PartialDelayedInitializationResponseWriter extends
PartialResponseWriter {
+
+ private static final String DEFAULT_CHARACTER_ENCODING = "ISO-8859-1";
+
+ private FacesContext facesContext;
+
+ private ResponseWriter responseWriter;
+
+ /**
+ * @param writer
+ */
+ public PartialDelayedInitializationResponseWriter(FacesContext facesContext) {
+ super(null);
+ this.facesContext = facesContext;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.faces.context.PartialResponseWriter#getWrapped()
+ */
+ @Override
+ public ResponseWriter getWrapped() {
+ if (responseWriter == null) {
+ responseWriter = createResponseWriter();
+ }
+
+ return responseWriter;
+ }
+
+ private ResponseWriter createResponseWriter() {
+ ResponseWriter newResponseWriter = null;
+ ExternalContext externalContext = facesContext.getExternalContext();
+ String characterEncoding = externalContext.getRequestCharacterEncoding();
+
+ if (characterEncoding == null) {
+ characterEncoding = DEFAULT_CHARACTER_ENCODING;
+ }
+
+ externalContext.setResponseCharacterEncoding(characterEncoding);
+
+ Writer outputWriter = null;
+ try {
+ outputWriter = facesContext.getExternalContext().getResponseOutputWriter();
+ } catch (IOException e) {
+ LOG.error("Error creating partial context response writer: " +
e.getMessage(), e);
+ }
+
+ newResponseWriter = facesContext.getRenderKit().
+ createResponseWriter(outputWriter, "text/xml", characterEncoding);
+
+ return newResponseWriter;
+ }
+ }
}
Modified:
root/framework/trunk/impl/src/main/java/org/richfaces/context/RenderComponentCallback.java
===================================================================
---
root/framework/trunk/impl/src/main/java/org/richfaces/context/RenderComponentCallback.java 2009-11-05
00:45:08 UTC (rev 15826)
+++
root/framework/trunk/impl/src/main/java/org/richfaces/context/RenderComponentCallback.java 2009-11-05
00:47:56 UTC (rev 15827)
@@ -34,10 +34,11 @@
* @since Oct 13, 2009
*/
class RenderComponentCallback extends ComponentCallback {
- private boolean limitRender = false;
+
+ private boolean limitRender = false;
RenderComponentCallback(String behaviorEvent) {
- super(behaviorEvent, false, false);
+ super(behaviorEvent, null);
}
public boolean isLimitRender() {
Modified:
root/framework/trunk/impl/src/main/java/org/richfaces/resource/AnimatedTestResource.java
===================================================================
---
root/framework/trunk/impl/src/main/java/org/richfaces/resource/AnimatedTestResource.java 2009-11-05
00:45:08 UTC (rev 15826)
+++
root/framework/trunk/impl/src/main/java/org/richfaces/resource/AnimatedTestResource.java 2009-11-05
00:47:56 UTC (rev 15827)
@@ -23,17 +23,17 @@
package org.richfaces.resource;
-import org.w3c.dom.Node;
-
-import java.awt.*;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.GradientPaint;
+import java.awt.Graphics2D;
+import java.awt.GraphicsEnvironment;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
-
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
-
import java.util.Iterator;
import javax.imageio.IIOImage;
@@ -45,6 +45,8 @@
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.stream.ImageOutputStream;
+import org.w3c.dom.Node;
+
public class AnimatedTestResource extends TestResource2 {
private static final int DELAY_TIME = 50;
private static final int FRAMES_COUNT = 10;
Modified: root/framework/trunk/impl/src/main/resources/META-INF/resources/richfaces.js
===================================================================
---
root/framework/trunk/impl/src/main/resources/META-INF/resources/richfaces.js 2009-11-05
00:45:08 UTC (rev 15826)
+++
root/framework/trunk/impl/src/main/resources/META-INF/resources/richfaces.js 2009-11-05
00:47:56 UTC (rev 15827)
@@ -396,8 +396,8 @@
parameters.execute = "@component";
parameters.render = "@component";
- if (!parameters.RICHFACES_AJAX) {
- parameters.RICHFACES_AJAX = sourceId;
+ if (!parameters["org.richfaces.ajax.component"]) {
+ parameters["org.richfaces.ajax.component"] = sourceId;
}
var eventHandlers;
Modified: root/framework/trunk/impl/src/test/resources/javascript/4_0_0.html
===================================================================
--- root/framework/trunk/impl/src/test/resources/javascript/4_0_0.html 2009-11-05 00:45:08
UTC (rev 15826)
+++ root/framework/trunk/impl/src/test/resources/javascript/4_0_0.html 2009-11-05 00:47:56
UTC (rev 15827)
@@ -150,7 +150,7 @@
'execute': '@component',
'render': '@component',
'param': 'value',
- 'RICHFACES_AJAX': 'source',
+ 'org.richfaces.ajax.component': 'source',
'source': 'source'
});
}
Modified:
root/ui/trunk/components/core/src/main/java/org/ajax4jsf/renderkit/AjaxBehaviorRenderer.java
===================================================================
---
root/ui/trunk/components/core/src/main/java/org/ajax4jsf/renderkit/AjaxBehaviorRenderer.java 2009-11-05
00:45:08 UTC (rev 15826)
+++
root/ui/trunk/components/core/src/main/java/org/ajax4jsf/renderkit/AjaxBehaviorRenderer.java 2009-11-05
00:47:56 UTC (rev 15827)
@@ -18,9 +18,6 @@
import org.ajax4jsf.component.behavior.AjaxBehavior;
import org.ajax4jsf.javascript.JSFunction;
-import org.richfaces.context.PartialViewContextFactoryImpl;
-import org.richfaces.context.PartialViewContextImpl;
-
/**
* @author Anton Belevich
*
@@ -103,8 +100,8 @@
String eventName = bContext.getEventName();
AjaxEventOptions options = AjaxRendererUtils.buildEventOptions(context, parent,
behavior);
- options.setParameter(PartialViewContextImpl.BEHAVIOR_EVENT_PARAMETER,
eventName);
- options.setParameter(PartialViewContextFactoryImpl.RICHFACES_AJAX,
parent.getClientId());
+ options.setParameter(AjaxRendererUtils.BEHAVIOR_EVENT_PARAMETER, eventName);
+ options.setParameter(AjaxRendererUtils.AJAX_COMPONENT_ID_PARAMETER,
parent.getClientId());
return options;
}