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