| /* |
| * Copyright 2010 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. You may obtain a copy of |
| * the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| package com.google.gwt.uibinder.elementparsers; |
| |
| import com.google.gwt.core.ext.UnableToCompleteException; |
| import com.google.gwt.core.ext.typeinfo.JClassType; |
| import com.google.gwt.core.ext.typeinfo.JType; |
| import com.google.gwt.core.ext.typeinfo.TypeOracle; |
| import com.google.gwt.core.ext.typeinfo.TypeOracleException; |
| import com.google.gwt.i18n.client.DateTimeFormat; |
| import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat; |
| import com.google.gwt.i18n.client.TimeZone; |
| import com.google.gwt.uibinder.rebind.TypeOracleUtils; |
| import com.google.gwt.uibinder.rebind.UiBinderWriter; |
| import com.google.gwt.uibinder.rebind.XMLElement; |
| |
| /** |
| * Parses {@link com.google.gwt.user.client.ui.DateLabel} widgets. |
| */ |
| public class DateLabelParser implements ElementParser { |
| |
| static final String AT_MOST_ONE_SPECIFIED_FORMAT = "May have at most one of format, predefinedFormat and customFormat."; |
| static final String AT_MOST_ONE_SPECIFIED_TIME_ZONE = "May have at most one of timezone and timezoneOffset."; |
| static final String NO_TIMEZONE_WITHOUT_SPECIFIED_FORMAT = "May not specify a time zone if no format is given."; |
| |
| public void parse(XMLElement elem, String fieldName, JClassType type, |
| UiBinderWriter writer) throws UnableToCompleteException { |
| boolean supportsTimeZone = hasDateTimeFormatAndTimeZoneConstructor( |
| writer.getOracle(), type); |
| if (hasDateTimeFormatConstructor(writer.getOracle(), type) |
| || supportsTimeZone) { |
| String format = consumeFormat(elem, writer); |
| |
| if (format != null) { |
| String timeZone = (supportsTimeZone ? consumeTimeZone(elem, writer) |
| : null); |
| |
| writer.setFieldInitializerAsConstructor(fieldName, makeArgs( |
| format, timeZone)); |
| } else if (supportsTimeZone && hasTimeZone(elem)) { |
| writer.die(elem, NO_TIMEZONE_WITHOUT_SPECIFIED_FORMAT); |
| } |
| } |
| } |
| |
| private String consumeFormat(XMLElement elem, UiBinderWriter writer) |
| throws UnableToCompleteException { |
| String format = elem.consumeAttribute("format", |
| writer.getOracle().findType(DateTimeFormat.class.getCanonicalName())); |
| String predefinedFormat = elem.consumeAttribute("predefinedFormat", |
| writer.getOracle().findType(PredefinedFormat.class.getCanonicalName())); |
| String customFormat = elem.consumeStringAttribute("customFormat"); |
| |
| if (format != null) { |
| if (predefinedFormat != null || customFormat != null) { |
| writer.die(elem, AT_MOST_ONE_SPECIFIED_FORMAT); |
| } |
| return format; |
| } |
| if (predefinedFormat != null) { |
| if (customFormat != null) { |
| writer.die(elem, AT_MOST_ONE_SPECIFIED_FORMAT); |
| } |
| return makeGetFormat(predefinedFormat); |
| } |
| if (customFormat != null) { |
| return makeGetFormat(customFormat); |
| } |
| return null; |
| } |
| |
| private String consumeTimeZone(XMLElement elem, UiBinderWriter writer) |
| throws UnableToCompleteException { |
| String timeZone = elem.consumeAttribute("timezone", |
| writer.getOracle().findType(TimeZone.class.getCanonicalName())); |
| String timeZoneOffset = elem.consumeAttribute("timezoneOffset", |
| getIntType(writer.getOracle())); |
| if (timeZone != null && timeZoneOffset != null) { |
| writer.die(elem, AT_MOST_ONE_SPECIFIED_TIME_ZONE); |
| } |
| if (timeZone != null) { |
| return timeZone; |
| } |
| if (timeZoneOffset != null) { |
| return TimeZone.class.getCanonicalName() + ".createTimeZone(" |
| + timeZoneOffset + ")"; |
| } |
| return null; |
| } |
| |
| private JType getIntType(TypeOracle oracle) { |
| try { |
| return oracle.parse("int"); |
| } catch (TypeOracleException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| private boolean hasDateTimeFormatAndTimeZoneConstructor( |
| TypeOracle typeOracle, JClassType type) { |
| JType dateTimeFormatType = typeOracle.findType(DateTimeFormat.class.getName()); |
| JType timeZoneType = typeOracle.findType(TimeZone.class.getName()); |
| return TypeOracleUtils.hasCompatibleConstructor(type, dateTimeFormatType, timeZoneType); |
| } |
| |
| private boolean hasDateTimeFormatConstructor(TypeOracle typeOracle, |
| JClassType type) { |
| JType dateTimeFormatType = typeOracle.findType(DateTimeFormat.class.getName()); |
| return TypeOracleUtils.hasCompatibleConstructor(type, dateTimeFormatType); |
| } |
| |
| private boolean hasTimeZone(XMLElement elem) { |
| return elem.hasAttribute("timezone") || elem.hasAttribute("timezoneOffset"); |
| } |
| |
| private String[] makeArgs(String format, String timeZone) { |
| if (timeZone == null) { |
| return new String[] {format}; |
| } |
| return new String[] {format, timeZone}; |
| } |
| |
| private String makeGetFormat(String format) { |
| return DateTimeFormat.class.getCanonicalName() + ".getFormat(" + format |
| + ")"; |
| } |
| } |