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 */
017package org.apache.wicket.core.util.lang;
018
019import java.util.Locale;
020
021import org.apache.wicket.util.io.IClusterable;
022import org.apache.wicket.IConverterLocator;
023import org.apache.wicket.util.convert.IConverter;
024import org.apache.wicket.util.lang.Objects;
025
026
027/**
028 * @author jcompagner
029 */
030public class PropertyResolverConverter implements IClusterable
031{
032        private static final long serialVersionUID = 1L;
033
034
035        private final IConverterLocator converterSupplier;
036        private final Locale locale;
037
038        /**
039         * Construct.
040         *
041         * @param converterSupplier
042         * @param locale
043         */
044        public PropertyResolverConverter(IConverterLocator converterSupplier, Locale locale)
045        {
046                this.converterSupplier = converterSupplier;
047                this.locale = locale;
048        }
049
050        /**
051         * @param <T>
052         *            target type
053         * @param object
054         * @param clz
055         * @return converted value of the type given, or null if the value cannot be converted to the
056         *         given type.
057         */
058        public <T> T convert(Object object, Class<T> clz)
059        {
060                if (object == null)
061                {
062                        return null;
063                }
064                if (clz.isAssignableFrom(object.getClass()))
065                {
066                        @SuppressWarnings("unchecked")
067                        T result = (T)object;
068                        return result;
069                }
070                IConverter<T> converter = converterSupplier.getConverter(clz);
071                if (object instanceof String)
072                {
073                        return converter.convertToObject((String)object, locale);
074                }
075                else if (clz == String.class)
076                {
077                        @SuppressWarnings("unchecked")
078                        T result = (T)convertToString(object, locale);
079                        return result;
080                }
081                else
082                {
083                        T result;
084                        try
085                        {
086                                result = Objects.convertValue(object, clz);
087                        }
088                        catch (RuntimeException ex)
089                        {
090                                result = null;
091                        }
092                        if (result == null)
093                        {
094                                String tmp = convertToString(object, locale);
095                                result = converter.convertToObject(tmp, locale);
096                        }
097                        return result;
098                }
099        }
100
101        protected <C> String convertToString(C object, Locale locale)
102        {
103                @SuppressWarnings("unchecked")
104                Class<C> type = (Class<C>)object.getClass();
105
106                IConverter<C> converterForObj = converterSupplier.getConverter(type);
107                return converterForObj.convertToString(object, locale);
108        }
109}