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