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