001 package org.apache.myfaces.tobago.renderkit; 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 static org.apache.myfaces.tobago.TobagoConstants.ATTR_HEIGHT; 021 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_WIDTH; 022 import static org.apache.myfaces.tobago.TobagoConstants.FACET_MENUBAR; 023 import org.apache.myfaces.tobago.component.ComponentUtil; 024 import org.apache.myfaces.tobago.component.UICell; 025 import org.apache.myfaces.tobago.component.UICommand; 026 import org.apache.myfaces.tobago.renderkit.html.HtmlRendererUtil; 027 import org.apache.myfaces.tobago.util.LayoutUtil; 028 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter; 029 030 import javax.faces.component.UIComponent; 031 import javax.faces.context.FacesContext; 032 import java.awt.Dimension; 033 import java.io.IOException; 034 import java.util.ArrayList; 035 import java.util.Arrays; 036 import java.util.List; 037 import java.util.Map; 038 039 public abstract class LayoutableRendererBase 040 extends RendererBase implements LayoutInformationProvider { 041 042 public int getHeaderHeight( 043 FacesContext facesContext, UIComponent component) { 044 int height = getConfiguredValue(facesContext, component, "headerHeight"); 045 final UIComponent menubar = component.getFacet(FACET_MENUBAR); 046 if (menubar != null) { 047 height += getConfiguredValue(facesContext, menubar, "headerHeight"); 048 } 049 return height; 050 } 051 052 public int getPaddingWidth(FacesContext facesContext, UIComponent component) { 053 return getConfiguredValue(facesContext, component, "paddingWidth"); 054 } 055 056 public int getPaddingHeight( 057 FacesContext facesContext, UIComponent component) { 058 return getConfiguredValue(facesContext, component, "paddingHeight"); 059 } 060 061 public int getComponentExtraWidth( 062 FacesContext facesContext, 063 UIComponent component) { 064 return getConfiguredValue(facesContext, component, "componentExtraWidth"); 065 } 066 067 public int getComponentExtraHeight( 068 FacesContext facesContext, 069 UIComponent component) { 070 return getConfiguredValue(facesContext, component, "componentExtraHeight"); 071 } 072 073 public Dimension getMinimumSize( 074 FacesContext facesContext, UIComponent component) { 075 int width = getConfiguredValue(facesContext, component, "minimumWidth"); 076 if (width == -1) { 077 width = getConfiguredValue(facesContext, component, "fixedWidth"); 078 } 079 int height = getConfiguredValue(facesContext, component, "minimumHeight"); 080 if (height == -1) { 081 height = getConfiguredValue(facesContext, component, "fixedHeight"); 082 } 083 return new Dimension(width, height); 084 } 085 086 public int getFixedWidth(FacesContext facesContext, UIComponent component) { 087 return getFixedSpace(facesContext, component, true); 088 } 089 public int getFixedHeight(FacesContext facesContext, UIComponent component) { 090 return getFixedSpace(facesContext, component, false); 091 } 092 public int getFixedSpace(FacesContext facesContext, UIComponent component, boolean width) { 093 094 int fixedSpace = 0; 095 096 if (component instanceof UICell) { 097 List children = LayoutUtil.addChildren(new ArrayList(), component); 098 for (Object aChildren : children) { 099 UIComponent child = (UIComponent) aChildren; 100 101 LayoutInformationProvider renderer = ComponentUtil.getRenderer(facesContext, child); 102 if (renderer != null) { 103 if (width) { 104 fixedSpace = Math.max(fixedSpace, renderer.getFixedWidth(facesContext, child)); 105 } else { 106 fixedSpace = Math.max(fixedSpace, renderer.getFixedHeight(facesContext, child)); 107 } 108 } 109 } 110 } else { 111 if (width) { 112 fixedSpace = getFixedSpace(facesContext, component, ATTR_WIDTH, "fixedWidth"); 113 } else { 114 fixedSpace = getFixedSpace(facesContext, component, ATTR_HEIGHT, "fixedHeight"); 115 } 116 } 117 return fixedSpace; 118 } 119 120 private int getFixedSpace(FacesContext facesContext, UIComponent component, 121 String attr, String attrFixed) { 122 int intSpace = -1; 123 String space = null; 124 if (component != null) { 125 space = ComponentUtil.getStringAttribute(component, attr); 126 } 127 if (space != null) { 128 try { 129 intSpace = Integer.parseInt(space.replaceAll("\\D", "")); 130 } catch (NumberFormatException e) { 131 LOG.error("Catched: " + e.getMessage(), e); 132 } 133 } 134 if (intSpace == -1) { 135 return getConfiguredValue(facesContext, component, attrFixed); 136 } else { 137 return intSpace; 138 } 139 } 140 141 protected void checkForCommandFacet(UIComponent component, FacesContext facesContext, TobagoResponseWriter writer) 142 throws IOException { 143 checkForCommandFacet(component, Arrays.asList(component.getClientId(facesContext)) , facesContext, writer); 144 } 145 146 protected void checkForCommandFacet(UIComponent component, List<String> clientIds, FacesContext facesContext, 147 TobagoResponseWriter writer) throws IOException { 148 Map<String, UIComponent> facets = component.getFacets(); 149 for (Map.Entry<String, UIComponent> entry: facets.entrySet()) { 150 if (entry.getValue() instanceof UICommand) { 151 addCommandFacet(clientIds, entry, facesContext, writer); 152 } 153 } 154 } 155 156 // TODO create HtmlRendererBase 157 private void addCommandFacet(List<String> clientIds, Map.Entry<String, UIComponent> facetEntry, 158 FacesContext facesContext, TobagoResponseWriter writer) throws 159 IOException { 160 for (String clientId: clientIds) { 161 writeScriptForClientId(clientId, facetEntry, facesContext, writer); 162 } 163 } 164 165 private void writeScriptForClientId(String clientId, Map.Entry<String, UIComponent> facetEntry, 166 FacesContext facesContext, TobagoResponseWriter writer) throws IOException { 167 if (facetEntry.getValue() instanceof UICommand 168 && ((UICommand) facetEntry.getValue()).getRenderedPartially().length > 0) { 169 String script = 170 "var element = Tobago.element(\"" + clientId + "\");\n" 171 + "if (element) {\n" 172 + " Tobago.addEventListener(element, \"" + facetEntry.getKey() 173 + "\", function(){Tobago.reloadComponent('" 174 + HtmlRendererUtil.getComponentId(facesContext, facetEntry.getValue(), 175 ((UICommand) facetEntry.getValue()).getRenderedPartially()[0]) + "','" 176 + facetEntry.getValue().getClientId(facesContext) + "', {})});\n" 177 + "}"; 178 writer.writeJavascript(script); 179 } else { 180 String script = 181 "var element = Tobago.element(\"" + clientId + "\");\n" 182 + "if (element) {\n" 183 + " Tobago.addEventListener(element, \"" + facetEntry.getKey() + "\", function(){Tobago.submitAction('" 184 + facetEntry.getValue().getClientId(facesContext) + "')});\n" 185 + "}"; 186 writer.writeJavascript(script); 187 } 188 } 189 }