001 package org.apache.myfaces.tobago.ajax.api; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one or more 005 * contributor license agreements. See the NOTICE file distributed with 006 * this work for additional information regarding copyright ownership. 007 * The ASF licenses this file to You under the Apache License, Version 2.0 008 * (the "License"); you may not use this file except in compliance with 009 * the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019 020 import org.apache.commons.logging.Log; 021 import org.apache.commons.logging.LogFactory; 022 import org.apache.myfaces.tobago.component.ComponentUtil; 023 import org.apache.myfaces.tobago.component.UIViewRoot; 024 025 import javax.faces.component.UIComponent; 026 import javax.faces.context.FacesContext; 027 import javax.faces.event.PhaseId; 028 import javax.faces.render.Renderer; 029 import java.io.IOException; 030 import java.util.Iterator; 031 import java.util.Map; 032 import java.util.StringTokenizer; 033 import java.util.HashMap; 034 035 /* 036 * Created by IntelliJ IDEA. 037 * User: weber 038 * Date: 12.10.2005 039 * Time: 13:11:05 040 */ 041 public class AjaxUtils { 042 043 private static final Log LOG = LogFactory.getLog(AjaxUtils.class); 044 045 public static final String AJAX_COMPONENTS = AjaxUtils.class.getName() + ".AJAX_COMPONENTS"; 046 047 public static void checkParamValidity(FacesContext facesContext, UIComponent uiComponent, Class compClass) { 048 if (facesContext == null) { 049 throw new NullPointerException("facesContext may not be null"); 050 } 051 if (uiComponent == null) { 052 throw new NullPointerException("uiComponent may not be null"); 053 } 054 //if (compClass != null && !(compClass.isAssignableFrom(uiComponent.getClass()))) 055 // why isAssignableFrom with additional getClass method call if isInstance does the same? 056 if (compClass != null && !(compClass.isInstance(uiComponent))) { 057 throw new IllegalArgumentException("uiComponent : " 058 + uiComponent.getClass().getName() + " is not instance of " 059 + compClass.getName() + " as it should be"); 060 } 061 } 062 063 064 065 066 public static void encodeAjaxComponent(FacesContext facesContext, UIComponent component) throws IOException { 067 if (facesContext == null) { 068 throw new NullPointerException("facesContext"); 069 } 070 if (!component.isRendered()) { 071 return; 072 } 073 Renderer renderer = ComponentUtil.getRenderer(facesContext, component); 074 if (renderer != null && renderer instanceof AjaxRenderer) { 075 ((AjaxRenderer) renderer).encodeAjax(facesContext, component); 076 } 077 } 078 079 080 public static void processAjax(FacesContext facesContext, UIComponent component) 081 throws IOException { 082 if (component instanceof AjaxComponent) { 083 ((AjaxComponent) component).processAjax(facesContext); 084 } else { 085 processAjaxOnChildren(facesContext, component); 086 } 087 } 088 089 public static void processActiveAjaxComponent(FacesContext facesContext, 090 UIComponent component) 091 throws IOException { 092 093 if (component instanceof AjaxComponent) { 094 final UIViewRoot viewRoot = (UIViewRoot) facesContext.getViewRoot(); 095 096 // TODO: handle phaseListeners ?? 097 098 if (!facesContext.getRenderResponse()) { 099 component.processValidators(facesContext); 100 viewRoot.broadcastEventsForPhase(facesContext, PhaseId.PROCESS_VALIDATIONS); 101 } else if (LOG.isDebugEnabled()) { 102 LOG.debug("Skipping validate"); 103 } 104 105 if (!facesContext.getRenderResponse()) { 106 component.processUpdates(facesContext); 107 viewRoot.broadcastEventsForPhase(facesContext, PhaseId.UPDATE_MODEL_VALUES); 108 } else if (LOG.isDebugEnabled()) { 109 LOG.debug("Skipping updates"); 110 } 111 112 if (!facesContext.getRenderResponse()) { 113 viewRoot.processApplication(facesContext); 114 } else if (LOG.isDebugEnabled()) { 115 LOG.debug("Skipping application"); 116 } 117 118 ((AjaxComponent) component).encodeAjax(facesContext); 119 } else { 120 LOG.error("Can't process non AjaxComponent : \"" 121 + component.getClientId(facesContext) + "\" = " 122 + component.getClass().getName()); 123 } 124 } 125 126 public static void processAjaxOnChildren(FacesContext facesContext, 127 UIComponent component) throws IOException { 128 129 final Iterator<UIComponent> facetsAndChildren = component.getFacetsAndChildren(); 130 while (facetsAndChildren.hasNext() && !facesContext.getResponseComplete()) { 131 AjaxUtils.processAjax(facesContext, facetsAndChildren.next()); 132 } 133 } 134 135 public static Map<String, UIComponent> parseAndStoreComponents(FacesContext facesContext) { 136 Map parameterMap = facesContext.getExternalContext().getRequestParameterMap(); 137 String ajaxComponentIds = (String) parameterMap.get(AjaxPhaseListener.AJAX_COMPONENT_ID); 138 if (ajaxComponentIds != null) { 139 LOG.info("ajaxComponentIds = \"" + ajaxComponentIds + "\""); 140 StringTokenizer tokenizer = new StringTokenizer(ajaxComponentIds, ","); 141 Map<String, UIComponent> ajaxComponents = new HashMap<String, UIComponent>(tokenizer.countTokens()); 142 //noinspection unchecked 143 facesContext.getExternalContext().getRequestMap().put(AJAX_COMPONENTS, ajaxComponents); 144 javax.faces.component.UIViewRoot viewRoot = facesContext.getViewRoot(); 145 while (tokenizer.hasMoreTokens()) { 146 String ajaxId = tokenizer.nextToken(); 147 UIComponent ajaxComponent = viewRoot.findComponent(ajaxId); 148 if (ajaxComponent != null) { 149 LOG.info("ajaxComponent for \"" + ajaxId + "\" = \"" + ajaxComponent + "\""); 150 ajaxComponents.put(ajaxId, ajaxComponent); 151 } 152 } 153 return ajaxComponents; 154 } 155 return null; 156 } 157 158 public static Map<String, UIComponent> getAjaxComponents(FacesContext facesContext) { 159 //noinspection unchecked 160 return (Map<String, UIComponent>) 161 facesContext.getExternalContext().getRequestMap().get(AJAX_COMPONENTS); 162 } 163 164 public static void ensureDecoded(FacesContext facesContext, String clientId) { 165 ensureDecoded(facesContext, facesContext.getViewRoot().findComponent(clientId)); 166 } 167 168 public static void ensureDecoded(FacesContext facesContext, UIComponent component) { 169 Map<String, UIComponent> ajaxComponents = getAjaxComponents(facesContext); 170 if (ajaxComponents != null) { 171 for (UIComponent uiComponent : ajaxComponents.values()) { 172 UIComponent currentComponent = component; 173 while (currentComponent != null) { 174 if (component == uiComponent) { 175 return; 176 } 177 currentComponent = currentComponent.getParent(); 178 } 179 } 180 component.processDecodes(facesContext); 181 } 182 } 183 }