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