| /* |
| * 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.i18n.client.CurrencyData; |
| import com.google.gwt.i18n.client.NumberFormat; |
| import com.google.gwt.uibinder.rebind.UiBinderWriter; |
| import com.google.gwt.uibinder.rebind.XMLElement; |
| |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| /** |
| * Parses {@link com.google.gwt.user.client.ui.DateLabel} widgets. |
| */ |
| public class NumberLabelParser implements ElementParser { |
| |
| static final String AT_MOST_ONE_SPECIFIED_FORMAT = "May have only one of format, predefinedFormat and customFormat."; |
| static final String AT_MOST_ONE_SPECIFIED_CURRENCY = "May have only one of currencyData and customCode."; |
| static final String NO_CURRENCY_WITH_FORMAT = "May not specify both a NumberFormat and a currency code."; |
| static final String NO_CURRENCY_WITHOUT_SPECIFIED_FORMAT = "May not specify a currency code if no format is given."; |
| static final String NO_CURRENCY_WITH_PREDEFINED_FORMAT = "May not specify a currency code with a predefined format (except the CURRENCY format)"; |
| static final String UNKNOWN_PREDEFINED_FORMAT = "Unknown predefined format: %s"; |
| |
| private static final Map<String, String> predefinedFormats; |
| |
| static { |
| String prefix = NumberFormat.class.getCanonicalName(); |
| Map<String, String> formats = new HashMap<String, String>(4); |
| formats.put("DECIMAL", prefix + ".getDecimalFormat()"); |
| formats.put("PERCENT", prefix + ".getPercentFormat()"); |
| formats.put("SCIENTIFIC", prefix + ".getScientificFormat()"); |
| // CURRENCY is special-cased in consumeFormat. |
| predefinedFormats = Collections.unmodifiableMap(formats); |
| } |
| |
| public void parse(XMLElement elem, String fieldName, JClassType type, |
| UiBinderWriter writer) throws UnableToCompleteException { |
| if (hasNumberFormatConstructor(writer.getOracle(), type)) { |
| String format = consumeFormat(elem, writer); |
| |
| if (format != null) { |
| writer.setFieldInitializerAsConstructor(fieldName, format); |
| } |
| } |
| } |
| |
| private String consumeCurrency(XMLElement elem, UiBinderWriter writer) |
| throws UnableToCompleteException { |
| String currencyData = elem.consumeAttribute("currencyData", |
| writer.getOracle().findType(CurrencyData.class.getCanonicalName())); |
| String currencyCode = elem.consumeStringAttribute("currencyCode"); |
| |
| if (currencyData != null && currencyCode != null) { |
| writer.die(elem, AT_MOST_ONE_SPECIFIED_CURRENCY); |
| } |
| return currencyData != null ? currencyData : currencyCode; |
| } |
| |
| private String consumeFormat(XMLElement elem, UiBinderWriter writer) |
| throws UnableToCompleteException { |
| String format = elem.consumeAttribute("format", |
| writer.getOracle().findType(NumberFormat.class.getCanonicalName())); |
| String predefinedFormat = elem.consumeRawAttribute("predefinedFormat"); |
| String customFormat = elem.consumeStringAttribute("customFormat"); |
| |
| if (format != null) { |
| if (predefinedFormat != null || customFormat != null) { |
| writer.die(elem, AT_MOST_ONE_SPECIFIED_FORMAT); |
| } |
| if (hasCurrency(elem)) { |
| writer.die(elem, NO_CURRENCY_WITH_FORMAT); |
| } |
| return format; |
| } |
| if (predefinedFormat != null) { |
| if (customFormat != null) { |
| writer.die(elem, AT_MOST_ONE_SPECIFIED_FORMAT); |
| } |
| if ("CURRENCY".equals(predefinedFormat)) { |
| String currency = consumeCurrency(elem, writer); |
| return NumberFormat.class.getCanonicalName() + ".getCurrencyFormat(" |
| + (currency != null ? currency : "") + ")"; |
| } |
| if (hasCurrency(elem)) { |
| writer.die(elem, NO_CURRENCY_WITH_PREDEFINED_FORMAT); |
| } |
| String f = predefinedFormats.get(predefinedFormat); |
| if (f == null) { |
| writer.die(elem, UNKNOWN_PREDEFINED_FORMAT, predefinedFormat); |
| } |
| return f; |
| } |
| if (customFormat != null) { |
| String currency = consumeCurrency(elem, writer); |
| return NumberFormat.class.getCanonicalName() + ".getFormat(" + customFormat |
| + (currency != null ? ", " + currency : "") + ")"; |
| } |
| if (hasCurrency(elem)) { |
| writer.die(elem, NO_CURRENCY_WITHOUT_SPECIFIED_FORMAT); |
| } |
| return null; |
| } |
| |
| private boolean hasCurrency(XMLElement elem) { |
| return elem.hasAttribute("currencyData") |
| || elem.hasAttribute("currencyCode"); |
| } |
| |
| private boolean hasNumberFormatConstructor(TypeOracle typeOracle, |
| JClassType type) { |
| JType numberFormatType = typeOracle.findType(NumberFormat.class.getName()); |
| return type.findConstructor(new JType[] {numberFormatType}) != null; |
| } |
| } |