View Javadoc

1   /*
2    * Copyright 2004-2005, 2008 the original author or authors.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5    * use this file except in compliance with the License. You may obtain a copy of
6    * the License at
7    * 
8    * http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations under
14   * the License.
15   */
16  package net.sf.morph.transform.converters;
17  
18  import java.text.NumberFormat;
19  import java.util.Locale;
20  
21  import net.sf.morph.Defaults;
22  import net.sf.morph.transform.Converter;
23  import net.sf.morph.transform.DecoratedConverter;
24  import net.sf.morph.transform.ImpreciseTransformer;
25  import net.sf.morph.transform.transformers.BaseTransformer;
26  import net.sf.morph.util.TransformerUtils;
27  
28  /**
29   * Converts {@link java.lang.Number}s into basic text types ({@link java.lang.String},
30   * {@link java.lang.StringBuffer} or {@link java.lang.Character}).
31   * 
32   * @author Matt Sgarlata
33   * @since Jan 26, 2006
34   */
35  public class NumberToTextConverter extends BaseTransformer implements DecoratedConverter,
36  		ImpreciseTransformer {
37  
38  	private Converter textConverter;
39  	private Converter numberConverter;
40  
41  	/**
42  	 * {@inheritDoc}
43  	 */
44  	protected Object convertImpl(Class destinationClass, Object source, Locale locale) throws Exception {
45  		String formatted = getNumberFormat(locale).format(source);
46  		return getTextConverter().convert(destinationClass, formatted, locale);
47  	}
48  
49  	/**
50  	 * {@inheritDoc}
51  	 */
52  	protected Class[] getSourceClassesImpl() throws Exception {
53  		return getNumberConverter().getDestinationClasses();
54  	}
55  
56  	/**
57  	 * {@inheritDoc}
58  	 */
59  	protected Class[] getDestinationClassesImpl() throws Exception {
60  		return getTextConverter().getSourceClasses();
61  	}
62  
63  	/**
64  	 * {@inheritDoc}
65  	 */
66  	protected boolean isImpreciseTransformationImpl(Class destinationClass, Class sourceClass) {
67  		return TransformerUtils.isImpreciseTransformation(getTextConverter(), destinationClass, String.class);
68  	}
69  
70  	/**
71  	 * Get the number converter used by this NumberToTextConverter.
72  	 * @return Converter
73  	 */
74  	public Converter getNumberConverter() {
75  		if (numberConverter == null) {
76  			setNumberConverter(Defaults.createNumberConverter());
77  		}
78  		return numberConverter;
79  	}
80  
81  	/**
82  	 * Sets the <code>numberConverter</code> to be used. Note that this method
83  	 * should be called before the transformer is used. Otherwise, if another
84  	 * thread is in the middle of transforming an object graph and this method
85  	 * is called, the behavior of the transformer can change partway through the
86  	 * transformation.
87  	 * 
88  	 * @param numberConverter
89  	 *            the <code>numberConverter</code> to be used
90  	 */
91  	public synchronized void setNumberConverter(Converter numberConverter) {
92  		this.numberConverter = numberConverter;
93  	}
94  
95  	/**
96  	 * Get the text converter used by this NumberToTextConverter.
97  	 * @return Converter
98  	 */
99  	public Converter getTextConverter() {
100 		if (textConverter == null) {
101 			setTextConverter(Defaults.createTextConverter());
102 		}
103 		return textConverter;
104 	}
105 
106 	/**
107 	 * Sets the <code>textConverter</code> to be used. Note that this method
108 	 * should be called before the transformer is used. Otherwise, if another
109 	 * thread is in the middle of transforming an object graph and this method
110 	 * is called, the behavior of the transformer can change partway through the
111 	 * transformation.
112 	 * 
113 	 * @param textConverter
114 	 *            the <code>textConverter</code> to be used
115 	 */
116 	public synchronized void setTextConverter(Converter textConverter) {
117 		this.textConverter = textConverter;
118 	}
119 
120 	/**
121 	 * Retrieves the {@link NumberFormat} instance to be used to in the given
122 	 * locale to format numbers as text. Subclasses can override this method to
123 	 * customize the behavior of this converter.
124 	 * 
125 	 * @param locale
126 	 *            the locale
127 	 * @return the {@link NumberFormat} instance to be used to in the given
128 	 *         locale to format numbers as text
129 	 */
130 	protected NumberFormat getNumberFormat(Locale locale) {
131 		NumberFormat numberFormat = NumberFormat.getInstance(locale);
132 		numberFormat.setGroupingUsed(false);
133 		numberFormat.setMaximumFractionDigits(Integer.MAX_VALUE);
134 		return numberFormat;
135 	}
136 
137 	/**
138 	 * {@inheritDoc}
139 	 */
140 	protected boolean isWrappingRuntimeExceptions() {
141 	    return true;
142     }
143 
144 }