001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.wicket.util.convert;
018:
019: import java.lang.ref.WeakReference;
020: import java.util.Date;
021: import java.util.HashMap;
022: import java.util.Locale;
023: import java.util.Map;
024:
025: import org.apache.wicket.IConverterLocator;
026: import org.apache.wicket.util.convert.converters.BooleanConverter;
027: import org.apache.wicket.util.convert.converters.ByteConverter;
028: import org.apache.wicket.util.convert.converters.CharacterConverter;
029: import org.apache.wicket.util.convert.converters.DateConverter;
030: import org.apache.wicket.util.convert.converters.DoubleConverter;
031: import org.apache.wicket.util.convert.converters.FloatConverter;
032: import org.apache.wicket.util.convert.converters.IntegerConverter;
033: import org.apache.wicket.util.convert.converters.LongConverter;
034: import org.apache.wicket.util.convert.converters.ShortConverter;
035: import org.apache.wicket.util.convert.converters.SqlDateConverter;
036: import org.apache.wicket.util.convert.converters.SqlTimeConverter;
037: import org.apache.wicket.util.convert.converters.SqlTimestampConverter;
038: import org.apache.wicket.util.lang.Objects;
039:
040: /**
041: * Implementation of {@link IConverterLocator} interface, which locates
042: * converters for a given type. It serves as a registry for {@link IConverter}
043: * instances stored by type, and is the default locator for Wicket.
044: *
045: * @see IConverterLocatorFactory
046: * @author Eelco Hillenius
047: * @author Jonathan Locke
048: */
049: public class ConverterLocator implements IConverterLocator {
050: /**
051: * CoverterLocator that is to be used when no registered converter is found.
052: */
053: private class DefaultConverter implements IConverter {
054: private static final long serialVersionUID = 1L;
055:
056: private final WeakReference/*<Class<?>>*/type;
057:
058: /**
059: * Construct.
060: *
061: * @param type
062: */
063: public DefaultConverter(Class/* ? */type) {
064: this .type = new WeakReference(type);
065: }
066:
067: /**
068: * @see org.apache.wicket.util.convert.IConverter#convertToObject(java.lang.String,
069: * java.util.Locale)
070: */
071: public Object convertToObject(String value, Locale locale) {
072: if (value == null) {
073: return null;
074: }
075: if ("".equals(value)) {
076: if (((Class) type.get()) == String.class) {
077: return "";
078: }
079: return null;
080: }
081:
082: try {
083: return Objects.convertValue(value, (Class) type.get());
084: } catch (Exception e) {
085: throw new ConversionException(e.getMessage(), e)
086: .setSourceValue(value);
087: }
088: }
089:
090: /**
091: * @see org.apache.wicket.util.convert.IConverter#convertToString(java.lang.Object,
092: * java.util.Locale)
093: */
094: public String convertToString(Object value, Locale locale) {
095: if (value == null || "".equals(value)) {
096: return "";
097: }
098:
099: return (String) Objects.convertValue(value, String.class);
100: }
101: }
102:
103: private static final long serialVersionUID = 1L;
104:
105: /** Maps Classes to ITypeConverters. */
106: private final Map/* String, IConverter */classToConverter = new HashMap/* String, IConverter */();
107:
108: /**
109: * Constructor
110: */
111: public ConverterLocator() {
112: set(Boolean.TYPE, BooleanConverter.INSTANCE);
113: set(Boolean.class, BooleanConverter.INSTANCE);
114: set(Byte.TYPE, ByteConverter.INSTANCE);
115: set(Byte.class, ByteConverter.INSTANCE);
116: set(Character.TYPE, CharacterConverter.INSTANCE);
117: set(Character.class, CharacterConverter.INSTANCE);
118: set(Double.TYPE, DoubleConverter.INSTANCE);
119: set(Double.class, DoubleConverter.INSTANCE);
120: set(Float.TYPE, FloatConverter.INSTANCE);
121: set(Float.class, FloatConverter.INSTANCE);
122: set(Integer.TYPE, IntegerConverter.INSTANCE);
123: set(Integer.class, IntegerConverter.INSTANCE);
124: set(Long.TYPE, LongConverter.INSTANCE);
125: set(Long.class, LongConverter.INSTANCE);
126: set(Short.TYPE, ShortConverter.INSTANCE);
127: set(Short.class, ShortConverter.INSTANCE);
128: set(Date.class, new DateConverter());
129: set(java.sql.Date.class, new SqlDateConverter());
130: set(java.sql.Time.class, new SqlTimeConverter());
131: set(java.sql.Timestamp.class, new SqlTimestampConverter());
132: }
133:
134: /**
135: * Gets the type converter that is registered for class c.
136: *
137: * @param c
138: * The class to get the type converter for
139: * @return The type converter that is registered for class c or null if no
140: * type converter was registered for class c
141: */
142: public final IConverter get(Class/* ? */c) {
143: return (IConverter) classToConverter.get(c.getName());
144: }
145:
146: /**
147: * Converts the given value to class c.
148: *
149: * @param type
150: * Class to get the converter for.
151: *
152: * @return The converter for the given type
153: *
154: * @see org.apache.wicket.util.convert.IConverter#convert(java.lang.Object,
155: * java.lang.Class, Locale)
156: */
157: public final IConverter getConverter(Class type) {
158: // Null is always converted to null
159: if (type == null) {
160: return new DefaultConverter(String.class);
161: }
162:
163: // Get type converter for class
164: final IConverter converter = get(type);
165: if (converter == null) {
166: return new DefaultConverter(type);
167: }
168: return converter;
169: }
170:
171: /**
172: * Removes the type converter currently registered for class c.
173: *
174: * @param c
175: * The class for which the converter registration should be
176: * removed
177: * @return The converter that was registered for class c before removal or
178: * null if none was registered
179: */
180: public final IConverter remove(Class/* ? */c) {
181: return (IConverter) classToConverter.remove(c.getName());
182: }
183:
184: /**
185: * Registers a converter for use with class c.
186: *
187: * @param converter
188: * The converter to add
189: * @param c
190: * The class for which the converter should be used
191: * @return The previous registered converter for class c or null if none was
192: * registered yet for class c
193: */
194: public final IConverter set(final Class/* ? */c,
195: final IConverter converter) {
196: if (converter == null) {
197: throw new IllegalArgumentException(
198: "CoverterLocator cannot be null");
199: }
200: if (c == null) {
201: throw new IllegalArgumentException("Class cannot be null");
202: }
203: return (IConverter) classToConverter
204: .put(c.getName(), converter);
205: }
206: }
|