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 }