/* * Copyright 2004-2009 the original author or authors. * * 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 org.compass.core.converter.basic; import java.text.DecimalFormat; import java.text.NumberFormat; import java.text.ParseException; import java.util.Locale; import org.compass.core.config.CompassConfigurable; import org.compass.core.converter.ConversionException; import org.compass.core.converter.basic.format.Formatter; import org.compass.core.converter.basic.format.FormatterFactory; import org.compass.core.converter.basic.format.TextFormatFormatter; import org.compass.core.mapping.ResourcePropertyMapping; import org.compass.core.marshall.MarshallingContext; /** * A base class for number based converters. Allows for formatting (if specified) and for default * behaviour handling if none is provided. * * @author kimchy */ public abstract class AbstractNumberConverter<N extends Number> extends AbstractFormatConverter<N> implements CompassConfigurable { public static final String SORTABLE_FORMAT = "sortable"; private class NumberFormatter implements FormatterFactory { private String format; private Locale locale; public void configure(String format, Locale locale) { this.format = format; this.locale = locale; } public Formatter create() { if (SORTABLE_FORMAT.equalsIgnoreCase(format)) { Formatter formatter = createSortableFormatter(); if (formatter == null) { throw new ConversionException("This converter [" + getClass().getName() + "] does not support sortable format"); } return formatter; } NumberFormat numberFormat; if (locale != null) { numberFormat = NumberFormat.getInstance(locale); } else { numberFormat = NumberFormat.getInstance(); } ((DecimalFormat) numberFormat).applyPattern(format); return new TextFormatFormatter(numberFormat); } } protected FormatterFactory doCreateFormatterFactory() { return new AbstractNumberConverter.NumberFormatter(); } protected abstract N defaultFromString(String str, ResourcePropertyMapping resourcePropertyMapping); protected abstract N fromNumber(Number number); protected abstract Formatter createSortableFormatter(); protected N doFromString(String str, ResourcePropertyMapping resourcePropertyMapping, MarshallingContext context) throws ConversionException { if (hasFormatter) { ParseException pe = null; for (Formatter formatter : formatters) { try { return fromNumber((Number) formatter.parse(str)); } catch (ParseException e) { pe = e; } } throw new ConversionException("Failed to parse number [" + str + "]", pe); } else { return defaultFromString(str, resourcePropertyMapping); } } protected String doToString(N o, ResourcePropertyMapping resourcePropertyMapping, MarshallingContext context) { if (hasFormatter) { return formatters[0].format(o); } else { return defaultToString(o, resourcePropertyMapping, context); } } protected String defaultToString(N o, ResourcePropertyMapping resourcePropertyMapping, MarshallingContext context) { return super.doToString(o, resourcePropertyMapping, context); } }