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    }