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.commons.logging.Log;
021    import org.apache.commons.logging.LogFactory;
022    import org.apache.myfaces.tobago.ajax.api.AjaxComponent;
023    import org.apache.myfaces.tobago.TobagoConstants;
024    import static org.apache.myfaces.tobago.TobagoConstants.ATTR_HEIGHT;
025    import static org.apache.myfaces.tobago.TobagoConstants.ATTR_LEFT;
026    import static org.apache.myfaces.tobago.TobagoConstants.ATTR_TOP;
027    import static org.apache.myfaces.tobago.TobagoConstants.ATTR_WIDTH;
028    
029    import javax.faces.component.NamingContainer;
030    import javax.faces.component.UIComponent;
031    import javax.faces.context.FacesContext;
032    import javax.faces.el.ValueBinding;
033    import java.io.IOException;
034    import java.util.Iterator;
035    
036    public class UIPopup extends UIPanelBase implements NamingContainer, AjaxComponent {
037    
038      private static final Log LOG = LogFactory.getLog(UIPopup.class);
039    
040      public static final String COMPONENT_TYPE = "org.apache.myfaces.tobago.Popup";
041    
042      private String width;
043      private String height;
044      private String left;
045      private String top;
046      private boolean activated;
047      private Boolean modal;
048    
049      public void setActivated(boolean activated) {
050        this.activated = activated;
051        addToPage();
052      }
053    
054      public void processDecodes(FacesContext facesContext) {
055        if (isSubmitted()) {
056          for (Iterator it = getFacetsAndChildren(); it.hasNext();) {
057            UIComponent childOrFacet = (UIComponent) it.next();
058            childOrFacet.processDecodes(facesContext);
059          }
060          try {
061            decode(facesContext);
062          } catch (RuntimeException e) {
063            facesContext.renderResponse();
064            throw e;
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 faild 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          return (String) vb.getValue(getFacesContext());
165        } else {
166          return null;
167        }
168      }
169    
170      public void setWidth(String width) {
171        this.width = width;
172      }
173    
174      public String getHeight() {
175        if (height != null) {
176          return height;
177        }
178        ValueBinding vb = getValueBinding(ATTR_HEIGHT);
179        if (vb != null) {
180          return (String) vb.getValue(getFacesContext());
181        } else {
182          return null;
183        }
184      }
185    
186      public void setHeight(String height) {
187        this.height = height;
188      }
189    
190      public String getLeft() {
191        if (left != null) {
192          return left;
193        }
194        ValueBinding vb = getValueBinding(ATTR_LEFT);
195        if (vb != null) {
196          return (String) vb.getValue(getFacesContext());
197        } else {
198          return null;
199        }
200      }
201    
202      public void setLeft(String left) {
203        this.left = left;
204      }
205    
206      public String getTop() {
207        if (top != null) {
208          return top;
209        }
210        ValueBinding vb = getValueBinding(ATTR_TOP);
211        if (vb != null) {
212          return (String) vb.getValue(getFacesContext());
213        } else {
214          return null;
215        }
216      }
217    
218      public void setTop(String top) {
219        this.top = top;
220      }
221    
222      public boolean isModal() {
223        if (modal != null) {
224          return modal;
225        }
226        ValueBinding vb = getValueBinding(TobagoConstants.ATTR_MODAL);
227        if (vb != null) {
228          return (Boolean.TRUE.equals(vb.getValue(getFacesContext())));
229        } else {
230          return true;
231        }
232      }
233    
234      public void setModal(boolean modal) {
235        this.modal = modal;
236      }
237    
238      private void addToPage() {
239        UIPage page = ComponentUtil.findPage(getFacesContext(), this);
240        if (page != null) {
241          page.getPopups().add(this);
242        }
243      }
244    
245      public void encodeEnd(FacesContext context) throws IOException {
246        super.encodeEnd(context);
247        activated = false;
248      }
249    
250      public void encodeAjax(FacesContext facesContext) throws IOException {
251        super.encodeAjax(facesContext);
252        activated = false;
253      }
254    }