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