001    package org.apache.myfaces.tobago.util;
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    
021    import org.apache.myfaces.tobago.component.Attributes;
022    import org.apache.myfaces.tobago.component.Facets;
023    import org.apache.myfaces.tobago.internal.layout.LayoutContext;
024    import org.apache.myfaces.tobago.layout.LayoutContainer;
025    import org.apache.myfaces.tobago.layout.Measure;
026    import org.apache.myfaces.tobago.renderkit.RendererBase;
027    
028    import javax.faces.FacesException;
029    import javax.faces.component.UIComponent;
030    import javax.faces.context.FacesContext;
031    import javax.faces.event.PhaseId;
032    import java.io.IOException;
033    import java.util.Iterator;
034    
035    public class EncodeAjaxCallback implements TobagoCallback {
036    
037      public void invokeContextCallback(FacesContext facesContext, UIComponent component) {
038        try {
039           UIComponent reload = component.getFacet(Facets.RELOAD);
040           if (reload != null && reload.isRendered()) {
041             Boolean immediate = (Boolean) reload.getAttributes().get(Attributes.IMMEDIATE);
042             if (immediate != null && !immediate) {
043               Boolean update = (Boolean) reload.getAttributes().get(Attributes.UPDATE);
044               if (update != null && !update) {
045                 return;
046               }
047             }
048          }
049          if (component instanceof LayoutContainer) {
050            LayoutContainer layoutContainer = (LayoutContainer) component;
051            Measure width = layoutContainer.getCurrentWidth();
052            Measure height = layoutContainer.getCurrentHeight();
053            Measure oldWidth = layoutContainer.getWidth();
054            Measure oldHeight = layoutContainer.getHeight();
055            layoutContainer.setWidth(width);
056            layoutContainer.setHeight(height);
057            new LayoutContext(layoutContainer).layout();
058            layoutContainer.setWidth(oldWidth);
059            layoutContainer.setHeight(oldHeight);
060          }
061          prepareRendererAll(facesContext, component);
062          encodeAll(facesContext, component);
063        } catch (IOException e) {
064          throw new FacesException(e);
065        }
066      }
067      
068      public PhaseId getPhaseId() {
069          return PhaseId.RENDER_RESPONSE;
070      }
071      
072    
073      // TODO replace with component.encodeAll after removing jsf 1.1 support
074      public static void encodeAll(FacesContext facesContext, UIComponent component) throws IOException {
075         if (component.isRendered()) {
076          component.encodeBegin(facesContext);
077          if (component.getRendersChildren()) {
078            component.encodeChildren(facesContext);
079          } else {
080            for (Object o : component.getChildren()) {
081              UIComponent kid = (UIComponent) o;
082              encodeAll(facesContext, kid);
083            }
084          }
085          component.encodeEnd(facesContext);
086        }
087      }
088    
089      // TODO merge with RenderUtils.prepareRendererAll
090      public static void prepareRendererAll(FacesContext facesContext, UIComponent component) throws IOException {
091        RendererBase renderer = ComponentUtils.getRenderer(facesContext,  component);
092        boolean prepareRendersChildren = false;
093        if (renderer != null) {
094          renderer.prepareRender(facesContext, component);
095          prepareRendersChildren = renderer.getPrepareRendersChildren();
096        }
097        if (prepareRendersChildren) {
098          renderer.prepareRendersChildren(facesContext, component);
099        } else {
100          Iterator it = component.getFacetsAndChildren();
101          while (it.hasNext()) {
102            UIComponent child = (UIComponent) it.next();
103            prepareRendererAll(facesContext, child);
104          }
105        }
106      }
107    }