blob: 01b4002ea1d8cbfb81100db36acdfefbc5b2ad43 [file] [log] [blame]
/*
* 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, type, 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;
}
}