001    /*
002     * Copyright 1999-2004 The Apache Software Foundation.
003     * Modifications, Copyright 2005 Stephen Colebourne
004     * 
005     * Licensed under the Apache License, Version 2.0 (the "License");
006     * you may not use this file except in compliance with the License.
007     * You may obtain a copy of the License at
008     * 
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     * 
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.joda.time.contrib.jsptag;
018    
019    import java.io.IOException;
020    
021    import javax.servlet.jsp.JspException;
022    import javax.servlet.jsp.JspTagException;
023    import javax.servlet.jsp.PageContext;
024    import javax.servlet.jsp.jstl.core.Config;
025    import javax.servlet.jsp.tagext.BodyTagSupport;
026    import javax.servlet.jsp.tagext.Tag;
027    
028    import org.joda.time.DateTimeZone;
029    
030    /**
031     * Support for tag handlers for <timeZone>.
032     * 
033     * @author Jan Luehe
034     * @author Jim Newsham
035     */
036    public abstract class DateTimeZoneSupport extends BodyTagSupport {
037    
038        /** The config key for the time zone. */
039        public static final String FMT_TIME_ZONE = "org.joda.time.dateTimeZone";
040    
041        /** The value attribute. */
042        protected Object value;
043    
044        /** The zone. */
045        private DateTimeZone dateTimeZone;
046    
047        /**
048         * Constructor.
049         */
050        public DateTimeZoneSupport() {
051            super();
052            init();
053        }
054    
055        private void init() {
056            value = null;
057        }
058    
059        public DateTimeZone getDateTimeZone() {
060            return dateTimeZone;
061        }
062    
063        public int doStartTag() throws JspException {
064            if (value == null) {
065                dateTimeZone = DateTimeZone.UTC;
066            } else if (value instanceof String) {
067                try {
068                    dateTimeZone = DateTimeZone.forID((String) value);
069                } catch (IllegalArgumentException iae) {
070                    dateTimeZone = DateTimeZone.UTC;
071                }
072            } else {
073                dateTimeZone = (DateTimeZone) value;
074            }
075            return EVAL_BODY_BUFFERED;
076        }
077    
078        public int doEndTag() throws JspException {
079            try {
080                pageContext.getOut().print(bodyContent.getString());
081            } catch (IOException ioe) {
082                throw new JspTagException(ioe.toString(), ioe);
083            }
084            return EVAL_PAGE;
085        }
086    
087        // Releases any resources we may have (or inherit)
088        public void release() {
089            init();
090        }
091    
092        /**
093         * Determines and returns the time zone to be used by the given action.
094         * <p>
095         * If the given action is nested inside a &lt;dateTimeZone&gt; action,
096         * the time zone is taken from the enclosing &lt;dateTimeZone&gt; action.
097         * <p>
098         * Otherwise, the time zone configuration setting
099         * <tt>org.joda.time.FMT_TIME_ZONE</tt> is used.
100         * 
101         * @param pc  the page containing the action for which the time zone
102         *  needs to be determined
103         * @param fromTag  the action for which the time zone needs to be determined
104         * 
105         * @return the time zone, or <tt> null </tt> if the given action is not
106         * nested inside a &lt;dateTimeZone&gt; action and no time zone configuration
107         * setting exists
108         */
109        static DateTimeZone getDateTimeZone(PageContext pc, Tag fromTag) {
110            DateTimeZone tz = null;
111    
112            Tag t = findAncestorWithClass(fromTag, DateTimeZoneSupport.class);
113            if (t != null) {
114                // use time zone from parent <timeZone> tag
115                DateTimeZoneSupport parent = (DateTimeZoneSupport) t;
116                tz = parent.getDateTimeZone();
117            } else {
118                // get time zone from configuration setting
119                Object obj = Config.find(pc, FMT_TIME_ZONE);
120                if (obj != null) {
121                    if (obj instanceof DateTimeZone) {
122                        tz = (DateTimeZone) obj;
123                    } else {
124                        try {
125                            tz = DateTimeZone.forID((String) obj);
126                        } catch (IllegalArgumentException iae) {
127                            tz = DateTimeZone.UTC;
128                        }
129                    }
130                }
131            }
132    
133            return tz;
134        }
135    
136    }