001: /*
002: * Copyright 2004-2006 the original author or authors.
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:
017: package org.compass.core.converter.basic;
018:
019: import java.text.DecimalFormat;
020: import java.text.NumberFormat;
021: import java.text.ParseException;
022: import java.util.Locale;
023:
024: import org.compass.core.config.CompassConfigurable;
025: import org.compass.core.converter.ConversionException;
026: import org.compass.core.mapping.ResourcePropertyMapping;
027: import org.compass.core.marshall.MarshallingContext;
028:
029: /**
030: * A base class for number based converters. Allows for formatting (if specified) and for default
031: * behaviour handling if none is provided.
032: *
033: * @author kimchy
034: */
035: public abstract class AbstractNumberConverter extends
036: AbstractFormatConverter implements CompassConfigurable {
037:
038: private static class NumberFormatter implements
039: ThreadSafeFormat.FormatterFactory {
040:
041: private String format;
042:
043: private Locale locale;
044:
045: public void configure(String format, Locale locale) {
046: this .format = format;
047: this .locale = locale;
048: }
049:
050: public java.text.Format create() {
051: NumberFormat numberFormat;
052: if (locale != null) {
053: numberFormat = NumberFormat.getInstance(locale);
054: } else {
055: numberFormat = NumberFormat.getInstance();
056: }
057: ((DecimalFormat) numberFormat).applyPattern(format);
058: return numberFormat;
059: }
060:
061: }
062:
063: protected ThreadSafeFormat.FormatterFactory doCreateFormatterFactory() {
064: return new AbstractNumberConverter.NumberFormatter();
065: }
066:
067: protected abstract Object defaultFromString(String str,
068: ResourcePropertyMapping resourcePropertyMapping);
069:
070: protected abstract Object fromNumber(Number number);
071:
072: protected Object doFromString(String str,
073: ResourcePropertyMapping resourcePropertyMapping,
074: MarshallingContext context) throws ConversionException {
075: if (hasFormatter) {
076: for (int i = 0; i < formatters.length; i++) {
077: try {
078: return fromNumber((Number) formatters[i].parse(str));
079: } catch (ParseException e) {
080: // do nothing, continue to the next one
081: }
082: }
083: throw new ConversionException("Failed to parse date ["
084: + str + "]");
085: } else {
086: return defaultFromString(str, resourcePropertyMapping);
087: }
088: }
089:
090: protected String doToString(Object o,
091: ResourcePropertyMapping resourcePropertyMapping,
092: MarshallingContext context) {
093: if (hasFormatter) {
094: return formatters[0].format(o);
095: } else {
096: return defaultToString(o, resourcePropertyMapping, context);
097: }
098: }
099:
100: protected String defaultToString(Object o,
101: ResourcePropertyMapping resourcePropertyMapping,
102: MarshallingContext context) {
103: return super.doToString(o, resourcePropertyMapping, context);
104: }
105: }
|