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 015package org.apache.tapestry5.internal.services.javascript; 016 017import java.text.DateFormatSymbols; 018import java.util.Calendar; 019import java.util.Collections; 020import java.util.List; 021import java.util.Locale; 022 023import org.apache.tapestry5.Asset; 024import org.apache.tapestry5.SymbolConstants; 025import org.apache.tapestry5.func.F; 026import org.apache.tapestry5.func.Mapper; 027import org.apache.tapestry5.internal.TapestryInternalUtils; 028import org.apache.tapestry5.ioc.annotations.Symbol; 029import org.apache.tapestry5.ioc.services.ThreadLocale; 030import org.apache.tapestry5.json.JSONArray; 031import org.apache.tapestry5.json.JSONObject; 032import org.apache.tapestry5.services.AssetSource; 033import org.apache.tapestry5.services.javascript.JavaScriptStack; 034import org.apache.tapestry5.services.javascript.StylesheetLink; 035 036public 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}