001: package com.icesoft.faces.webapp.http.core;
002:
003: import com.icesoft.faces.application.D2DViewHandler;
004: import com.icesoft.faces.el.PartialSubmitValueBinding;
005: import com.icesoft.faces.webapp.http.common.Request;
006: import com.icesoft.faces.webapp.http.common.Server;
007:
008: import javax.faces.FactoryFinder;
009: import javax.faces.component.UIComponent;
010: import javax.faces.component.UIForm;
011: import javax.faces.component.UIInput;
012: import javax.faces.context.FacesContext;
013: import javax.faces.el.ValueBinding;
014: import javax.faces.lifecycle.Lifecycle;
015: import javax.faces.lifecycle.LifecycleFactory;
016: import java.util.Arrays;
017: import java.util.Collection;
018: import java.util.HashMap;
019: import java.util.Iterator;
020: import java.util.List;
021: import java.util.Map;
022:
023: public class ReceiveSendUpdates implements Server {
024: private static final String REQUIRED = "required";
025: private static final LifecycleFactory LifecycleFactory = (LifecycleFactory) FactoryFinder
026: .getFactory(FactoryFinder.LIFECYCLE_FACTORY);
027: private Lifecycle lifecycle = LifecycleFactory
028: .getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
029: private Map commandQueues;
030: private Collection synchronouslyUpdatedViews;
031:
032: public ReceiveSendUpdates(Map commandQueues,
033: Collection synchronouslyUpdatedViews) {
034: this .commandQueues = commandQueues;
035: this .synchronouslyUpdatedViews = synchronouslyUpdatedViews;
036: }
037:
038: public void service(final Request request) throws Exception {
039: List viewIdentifiers = Arrays.asList(request
040: .getParameterAsStrings("ice.view.all"));
041: synchronouslyUpdatedViews.addAll(viewIdentifiers);
042:
043: FacesContext context = FacesContext.getCurrentInstance();
044: if (request.getParameterAsBoolean("ice.submit.partial", false)) {
045: String componentID = request
046: .getParameter("ice.event.captured");
047: UIComponent component = D2DViewHandler.findComponent(
048: componentID, context.getViewRoot());
049: renderCyclePartial(context, component, componentID);
050: } else {
051: renderCycle(context);
052: }
053:
054: request.respondWith(new SendUpdates.Handler(commandQueues,
055: request));
056: }
057:
058: public void shutdown() {
059: }
060:
061: private void renderCycle(FacesContext context) {
062: synchronized (context) {
063: com.icesoft.util.SeamUtilities
064: .removeSeamDebugPhaseListener(lifecycle);
065: lifecycle.execute(context);
066: lifecycle.render(context);
067: }
068: }
069:
070: private void renderCyclePartial(FacesContext context,
071: UIComponent component, String clientId) {
072: synchronized (context) {
073: Map alteredRequiredComponents = setRequiredFalseInFormContaining(
074: component, clientId);
075: com.icesoft.util.SeamUtilities
076: .removeSeamDebugPhaseListener(lifecycle);
077: lifecycle.execute(context);
078: lifecycle.render(context);
079: setRequiredTrue(alteredRequiredComponents);
080: }
081: }
082:
083: private void setRequiredTrue(Map requiredComponents) {
084: Iterator i = requiredComponents.keySet().iterator();
085: UIInput next = null;
086: while (i.hasNext()) {
087: next = (UIInput) i.next();
088: ValueBinding valueBinding = (ValueBinding) requiredComponents
089: .get(next);
090: if (null != valueBinding) {
091: next.setValueBinding(REQUIRED, valueBinding);
092: } else {
093: next.setRequired(true);
094: }
095: }
096: }
097:
098: private Map setRequiredFalseInFormContaining(UIComponent component,
099: String clientId) {
100: Map alteredComponents = new HashMap();
101: UIComponent form = getContainingForm(component);
102: setRequiredFalseOnAllChildrenExceptOne(form, component,
103: clientId, alteredComponents);
104: return alteredComponents;
105: }
106:
107: private void setRequiredFalseOnAllChildrenExceptOne(
108: UIComponent parent, UIComponent componentToAvoid,
109: String clientIdToAvoid, Map alteredComponents) {
110:
111: //turn off required simply with false for all but iterative case
112: ValueBinding FALSE_BINDING = FacesContext.getCurrentInstance()
113: .getApplication().createValueBinding("#{false}");
114:
115: int length = parent.getChildCount();
116: UIComponent next = null;
117: for (int i = 0; i < length; i++) {
118: next = (UIComponent) parent.getChildren().get(i);
119: if (next instanceof UIInput) {
120: UIInput input = (UIInput) next;
121: ValueBinding valueBinding = input
122: .getValueBinding(REQUIRED);
123: if (null != valueBinding) {
124: ValueBinding replacementBinding = null;
125: if (input == componentToAvoid) {
126: //The component that caused the partialSubmit may
127: //be used iteratively (in a dataTable). We use
128: //PartialSubmitValueBinding to detect which single
129: //client instance of the component to avoid
130: replacementBinding = new PartialSubmitValueBinding(
131: valueBinding, input, clientIdToAvoid);
132: } else {
133: replacementBinding = FALSE_BINDING;
134: }
135: input.setValueBinding(REQUIRED, replacementBinding);
136: alteredComponents.put(input, valueBinding);
137: } else {
138: if (input.isRequired() && input != componentToAvoid) {
139: input.setRequired(false);
140: alteredComponents.put(input, null);
141: }
142: }
143: }
144: setRequiredFalseOnAllChildrenExceptOne(next,
145: componentToAvoid, clientIdToAvoid,
146: alteredComponents);
147: }
148: }
149:
150: private UIComponent getContainingForm(UIComponent component) {
151: if (null == component) {
152: return FacesContext.getCurrentInstance().getViewRoot();
153: }
154: UIComponent parent = component.getParent();
155: while (parent != null) {
156: if (parent instanceof UIForm) {
157: break;
158: }
159: parent = parent.getParent();
160: }
161: return (UIForm) parent;
162: }
163:
164: }
|