    001    // Copyright 2010, 2011 The Apache Software Foundation
    002    //
    003    // Licensed under the Apache License, Version 2.0 (the "License");
    004    // you may not use this file except in compliance with the License.
    005    // You may obtain a copy of the License at
    006    //
    007    // http://www.apache.org/licenses/LICENSE-2.0
    008    //
    009    // Unless required by applicable law or agreed to in writing, software
    010    // distributed under the License is distributed on an "AS IS" BASIS,
    011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    012    // See the License for the specific language governing permissions and
    013    // limitations under the License.
    014
    015    package org.apache.tapestry5.internal.services.javascript;
    016
    017    import java.text.DateFormatSymbols;
    018    import java.util.Calendar;
    019    import java.util.Collections;
    020    import java.util.List;
    021    import java.util.Locale;
    022
    023    import org.apache.tapestry5.Asset;
    024    import org.apache.tapestry5.SymbolConstants;
    025    import org.apache.tapestry5.func.F;
    026    import org.apache.tapestry5.func.Mapper;
    027    import org.apache.tapestry5.internal.TapestryInternalUtils;
    028    import org.apache.tapestry5.ioc.annotations.Symbol;
    029    import org.apache.tapestry5.ioc.services.ThreadLocale;
    030    import org.apache.tapestry5.json.JSONArray;
    031    import org.apache.tapestry5.json.JSONObject;
    032    import org.apache.tapestry5.services.AssetSource;
    033    import org.apache.tapestry5.services.javascript.JavaScriptStack;
    034    import org.apache.tapestry5.services.javascript.StylesheetLink;
    035
    036    public class DateFieldStack implements JavaScriptStack
    037    {
    038        private final ThreadLocale threadLocale;
    039
    040        private final boolean compactJSON;
    041
    042        private final List<Asset> javaScriptStack;
    043
    044        private final List<StylesheetLink> stylesheetStack;
    045
    046        public DateFieldStack(ThreadLocale threadLocale, @Symbol(SymbolConstants.COMPACT_JSON)
    047        boolean compactJSON, final AssetSource assetSource)
    048        {
    049            this.threadLocale = threadLocale;
    050            this.compactJSON = compactJSON;
    051
    052            Mapper<String, Asset> pathToAsset = new Mapper<String, Asset>()
    053            {
    054                public Asset map(String path)
    055                {
    056                    return assetSource.getExpandedAsset(path);
    057                }
    058            };
    059
    060            Mapper<String, StylesheetLink> pathToStylesheetLink = F.combine(pathToAsset,
    061                    TapestryInternalUtils.assetToStylesheetLink);
    062
    063            javaScriptStack = F
    064                    .flow("${tapestry.datepicker}/js/datepicker.js", "org/apache/tapestry5/corelib/components/datefield.js")
    065                    .map(pathToAsset).toList();
    066
    067            stylesheetStack = F.flow("${tapestry.datepicker}/css/datepicker.css").map(pathToStylesheetLink).toList();
    068        }
    069
    070        public String getInitialization()
    071        {
    072            Locale locale = threadLocale.getLocale();
    073
    074            JSONObject spec = new JSONObject();
    075
    076            DateFormatSymbols symbols = new DateFormatSymbols(locale);
    077
    078            spec.put("months", new JSONArray((Object[])symbols.getMonths()));
    079
    080            StringBuilder days = new StringBuilder();
    081
    082            String[] weekdays = symbols.getWeekdays();
    083
    084            Calendar c = Calendar.getInstance(locale);
    085
    086            int firstDay = c.getFirstDayOfWeek();
    087
    088            // DatePicker needs them in order from monday to sunday.
    089
    090            for (int i = Calendar.MONDAY; i <= Calendar.SATURDAY; i++)
    091            {
    092                days.append(weekdays[i].substring(0, 1));
    093            }
    094
    095            days.append(weekdays[Calendar.SUNDAY].substring(0, 1));
    096
    097            spec.put("days", days.toString().toLowerCase(locale));
    098
    099            // DatePicker expects 0 to be monday. Calendar defines SUNDAY as 1, MONDAY as 2, etc.
    100
    101            spec.put("firstDay", firstDay == Calendar.SUNDAY ? 6 : firstDay - 2);
    102
    103            // TODO: Skip localization if locale is English?
    104
    105            return String.format("Tapestry.DateField.initLocalization(%s);", spec.toString(compactJSON));
    106        }
    107
    108        public List<Asset> getJavaScriptLibraries()
    109        {
    110            return javaScriptStack;
    111        }
    112
    113        public List<StylesheetLink> getStylesheets()
    114        {
    115            return stylesheetStack;
    116        }
    117
    118        public List<String> getStacks()
    119        {
    120            return Collections.emptyList();
    121        }
    122    }