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.camel.impl;
018    
019    import java.lang.reflect.Method;
020    import java.util.ArrayList;
021    import java.util.Collections;
022    import java.util.Comparator;
023    import java.util.List;
024    
025    import org.apache.camel.TypeConverter;
026    import org.apache.camel.impl.converter.AnnotationTypeConverterLoader;
027    import org.apache.camel.impl.converter.TypeConverterRegistry;
028    import org.apache.camel.util.ObjectHelper;
029    
030    /**
031     * Type converter loader that is capable of reporting the loaded type converters.
032     * <p/>
033     * Used by the camel-maven-plugin.
034     */
035    public class ReportingTypeConverterLoader extends AnnotationTypeConverterLoader {
036    
037        private static final Comparator<TypeMapping> COMPARE_LAST_LOADED_FIRST = new Comparator<TypeMapping>() {
038            public int compare(TypeMapping t1, TypeMapping t2) {
039                if (ObjectHelper.equal(t1.fromType, t2.fromType)) {
040                    return ObjectHelper.equal(t1.toType, t2.toType) ? t1.index - t2.index : ObjectHelper
041                        .compare(getTypeName(t1.toType), getTypeName(t2.toType));
042                }
043                return ObjectHelper.compare(getTypeName(t1.fromType), getTypeName(t2.fromType));
044            }
045    
046        };
047        private List<TypeMapping> typeMappings = new ArrayList<TypeMapping>();
048    
049        public TypeMapping[] getTypeConversions() {
050            Collections.sort(typeMappings, COMPARE_LAST_LOADED_FIRST);
051            return typeMappings.toArray(new TypeMapping[typeMappings.size()]);
052        }
053    
054        protected void registerTypeConverter(TypeConverterRegistry registry, Method method, Class toType,
055                                             Class fromType, TypeConverter typeConverter) {
056    
057            TypeMapping mapping = new TypeMapping(toType, fromType, typeConverter.getClass(), method);
058            typeMappings.add(mapping);
059        }
060    
061        private static String getTypeName(Class type) {
062            return type != null ? type.getName() : null;
063        }
064    
065        /**
066         * Represents a mapping from one type (which can be null) to another
067         *
068         * Used by the camel-maven-plugin.
069         */
070        public static class TypeMapping {
071            private static int counter;
072            private Class toType;
073            private Class fromType;
074            private Class converterType;
075            private Method method;
076            private int index;
077    
078            public TypeMapping(Class toType, Class fromType, Class converterType, Method method) {
079                this.toType = toType;
080                this.fromType = fromType;
081                this.converterType = converterType;
082                this.method = method;
083                this.index = counter++;
084            }
085    
086            public Class getFromType() {
087                return fromType;
088            }
089    
090            public Class getToType() {
091                return toType;
092            }
093    
094            public Class getConverterType() {
095                return converterType;
096            }
097    
098            public Method getMethod() {
099                return method;
100            }
101    
102            public int getIndex() {
103                return index;
104            }
105    
106            @Override
107            public boolean equals(Object object) {
108                if (object instanceof TypeMapping) {
109                    TypeMapping that = (TypeMapping)object;
110                    return this.index == that.index;
111                }
112                return false;
113            }
114    
115            @Override
116            public int hashCode() {
117                int answer = toType.hashCode();
118                if (fromType != null) {
119                    answer *= 37 + fromType.hashCode();
120                }
121                return answer;
122            }
123    
124            @Override
125            public String toString() {
126                return "[" + fromType.getSimpleName() + "=>" + toType.getSimpleName() + "]";
127            }
128        }
129    
130    }