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.activemq.util;
018    
019    import java.util.Date;
020    import java.util.HashMap;
021    
022    import org.apache.activemq.command.ActiveMQDestination;
023    
024    public final class TypeConversionSupport {
025    
026        static class ConversionKey {
027            final Class from;
028            final Class to;
029            final int hashCode;
030    
031            public ConversionKey(Class from, Class to) {
032                this.from = from;
033                this.to = to;
034                this.hashCode = from.hashCode() ^ (to.hashCode() << 1);
035            }
036    
037            public boolean equals(Object o) {
038                ConversionKey x = (ConversionKey)o;
039                return x.from == from && x.to == to;
040            }
041    
042            public int hashCode() {
043                return hashCode;
044            }
045        }
046    
047        interface Converter {
048            Object convert(Object value);
049        }
050    
051        private static final HashMap<ConversionKey, Converter> CONVERSION_MAP = new HashMap<ConversionKey, Converter>();
052        static {
053            Converter toStringConverter = new Converter() {
054                public Object convert(Object value) {
055                    return value.toString();
056                }
057            };
058            CONVERSION_MAP.put(new ConversionKey(Boolean.class, String.class), toStringConverter);
059            CONVERSION_MAP.put(new ConversionKey(Byte.class, String.class), toStringConverter);
060            CONVERSION_MAP.put(new ConversionKey(Short.class, String.class), toStringConverter);
061            CONVERSION_MAP.put(new ConversionKey(Integer.class, String.class), toStringConverter);
062            CONVERSION_MAP.put(new ConversionKey(Long.class, String.class), toStringConverter);
063            CONVERSION_MAP.put(new ConversionKey(Float.class, String.class), toStringConverter);
064            CONVERSION_MAP.put(new ConversionKey(Double.class, String.class), toStringConverter);
065    
066            CONVERSION_MAP.put(new ConversionKey(String.class, Boolean.class), new Converter() {
067                public Object convert(Object value) {
068                    return Boolean.valueOf((String)value);
069                }
070            });
071            CONVERSION_MAP.put(new ConversionKey(String.class, Byte.class), new Converter() {
072                public Object convert(Object value) {
073                    return Byte.valueOf((String)value);
074                }
075            });
076            CONVERSION_MAP.put(new ConversionKey(String.class, Short.class), new Converter() {
077                public Object convert(Object value) {
078                    return Short.valueOf((String)value);
079                }
080            });
081            CONVERSION_MAP.put(new ConversionKey(String.class, Integer.class), new Converter() {
082                public Object convert(Object value) {
083                    return Integer.valueOf((String)value);
084                }
085            });
086            CONVERSION_MAP.put(new ConversionKey(String.class, Long.class), new Converter() {
087                public Object convert(Object value) {
088                    return Long.valueOf((String)value);
089                }
090            });
091            CONVERSION_MAP.put(new ConversionKey(String.class, Float.class), new Converter() {
092                public Object convert(Object value) {
093                    return Float.valueOf((String)value);
094                }
095            });
096            CONVERSION_MAP.put(new ConversionKey(String.class, Double.class), new Converter() {
097                public Object convert(Object value) {
098                    return Double.valueOf((String)value);
099                }
100            });
101    
102            Converter longConverter = new Converter() {
103                public Object convert(Object value) {
104                    return Long.valueOf(((Number)value).longValue());
105                }
106            };
107            CONVERSION_MAP.put(new ConversionKey(Byte.class, Long.class), longConverter);
108            CONVERSION_MAP.put(new ConversionKey(Short.class, Long.class), longConverter);
109            CONVERSION_MAP.put(new ConversionKey(Integer.class, Long.class), longConverter);
110            CONVERSION_MAP.put(new ConversionKey(Date.class, Long.class), new Converter() {
111                public Object convert(Object value) {
112                    return Long.valueOf(((Date)value).getTime());
113                }
114            });
115    
116            Converter intConverter = new Converter() {
117                public Object convert(Object value) {
118                    return Integer.valueOf(((Number)value).intValue());
119                }
120            };
121            CONVERSION_MAP.put(new ConversionKey(Byte.class, Integer.class), intConverter);
122            CONVERSION_MAP.put(new ConversionKey(Short.class, Integer.class), intConverter);
123    
124            CONVERSION_MAP.put(new ConversionKey(Byte.class, Short.class), new Converter() {
125                public Object convert(Object value) {
126                    return Short.valueOf(((Number)value).shortValue());
127                }
128            });
129    
130            CONVERSION_MAP.put(new ConversionKey(Float.class, Double.class), new Converter() {
131                public Object convert(Object value) {
132                    return new Double(((Number)value).doubleValue());
133                }
134            });
135            CONVERSION_MAP.put(new ConversionKey(String.class, ActiveMQDestination.class), new Converter() {
136                public Object convert(Object value) {
137                    return ActiveMQDestination.createDestination((String)value, ActiveMQDestination.QUEUE_TYPE);
138                }
139            });
140        }
141    
142        private TypeConversionSupport() {
143        }
144    
145        public static Object convert(Object value, Class clazz) {
146    
147            assert value != null && clazz != null;
148    
149            if (value.getClass() == clazz) {
150                return value;
151            }
152    
153            Converter c = CONVERSION_MAP.get(new ConversionKey(value.getClass(), clazz));
154            if (c == null) {
155                return null;
156            }
157            return c.convert(value);
158    
159        }
160    
161    }