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    }