001    package org.apache.myfaces.tobago.event;
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 static org.apache.myfaces.tobago.TobagoConstants.ATTR_HEIGHT;
023    import static org.apache.myfaces.tobago.TobagoConstants.ATTR_LEFT;
024    import static org.apache.myfaces.tobago.TobagoConstants.ATTR_TOP;
025    import static org.apache.myfaces.tobago.TobagoConstants.ATTR_WIDTH;
026    import static org.apache.myfaces.tobago.TobagoConstants.FACET_PICKER_POPUP;
027    import org.apache.myfaces.tobago.component.ComponentUtil;
028    import org.apache.myfaces.tobago.config.ThemeConfig;
029    
030    import javax.faces.component.UICommand;
031    import javax.faces.component.UIComponent;
032    import javax.faces.context.FacesContext;
033    import javax.faces.el.EvaluationException;
034    import javax.faces.el.MethodBinding;
035    import javax.faces.el.MethodNotFoundException;
036    import javax.faces.event.ActionEvent;
037    import java.util.Map;
038    import java.util.StringTokenizer;
039    
040    /*
041     * User: weber
042     * Date: Jul 18, 2005
043     * Time: 3:24:46 PM
044     */
045    public class DatePickerController extends MethodBinding {
046    
047      private static final Log LOG = LogFactory.getLog(DatePickerController.class);
048      public static final String OPEN_POPUP = "openPopup";
049      public static final String CLOSE_POPUP = "closePopup";
050    
051      public DatePickerController() {
052      }
053    
054      public Object invoke(FacesContext facesContext, Object[] objects)
055          throws EvaluationException {
056    
057        if (objects[0] instanceof ActionEvent) {
058    
059          UICommand command = (UICommand) ((ActionEvent) objects[0]).getSource();
060          final String commandId = command.getClientId(facesContext);
061    
062          if (commandId.endsWith(OPEN_POPUP)) {
063    
064            final UIComponent popup
065                = command.getFacet(FACET_PICKER_POPUP);
066            if (popup != null) {
067              popup.setRendered(true);
068              final String dimensionParameter
069                  = commandId.substring(0, commandId.length() - OPEN_POPUP.length())
070                  + "Dimension";
071              final String dimension = (String) facesContext.getExternalContext()
072                  .getRequestParameterMap().get(dimensionParameter);
073    
074              StringTokenizer st = new StringTokenizer(dimension, "x:");
075              int width = nextDimensionToken(st,
076                  ThemeConfig.getValue(facesContext, popup, "DefaultPageWidth"));
077              int height = nextDimensionToken(st,
078                  ThemeConfig.getValue(facesContext, popup, "DefaultPageHeight"));
079              int left = nextDimensionToken(st, -1);
080              int top = nextDimensionToken(st, -1);
081              int popupWidth = ComponentUtil.getIntAttribute(
082                  popup, ATTR_WIDTH, -1);
083              int popupHeight = ComponentUtil.getIntAttribute(
084                  popup, ATTR_HEIGHT, -1);
085              int popupLeft = ComponentUtil.getIntAttribute(
086                  popup, ATTR_LEFT, -1);
087              int popupTop = ComponentUtil.getIntAttribute(
088                  popup, ATTR_TOP, -1);
089    
090              final Map<String, String> attributes = popup.getAttributes();
091              if (popupWidth == -1) {
092                popupWidth = ThemeConfig.getValue(
093                    facesContext, popup, "CalendarPopupWidth");
094                attributes.put(
095                    ATTR_WIDTH, String.valueOf(popupWidth));
096              }
097              if (popupHeight == -1) {
098                popupHeight = ThemeConfig.getValue(
099                    facesContext, popup, "CalendarPopupHeight");
100                attributes.put(
101                    ATTR_HEIGHT, String.valueOf(popupHeight));
102              }
103    
104              if (popupLeft == -1) {
105                if (left != -1) {
106                  int popupRight = left + (popupWidth / 2);
107                  popupLeft = popupRight < width
108                      ? popupRight - popupWidth
109                      : width - popupWidth;
110                } else {
111                  popupLeft = (width - popupWidth) / 2;
112                }
113                attributes.put(ATTR_LEFT,
114                    (popupLeft > 0 ? String.valueOf(popupLeft) : "0"));
115              }
116    
117              if (popupTop == -1) {
118                if (top != -1) {
119                  final int fixedHeight =
120                      ThemeConfig.getValue(facesContext, command, "fixedHeight");
121                  int popupBottom = top + popupHeight + fixedHeight;
122                  popupTop = popupBottom < height
123                      ? top + fixedHeight
124                      : height - popupHeight;
125                } else {
126                  popupTop = (height - popupHeight) / 2;
127                }
128                attributes.put(ATTR_TOP,
129                    (popupTop > 0 ? String.valueOf(popupTop) : "0"));
130              }
131            }
132          }
133    
134        }
135        return null;
136      }
137    
138      private int nextDimensionToken(StringTokenizer st, int defaultValue) {
139        if (st.hasMoreTokens()) {
140          try {
141            defaultValue = Integer.parseInt(st.nextToken());
142          } catch (NumberFormatException e) {
143            LOG.error("Caught: " + e.getMessage(), e);
144          }
145        }
146        return defaultValue;
147      }
148    
149      public Class getType(FacesContext facesContext)
150          throws MethodNotFoundException {
151        return String.class;
152      }
153    }