1
2
3
4
5
6
7 package org.mule.transformer;
8
9 import org.mule.api.transformer.DataType;
10 import org.mule.api.transformer.DiscoverableTransformer;
11 import org.mule.api.transformer.Transformer;
12
13 import java.util.List;
14
15 import org.apache.commons.beanutils.MethodUtils;
16
17
18
19
20
21
22 public class TransformerWeighting implements Comparable
23 {
24 private Transformer transformer;
25 private int inputWeighting;
26 private int outputWeighting;
27 private Class inputClass;
28 private Class outputClass;
29
30 public TransformerWeighting(Class inputClass, Class outputClass, Transformer transformer)
31 {
32 this.inputClass = inputClass;
33 this.outputClass = outputClass;
34 this.transformer = transformer;
35 init();
36 }
37
38 private void init()
39 {
40 inputWeighting = Integer.MAX_VALUE;
41 List<DataType<?>> sourceTypes = transformer.getSourceDataTypes();
42
43 for (DataType type : sourceTypes)
44 {
45 int weighting = getWeighting(-1, inputClass, type.getType());
46 if (weighting < inputWeighting && weighting != -1)
47 {
48 inputWeighting = weighting;
49 }
50 }
51
52 outputWeighting = getWeighting(-1, outputClass, transformer.getReturnClass());
53
54 inputWeighting = (inputWeighting == Integer.MAX_VALUE ? -1 : inputWeighting);
55 outputWeighting = (outputWeighting == Integer.MAX_VALUE ? -1 : outputWeighting);
56
57 }
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74 protected int getWeighting(int weighting, Class src, Class dest)
75 {
76 if (!dest.isAssignableFrom(src))
77 {
78 if (src.isPrimitive())
79 {
80 return getWeighting(weighting, MethodUtils.getPrimitiveWrapper(src), dest);
81 }
82
83 return -1;
84 }
85
86 if (dest.equals(src))
87 {
88 if (dest.equals(Object.class))
89 {
90 return weighting + 3;
91 }
92 else
93 {
94 return weighting + 1;
95 }
96 }
97
98 if (dest.isInterface() && src.getInterfaces().length > 0)
99 {
100 for (int i = 0; i < src.getInterfaces().length; i++)
101 {
102 Class aClass = src.getInterfaces()[i];
103 if (dest.equals(aClass))
104 {
105 return weighting + 2;
106 }
107 }
108 }
109
110 if (src.getSuperclass() != null)
111 {
112 return getWeighting(weighting + 1, src.getSuperclass(), dest);
113 }
114
115 return -1;
116 }
117
118 public Class getInputClass()
119 {
120 return inputClass;
121 }
122
123 public int getInputWeighting()
124 {
125 return inputWeighting;
126 }
127
128 public Class getOutputClass()
129 {
130 return outputClass;
131 }
132
133 public int getOutputWeighting()
134 {
135 return outputWeighting;
136 }
137
138 public Transformer getTransformer()
139 {
140 return transformer;
141 }
142
143 public boolean isExactMatch()
144 {
145 return inputWeighting == 0 && outputWeighting == 0;
146 }
147
148 public boolean isNotMatch()
149 {
150 return inputWeighting == -1 || outputWeighting == -1;
151 }
152
153 public int compareTo(Object o)
154 {
155 TransformerWeighting weighting = (TransformerWeighting) o;
156 if (weighting.getInputWeighting() == getInputWeighting() &&
157 weighting.getOutputWeighting() == getOutputWeighting())
158 {
159
160
161 if (weighting.getTransformer() instanceof DiscoverableTransformer
162 && this.getTransformer() instanceof DiscoverableTransformer)
163 {
164 int x = ((DiscoverableTransformer) weighting.getTransformer()).getPriorityWeighting();
165 int y = ((DiscoverableTransformer) this.getTransformer()).getPriorityWeighting();
166 if (x > y)
167 {
168 return -1;
169 }
170 if (x < y)
171 {
172 return 1;
173 }
174 return 0;
175 }
176 else
177 {
178 return 0;
179 }
180 }
181 else
182 {
183 if (isNotMatch())
184 {
185 return -1;
186 }
187 else if (weighting.isNotMatch() && !isNotMatch())
188 {
189 return 1;
190 }
191 else if (weighting.isExactMatch() && !isExactMatch())
192 {
193 return -1;
194 }
195 else if (weighting.getInputWeighting() < getInputWeighting() &&
196 weighting.getOutputWeighting() < getOutputWeighting())
197 {
198 return -1;
199 }
200
201 else if (weighting.getInputWeighting() == getInputWeighting() &&
202 weighting.getOutputWeighting() < getOutputWeighting())
203 {
204 return -1;
205 }
206
207 else if (weighting.getInputWeighting() < getInputWeighting() &&
208 weighting.getOutputWeighting() == getOutputWeighting())
209 {
210 return -1;
211 }
212 return 1;
213 }
214 }
215
216 public boolean equals(Object o)
217 {
218 if (this == o)
219 {
220 return true;
221 }
222 if (o == null || getClass() != o.getClass())
223 {
224 return false;
225 }
226
227 TransformerWeighting that = (TransformerWeighting) o;
228
229 if (inputClass != null ? !inputClass.equals(that.inputClass) : that.inputClass != null)
230 {
231 return false;
232 }
233 if (outputClass != null ? !outputClass.equals(that.outputClass) : that.outputClass != null)
234 {
235 return false;
236 }
237
238 return true;
239 }
240
241 public int hashCode()
242 {
243 int result;
244 result = (transformer != null ? transformer.hashCode() : 0);
245 result = 31 * result + inputWeighting;
246 result = 31 * result + outputWeighting;
247 result = 31 * result + (inputClass != null ? inputClass.hashCode() : 0);
248 result = 31 * result + (outputClass != null ? outputClass.hashCode() : 0);
249 return result;
250 }
251
252
253 public String toString()
254 {
255 final StringBuffer sb = new StringBuffer();
256 sb.append("TransformerWeighting");
257 sb.append("{inputClass=").append(inputClass);
258 sb.append(", inputWeighting=").append(inputWeighting);
259 sb.append(", outputClass=").append(outputClass);
260 sb.append(", outputWeighting=").append(outputWeighting);
261 sb.append(", transformer=").append(transformer.getName());
262 sb.append('}');
263 return sb.toString();
264 }
265 }