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          addToPage();
064        }
065      }
066    
067      public boolean isRendered() {
068        ValueBinding valueBinding = getValueBinding("rendered");
069        if (valueBinding != null) {
070          return (Boolean) valueBinding.getValue(getFacesContext());
071        } else {
072          return isActivated() || isRedisplay();
073        }
074      }
075    
076      private boolean isSubmitted() {
077        String action = ComponentUtil.findPage(getFacesContext(), this).getActionId();
078        return action != null && action.startsWith(getClientId(getFacesContext()) + SEPARATOR_CHAR);
079      }
080    
081      private boolean isRedisplay() {
082        if (isSubmitted()) {
083          UIPage page = ComponentUtil.findPage(getFacesContext(), this);
084          String action = page.getActionId();
085          if (action != null) {
086            UIComponent command = page.findComponent(SEPARATOR_CHAR + action);
087            if (command != null && command instanceof UICommand) {
088              return !(command.getAttributes().get(TobagoConstants.ATTR_POPUP_CLOSE) != null);
089            }
090          }
091        }
092        return false;
093      }
094    
095      private boolean isActivated() {
096        return activated;
097      }
098    
099      public void encodeBegin(FacesContext facesContext) throws IOException {
100        super.encodeBegin(facesContext);
101      }
102    
103      public void processValidators(FacesContext context) {
104        if (isSubmitted()) {
105          for (Iterator it = getFacetsAndChildren(); it.hasNext();) {
106            UIComponent childOrFacet = (UIComponent) it.next();
107            childOrFacet.processValidators(context);
108          }
109          //TODO: check if validation has failed and reset rendered if needed
110          if (context.getRenderResponse()) {
111            setActivated(true);
112          }
113        }
114      }
115    
116      public void processUpdates(FacesContext context) {
117        if (isSubmitted()) {
118          for (Iterator it = getFacetsAndChildren(); it.hasNext();) {
119            UIComponent childOrFacet = (UIComponent) it.next();
120            childOrFacet.processUpdates(context);
121          }
122        }
123      }
124    
125    
126      public void setParent(UIComponent uiComponent) {
127        super.setParent(uiComponent);
128        // XXX find a better way
129        addToPage();
130      }
131    
132      public Object saveState(FacesContext context) {
133        Object[] saveState = new Object[7];
134        saveState[0] = super.saveState(context);
135        saveState[1] = width;
136        saveState[2] = height;
137        saveState[3] = left;
138        saveState[4] = top;
139        saveState[5] = activated;
140        saveState[6] = modal;
141        return saveState;
142      }
143    
144      public void restoreState(FacesContext context, Object savedState) {
145        Object[] values = (Object[]) savedState;
146        super.restoreState(context, values[0]);
147        width = (String) values[1];
148        height = (String) values[2];
149        left = (String) values[3];
150        top = (String) values[4];
151        activated = (Boolean) values[5];
152        modal = (Boolean) values[6];
153      }
154    
155      public String getWidth() {
156        if (width != null) {
157          return width;
158        }
159        ValueBinding vb = getValueBinding(ATTR_WIDTH);
160        if (vb != null) {
161          Object value = vb.getValue(getFacesContext());
162          return value != null ? value.toString() : null;
163        } else {
164          return null;
165        }
166      }
167    
168      public void setWidth(String width) {
169        this.width = width;
170      }
171    
172      public String getHeight() {
173        if (height != null) {
174          return height;
175        }
176        ValueBinding vb = getValueBinding(ATTR_HEIGHT);
177        if (vb != null) {
178          Object value = vb.getValue(getFacesContext());
179          return value != null ? value.toString() : null;
180        } else {
181          return null;
182        }
183      }
184    
185      public void setHeight(String height) {
186        this.height = height;
187      }
188    
189      public String getLeft() {
190        if (left != null) {
191          return left;
192        }
193        ValueBinding vb = getValueBinding(ATTR_LEFT);
194        if (vb != null) {
195          Object value = vb.getValue(getFacesContext());
196          return value != null ? value.toString() : null;
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          Object value = vb.getValue(getFacesContext());
213          return value != null ? value.toString() : null;
214        } else {
215          return null;
216        }
217      }
218    
219      public void setTop(String top) {
220        this.top = top;
221      }
222    
223      public boolean isModal() {
224        if (modal != null) {
225          return modal;
226        }
227        ValueBinding vb = getValueBinding(TobagoConstants.ATTR_MODAL);
228        if (vb != null) {
229          return (Boolean.TRUE.equals(vb.getValue(getFacesContext())));
230        } else {
231          return true;
232        }
233      }
234    
235      public void setModal(boolean modal) {
236        this.modal = modal;
237      }
238    
239      private void addToPage() {
240        UIPage page = ComponentUtil.findPage(getFacesContext(), this);
241        if (page != null) {
242          page.getPopups().add(this);
243        }
244      }
245    
246      public void encodeEnd(FacesContext context) throws IOException {
247        super.encodeEnd(context);
248        activated = false;
249      }
250    
251      public void encodeAjax(FacesContext facesContext) throws IOException {
252        super.encodeAjax(facesContext);
253        activated = false;
254      }
255    }