001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019 020 package org.apache.myfaces.tobago.component; 021 022 import org.apache.myfaces.tobago.TobagoConstants; 023 import org.apache.myfaces.tobago.ajax.api.AjaxComponent; 024 025 import javax.faces.component.NamingContainer; 026 import javax.faces.component.UIComponent; 027 import javax.faces.context.FacesContext; 028 import javax.faces.el.ValueBinding; 029 import java.io.IOException; 030 import java.util.Iterator; 031 032 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_HEIGHT; 033 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_LEFT; 034 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_TOP; 035 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_WIDTH; 036 037 public class UIPopup extends UIPanelBase implements NamingContainer, AjaxComponent { 038 039 public static final String COMPONENT_TYPE = "org.apache.myfaces.tobago.Popup"; 040 041 private String width; 042 private String height; 043 private String left; 044 private String top; 045 private boolean activated; 046 private Boolean modal; 047 048 public void setActivated(boolean activated) { 049 this.activated = activated; 050 addToPage(); 051 } 052 053 public void processDecodes(FacesContext facesContext) { 054 if (isSubmitted()) { 055 for (Iterator it = getFacetsAndChildren(); it.hasNext();) { 056 UIComponent childOrFacet = (UIComponent) it.next(); 057 childOrFacet.processDecodes(facesContext); 058 } 059 try { 060 decode(facesContext); 061 } catch (RuntimeException e) { 062 facesContext.renderResponse(); 063 throw e; 064 } 065 if (facesContext.getRenderResponse()) { 066 setActivated(true); 067 } 068 addToPage(); 069 } 070 } 071 072 public boolean isRendered() { 073 ValueBinding valueBinding = getValueBinding("rendered"); 074 if (valueBinding != null) { 075 return (Boolean) valueBinding.getValue(getFacesContext()); 076 } else { 077 return isActivated() || isRedisplay(); 078 } 079 } 080 081 private boolean isSubmitted() { 082 String action = ComponentUtil.findPage(getFacesContext(), this).getActionId(); 083 return action != null && action.startsWith(getClientId(getFacesContext()) + SEPARATOR_CHAR); 084 } 085 086 private boolean isRedisplay() { 087 if (isSubmitted()) { 088 UIPage page = ComponentUtil.findPage(getFacesContext(), this); 089 String action = page.getActionId(); 090 if (action != null) { 091 UIComponent command = page.findComponent(SEPARATOR_CHAR + action); 092 if (command != null && command instanceof UICommand) { 093 return !(command.getAttributes().get(TobagoConstants.ATTR_POPUP_CLOSE) != null); 094 } 095 } 096 } 097 return false; 098 } 099 100 private boolean isActivated() { 101 return activated; 102 } 103 104 public void encodeBegin(FacesContext facesContext) throws IOException { 105 super.encodeBegin(facesContext); 106 } 107 108 public void processValidators(FacesContext context) { 109 if (isSubmitted()) { 110 for (Iterator it = getFacetsAndChildren(); it.hasNext();) { 111 UIComponent childOrFacet = (UIComponent) it.next(); 112 childOrFacet.processValidators(context); 113 } 114 //TODO: check if validation has failed and reset rendered if needed 115 if (context.getRenderResponse()) { 116 setActivated(true); 117 } 118 } 119 } 120 121 public void processUpdates(FacesContext context) { 122 if (isSubmitted()) { 123 for (Iterator it = getFacetsAndChildren(); it.hasNext();) { 124 UIComponent childOrFacet = (UIComponent) it.next(); 125 childOrFacet.processUpdates(context); 126 } 127 } 128 } 129 130 131 public void setParent(UIComponent uiComponent) { 132 super.setParent(uiComponent); 133 // XXX find a better way 134 addToPage(); 135 } 136 137 public Object saveState(FacesContext context) { 138 Object[] saveState = new Object[7]; 139 saveState[0] = super.saveState(context); 140 saveState[1] = width; 141 saveState[2] = height; 142 saveState[3] = left; 143 saveState[4] = top; 144 saveState[5] = activated; 145 saveState[6] = modal; 146 return saveState; 147 } 148 149 public void restoreState(FacesContext context, Object savedState) { 150 Object[] values = (Object[]) savedState; 151 super.restoreState(context, values[0]); 152 width = (String) values[1]; 153 height = (String) values[2]; 154 left = (String) values[3]; 155 top = (String) values[4]; 156 activated = (Boolean) values[5]; 157 modal = (Boolean) values[6]; 158 } 159 160 public String getWidth() { 161 if (width != null) { 162 return width; 163 } 164 ValueBinding vb = getValueBinding(ATTR_WIDTH); 165 if (vb != null) { 166 Object value = vb.getValue(getFacesContext()); 167 return value != null ? value.toString() : null; 168 } else { 169 return null; 170 } 171 } 172 173 public void setWidth(String width) { 174 this.width = width; 175 } 176 177 public String getHeight() { 178 if (height != null) { 179 return height; 180 } 181 ValueBinding vb = getValueBinding(ATTR_HEIGHT); 182 if (vb != null) { 183 Object value = vb.getValue(getFacesContext()); 184 return value != null ? value.toString() : null; 185 } else { 186 return null; 187 } 188 } 189 190 public void setHeight(String height) { 191 this.height = height; 192 } 193 194 public String getLeft() { 195 if (left != null) { 196 return left; 197 } 198 ValueBinding vb = getValueBinding(ATTR_LEFT); 199 if (vb != null) { 200 Object value = vb.getValue(getFacesContext()); 201 return value != null ? value.toString() : null; 202 } else { 203 return null; 204 } 205 } 206 207 public void setLeft(String left) { 208 this.left = left; 209 } 210 211 public String getTop() { 212 if (top != null) { 213 return top; 214 } 215 ValueBinding vb = getValueBinding(ATTR_TOP); 216 if (vb != null) { 217 Object value = vb.getValue(getFacesContext()); 218 return value != null ? value.toString() : null; 219 } else { 220 return null; 221 } 222 } 223 224 public void setTop(String top) { 225 this.top = top; 226 } 227 228 public boolean isModal() { 229 if (modal != null) { 230 return modal; 231 } 232 ValueBinding vb = getValueBinding(TobagoConstants.ATTR_MODAL); 233 if (vb != null) { 234 return (Boolean.TRUE.equals(vb.getValue(getFacesContext()))); 235 } else { 236 return true; 237 } 238 } 239 240 public void setModal(boolean modal) { 241 this.modal = modal; 242 } 243 244 private void addToPage() { 245 UIPage page = ComponentUtil.findPage(getFacesContext(), this); 246 if (page != null) { 247 page.getPopups().add(this); 248 } 249 } 250 251 public void encodeEnd(FacesContext context) throws IOException { 252 super.encodeEnd(context); 253 activated = false; 254 } 255 256 public void encodeAjax(FacesContext facesContext) throws IOException { 257 super.encodeAjax(facesContext); 258 activated = false; 259 } 260 }