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