1
2
3
4
5
6
7 package org.mule.config.transformer;
8
9 import org.mule.api.MuleContext;
10 import org.mule.api.lifecycle.Disposable;
11 import org.mule.api.transformer.DataType;
12 import org.mule.transformer.types.CollectionDataType;
13 import org.mule.util.annotation.AnnotationUtils;
14
15 import java.io.IOException;
16 import java.util.Set;
17 import java.util.concurrent.CopyOnWriteArraySet;
18
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21
22
23
24
25
26
27 public abstract class AbstractAnnotatedTransformerArgumentResolver implements TransformerArgumentResolver, Disposable
28 {
29 public static final String[] ignoredPackages = {"java.", "javax.", "org.w3c.", "org.mule.transport.", "org.mule.module."};
30
31
32
33
34 protected transient final Log logger = LogFactory.getLog(getClass());
35
36
37 private Set<Class> matchingClasses = new CopyOnWriteArraySet<Class>();
38
39
40 private Set<Class> nonMatchingClasses = new CopyOnWriteArraySet<Class>();
41
42 public <T> T resolve(Class<T> type, DataType source, DataType result, MuleContext context) throws Exception
43 {
44
45
46 if(!getArgumentClass().isAssignableFrom(type) || isNonMatching(source, result))
47 {
48 return null;
49 }
50
51 Class annotatedType = (result instanceof CollectionDataType ? ((CollectionDataType)result).getItemType() : result.getType());
52
53
54 boolean isAnnotated = matchingClasses.contains(annotatedType);
55 if(!isAnnotated)
56 {
57
58 isAnnotated = findAnnotation(annotatedType);
59 }
60
61 if (!isAnnotated)
62 {
63 annotatedType = source.getType();
64
65 isAnnotated = matchingClasses.contains(annotatedType);
66 if(!isAnnotated)
67 {
68
69 isAnnotated = AnnotationUtils.hasAnnotationWithPackage(getAnnotationsPackageName(), annotatedType);
70 }
71 }
72
73 Object argument = context.getRegistry().lookupObject(getArgumentClass());
74
75 if (!isAnnotated)
76 {
77
78 nonMatchingClasses.add(source.getType());
79 nonMatchingClasses.add(result.getType());
80
81
82 return (T)argument;
83 }
84 else
85 {
86 matchingClasses.add(annotatedType);
87 }
88
89
90 if (argument == null)
91 {
92 logger.info("No common Object of type '" + getArgumentClass() + "' configured, creating a local one for: " + source + ", " + result);
93 argument = createArgument(annotatedType, context);
94 }
95 return (T)argument;
96
97 }
98
99 protected boolean findAnnotation(Class annotatedType) throws IOException
100 {
101
102 if(annotatedType.getPackage()==null)
103 {
104 return false;
105 }
106
107 for (String ignoredPackage : ignoredPackages)
108 {
109 if(annotatedType.getPackage().getName().startsWith(ignoredPackage))
110 {
111 return false;
112 }
113 }
114 return AnnotationUtils.hasAnnotationWithPackage(getAnnotationsPackageName(), annotatedType);
115 }
116
117 protected boolean isNonMatching(DataType source, DataType result)
118 {
119 return nonMatchingClasses.contains(result.getType()) && nonMatchingClasses.contains(source.getType());
120 }
121
122 public void dispose()
123 {
124 nonMatchingClasses.clear();
125 matchingClasses.clear();
126 }
127
128 public Set<Class> getMatchingClasses()
129 {
130 return matchingClasses;
131 }
132
133 public Set<Class> getNonMatchingClasses()
134 {
135 return nonMatchingClasses;
136 }
137
138
139
140
141
142 protected abstract Class<?> getArgumentClass();
143
144
145
146
147
148
149
150
151
152
153
154 protected abstract Object createArgument(Class<?> annotatedType, MuleContext muleContext) throws Exception;
155
156
157
158
159
160
161 protected abstract String getAnnotationsPackageName();
162 }