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_ONCLICK; 021 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_HEIGHT; 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 public int getFixedHeight(FacesContext facesContext, UIComponent component) { 091 return getFixedSpace(facesContext, component, false); 092 } 093 public int getFixedSpace(FacesContext facesContext, UIComponent component, boolean width) { 094 095 int fixedSpace = 0; 096 097 if (component instanceof UICell) { 098 List children = LayoutUtil.addChildren(new ArrayList(), component); 099 for (Object aChildren : children) { 100 UIComponent child = (UIComponent) aChildren; 101 102 LayoutInformationProvider renderer = ComponentUtil.getRenderer(facesContext, child); 103 if (renderer != null) { 104 if (width) { 105 fixedSpace = Math.max(fixedSpace, renderer.getFixedWidth(facesContext, child)); 106 } else { 107 fixedSpace = Math.max(fixedSpace, renderer.getFixedHeight(facesContext, child)); 108 } 109 } 110 } 111 } else { 112 if (width) { 113 fixedSpace = getFixedSpace(facesContext, component, ATTR_WIDTH, "fixedWidth"); 114 } else { 115 fixedSpace = getFixedSpace(facesContext, component, ATTR_HEIGHT, "fixedHeight"); 116 } 117 } 118 return fixedSpace; 119 } 120 121 private int getFixedSpace(FacesContext facesContext, UIComponent component, 122 String attr, String attrFixed) { 123 int intSpace = -1; 124 String space = null; 125 if (component != null) { 126 space = ComponentUtil.getStringAttribute(component, attr); 127 } 128 if (space != null) { 129 try { 130 intSpace = Integer.parseInt(space.replaceAll("\\D", "")); 131 } catch (NumberFormatException e) { 132 LOG.error("Catched: " + e.getMessage(), e); 133 } 134 } 135 if (intSpace == -1) { 136 return getConfiguredValue(facesContext, component, attrFixed); 137 } else { 138 return intSpace; 139 } 140 } 141 142 protected void checkForCommandFacet(UIComponent component, FacesContext facesContext, TobagoResponseWriter writer) 143 throws IOException { 144 checkForCommandFacet(component, Arrays.asList(component.getClientId(facesContext)) , facesContext, writer); 145 } 146 147 protected void checkForCommandFacet(UIComponent component, List<String> clientIds, FacesContext facesContext, 148 TobagoResponseWriter writer) throws IOException { 149 Map<String, UIComponent> facets = component.getFacets(); 150 for (Map.Entry<String, UIComponent> entry: facets.entrySet()) { 151 if (entry.getValue() instanceof UICommand) { 152 addCommandFacet(clientIds, entry, facesContext, writer); 153 } 154 } 155 } 156 157 // TODO create HtmlRendererBase 158 private void addCommandFacet(List<String> clientIds, Map.Entry<String, UIComponent> facetEntry, 159 FacesContext facesContext, TobagoResponseWriter writer) throws 160 IOException { 161 for (String clientId: clientIds) { 162 writeScriptForClientId(clientId, facetEntry, facesContext, writer); 163 } 164 } 165 166 private void writeScriptForClientId(String clientId, Map.Entry<String, UIComponent> facetEntry, 167 FacesContext facesContext, TobagoResponseWriter writer) throws IOException { 168 if (facetEntry.getValue() instanceof UICommand 169 && ((UICommand) facetEntry.getValue()).getRenderedPartially().length > 0) { 170 String script = 171 "var element = Tobago.element(\"" + clientId + "\");\n" 172 + "if (element) {\n" 173 + " Tobago.addEventListener(element, \"" + facetEntry.getKey() 174 + "\", function(){Tobago.reloadComponent('" 175 + HtmlRendererUtil.getComponentId(facesContext, facetEntry.getValue(), 176 ((UICommand) facetEntry.getValue()).getRenderedPartially()[0]) + "','" 177 + facetEntry.getValue().getClientId(facesContext) + "', {})});\n" 178 + "}"; 179 writer.writeJavascript(script); 180 } else { 181 UIComponent facetComponent = facetEntry.getValue(); 182 String facetAction = (String) facetComponent.getAttributes().get(ATTR_ONCLICK); 183 if (facetAction == null) { 184 facetAction = "Tobago.submitAction('" + facetComponent.getClientId(facesContext) + "')"; 185 } 186 String script = 187 "var element = Tobago.element(\"" + clientId + "\");\n" 188 + "if (element) {\n" 189 + " Tobago.addEventListener(element, \"" + facetEntry.getKey() + "\", function(){" 190 + facetAction + "});\n}"; 191 writer.writeJavascript(script); 192 } 193 } 194 }