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