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