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