001/* 002 * (C) Copyright 2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Anahide Tchertchian 018 */ 019package org.nuxeo.ecm.platform.ui.web.tag.handler; 020 021import java.text.ParseException; 022import java.text.SimpleDateFormat; 023import java.util.Date; 024import java.util.TimeZone; 025 026import javax.faces.view.facelets.ComponentConfig; 027import javax.faces.view.facelets.FaceletContext; 028import javax.faces.view.facelets.MetaRule; 029import javax.faces.view.facelets.MetaRuleset; 030import javax.faces.view.facelets.Metadata; 031import javax.faces.view.facelets.MetadataTarget; 032import javax.faces.view.facelets.TagAttribute; 033import javax.faces.view.facelets.TagAttributes; 034 035import org.apache.commons.logging.Log; 036import org.apache.commons.logging.LogFactory; 037import org.jboss.seam.international.LocaleSelector; 038import org.jboss.seam.international.TimeZoneSelector; 039import org.richfaces.component.UICalendar; 040 041/** 042 * @since 5.4.2 043 */ 044public class InputDateTimeTagHandler extends GenericHtmlComponentHandler { 045 046 private static final Log log = LogFactory.getLog(InputDateTimeTagHandler.class); 047 048 protected final String defaultTime; 049 050 /** 051 * @since 5.7.2 052 */ 053 protected TagAttributes attributes; 054 055 public InputDateTimeTagHandler(ComponentConfig config) { 056 super(config); 057 attributes = config.getTag().getAttributes(); 058 defaultTime = getValue(attributes, "defaultTime", "12:00"); 059 } 060 061 protected String getValue(TagAttributes attrs, String name, String defaultValue) { 062 TagAttribute attr = attrs.get(name); 063 if (attr == null) { 064 return defaultValue; 065 } 066 return attr.getValue(); 067 } 068 069 @Override 070 @SuppressWarnings("rawtypes") 071 protected MetaRuleset createMetaRuleset(Class type) { 072 MetaRuleset m = super.createMetaRuleset(type); 073 074 // aliases for the old date time component compatibility 075 m.alias("format", "datePattern"); 076 // showsTime is not configurable anymore 077 m.ignore("showsTime"); 078 // locale ok 079 // timeZone ok, just need to convert string to a TimeZone instance 080 m.addRule(new TimeZoneMetaRule()); 081 // do not bind styleClass to inputClass anymore: styleClass can be 082 // taken into account but the datetime widget itself, see NXP-14963. 083 // m.alias("styleClass", "inputClass"); 084 m.alias("triggerLabel", "buttonLabel"); 085 m.alias("triggerImg", "buttonIcon"); 086 m.alias("triggerStyleClass", "buttonClass"); 087 088 m.alias("onclick", "oninputclick"); 089 090 // setup some default properties 091 m.add(new TagMetaData()); 092 093 // onchange and onselect not working anymore, but keep them in case 094 // this is solved one day 095 // m.ignore("onchange"); 096 // m.ignore("onselect"); 097 098 return m; 099 100 } 101 102 class TimeZoneMetaRule extends MetaRule { 103 104 public Metadata applyRule(String name, TagAttribute attribute, MetadataTarget meta) { 105 if (!"timeZone".equals(name)) { 106 return null; 107 } 108 return new Metadata() { 109 @Override 110 public void applyMetadata(FaceletContext ctx, Object instance) { 111 Object tz = attribute.getObject(ctx); 112 if (tz instanceof TimeZone) { 113 ((UICalendar) instance).setTimeZone((TimeZone) tz); 114 } else if (tz instanceof String) { 115 ((UICalendar) instance).setTimeZone(TimeZone.getTimeZone((String) tz)); 116 } else { 117 throw new IllegalArgumentException("Invalid timezone: " + tz); 118 } 119 } 120 }; 121 } 122 } 123 124 class TagMetaData extends Metadata { 125 126 public TagMetaData() { 127 super(); 128 } 129 130 @Override 131 public void applyMetadata(FaceletContext ctx, Object instance) { 132 if (!(instance instanceof UICalendar)) { 133 log.error("Cannot apply date time component metadata, " + "not a HtmlCalendar instance: " + instance); 134 return; 135 } 136 UICalendar c = (UICalendar) instance; 137 TimeZone tz = c.getTimeZone(); 138 if (tz == null) { 139 // set default timezone only if not already specified in the component 140 c.setTimeZone(TimeZoneSelector.instance().getTimeZone()); 141 } 142 c.setLocale(LocaleSelector.instance().getLocale()); 143 } 144 } 145 146 @Override 147 public void setAttributes(FaceletContext ctx, Object instance) { 148 super.setAttributes(ctx, instance); 149 // set default time in timezone 150 UICalendar c = (UICalendar) instance; 151 c.setPopup(Boolean.parseBoolean(getValue(attributes, "popup", "true"))); 152 c.setEnableManualInput(Boolean.parseBoolean(getValue(attributes, "enableManualInput", "true"))); 153 c.setShowApplyButton(Boolean.parseBoolean(getValue(attributes, "showApplyButton", "false"))); 154 c.setZindex(Integer.parseInt(getValue(attributes, "zindex", "1500"))); 155 setDefaultTime(c); 156 } 157 158 protected void setDefaultTime(UICalendar instance) { 159 SimpleDateFormat format = new SimpleDateFormat("HH:mm"); 160 format.setTimeZone(instance.getTimeZone()); 161 Date date; 162 try { 163 date = format.parse(defaultTime); 164 } catch (ParseException e) { 165 return; 166 } 167 instance.setDefaultTime(date); 168 } 169}