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 }