1 package org.andromda.core.metafacade;
2
3 import java.io.Serializable;
4 import java.net.URL;
5 import java.util.ArrayList;
6 import java.util.Arrays;
7 import java.util.Collection;
8 import java.util.LinkedHashMap;
9 import java.util.List;
10 import java.util.Map;
11 import org.andromda.core.common.ClassUtils;
12 import org.andromda.core.common.Constants;
13 import org.andromda.core.common.ExceptionUtils;
14 import org.andromda.core.common.ResourceUtils;
15 import org.andromda.core.configuration.Namespaces;
16 import org.andromda.core.namespace.NamespaceRegistry;
17 import org.apache.commons.lang.StringUtils;
18
19
20
21
22
23
24
25
26
27 public class MetafacadeImpls
28 implements Serializable
29 {
30 private static final long serialVersionUID = 34L;
31
32
33
34
35 private static final MetafacadeImpls instance = new MetafacadeImpls();
36
37
38
39
40 private final Map<String, MetafacadeClasses> metafacadeClasses = new LinkedHashMap<String, MetafacadeClasses>();
41
42
43
44
45
46
47 public static MetafacadeImpls instance()
48 {
49 return instance;
50 }
51
52
53
54
55 private String metafacadeModelNamespace;
56
57
58
59
60
61
62
63 public void setMetafacadeModelNamespace(final String metafacadeModelNamespace)
64 {
65 this.metafacadeModelNamespace = metafacadeModelNamespace;
66 }
67
68
69
70
71 private static final String METAFACADE_IMPLEMENTATION_SUFFIX =
72 MetafacadeConstants.METAFACADE_IMPLEMENTATION_SUFFIX + ClassUtils.CLASS_EXTENSION;
73
74
75
76
77
78
79
80
81
82 public void discover(final String[] metafacadeModelNamespaces)
83 {
84 ExceptionUtils.checkNull(
85 "modelTypes",
86 metafacadeModelNamespaces);
87 final List<String> modelNamespaces = new ArrayList<String>(Arrays.asList(metafacadeModelNamespaces));
88 for (final String modelNamespace : metafacadeModelNamespaces)
89 {
90 if (modelNamespace != null)
91 {
92
93
94 modelNamespaces.remove(modelNamespace);
95
96 MetafacadeClasses metafacadeClasses = this.metafacadeClasses.get(modelNamespace);
97 if (metafacadeClasses == null)
98 {
99 metafacadeClasses = new MetafacadeClasses();
100 this.metafacadeClasses.put(
101 modelNamespace,
102 metafacadeClasses);
103 }
104 metafacadeClasses.clear();
105 try
106 {
107 final Namespaces namespacesConfiguration = Namespaces.instance();
108 for (final NamespaceRegistry namespaceRegistry : namespacesConfiguration.getNamespaceRegistries())
109 {
110 final String namespaceRegistryName = namespaceRegistry.getName();
111 if (!modelNamespaces.contains(namespaceRegistryName))
112 {
113 this.registerMetafacadeClasses(
114 metafacadeClasses,
115 namespacesConfiguration,
116 namespaceRegistry);
117 }
118 }
119 }
120 catch (final Throwable throwable)
121 {
122 throw new MetafacadeImplsException(throwable);
123 }
124
125
126 modelNamespaces.add(modelNamespace);
127 }
128 }
129 }
130
131
132
133
134
135
136
137
138 private void registerMetafacadeClasses(
139 final MetafacadeClasses metafacadeClasses,
140 final Namespaces namespaces,
141 final NamespaceRegistry namespaceRegistry)
142 {
143 final String namespaceRegistryName = namespaceRegistry.getName();
144 if (namespaces.isComponentPresent(
145 namespaceRegistryName,
146 Constants.COMPONENT_METAFACADES))
147 {
148 final URL[] namespaceRoots = namespaceRegistry.getResourceRoots();
149 if (namespaceRoots != null && namespaceRoots.length > 0)
150 {
151 for (final URL namespaceRoot : namespaceRoots)
152 {
153 final Collection<String> contents = ResourceUtils.getDirectoryContents(
154 namespaceRoot,
155 false,
156 null);
157 for (final String path : contents)
158 {
159 if (path.endsWith(METAFACADE_IMPLEMENTATION_SUFFIX))
160 {
161 final String typeName =
162 StringUtils.replace(
163 ResourceUtils.normalizePath(path).replace(
164 '/',
165 '.'),
166 ClassUtils.CLASS_EXTENSION,
167 "");
168 Class implementationClass = null;
169 try
170 {
171 implementationClass = ClassUtils.loadClass(typeName);
172 }
173 catch (final Exception exception)
174 {
175
176 }
177 if (implementationClass != null &&
178 MetafacadeBase.class.isAssignableFrom(implementationClass))
179 {
180 final List<Class> allInterfaces = ClassUtils.getInterfaces(implementationClass);
181 if (!allInterfaces.isEmpty())
182 {
183 final Class interfaceClass = allInterfaces.iterator().next();
184 final String implementationClassName = implementationClass.getName();
185 final String interfaceClassName = interfaceClass.getName();
186 metafacadeClasses.metafacadesByImpls.put(
187 implementationClassName,
188 interfaceClassName);
189 metafacadeClasses.implsByMetafacades.put(
190 interfaceClassName,
191 implementationClassName);
192 }
193 }
194 }
195 }
196 }
197 }
198 }
199 }
200
201
202
203
204
205
206
207 private MetafacadeClasses getMetafacadeClasses()
208 {
209 final MetafacadeClasses classes = this.metafacadeClasses.get(this.metafacadeModelNamespace);
210 if (classes == null)
211 {
212 throw new MetafacadeImplsException("Namespace '" + this.metafacadeModelNamespace + "' is not a registered metafacade model facade namespace");
213 }
214 return classes;
215 }
216
217
218
219
220
221
222
223
224 public Class getMetafacadeClass(final String metafacadeImplClass)
225 {
226 ExceptionUtils.checkEmpty(
227 "metafacadeImplClass",
228 metafacadeImplClass);
229 return this.getMetafacadeClasses().getMetafacadeClass(metafacadeImplClass);
230 }
231
232
233
234
235
236
237
238
239
240 public Class getMetafacadeImplClass(final String metafacadeClass)
241 {
242 ExceptionUtils.checkEmpty(
243 "metafacadeClass",
244 metafacadeClass);
245 return this.getMetafacadeClasses().getMetafacadeImplClass(metafacadeClass);
246 }
247
248
249
250
251 static final class MetafacadeClasses
252 {
253
254
255
256 Map<String, String> implsByMetafacades = new LinkedHashMap<String, String>();
257
258
259
260
261 Map<String, String> metafacadesByImpls = new LinkedHashMap<String, String>();
262
263
264
265
266
267
268
269
270 Class getMetafacadeClass(final String metafacadeImplClass)
271 {
272 ExceptionUtils.checkEmpty(
273 "metafacadeImplClass",
274 metafacadeImplClass);
275 Class metafacadeClass = null;
276 try
277 {
278 final String metafacadeClassName = this.metafacadesByImpls.get(metafacadeImplClass);
279 if (StringUtils.isEmpty(metafacadeClassName))
280 {
281 throw new MetafacadeImplsException("Can not find a metafacade interface for --> '" +
282 metafacadeImplClass + "', check your classpath");
283 }
284 metafacadeClass = ClassUtils.loadClass(metafacadeClassName);
285 }
286 catch (final Throwable throwable)
287 {
288 throw new MetafacadeImplsException(throwable);
289 }
290 return metafacadeClass;
291 }
292
293
294
295
296
297
298
299
300
301 Class getMetafacadeImplClass(final String metafacadeClass)
302 {
303 ExceptionUtils.checkEmpty(
304 "metafacadeClass",
305 metafacadeClass);
306 Class metafacadeImplementationClass = null;
307 try
308 {
309 final String metafacadeImplementationClassName = this.implsByMetafacades.get(metafacadeClass);
310 if (StringUtils.isEmpty(metafacadeImplementationClassName))
311 {
312 throw new MetafacadeImplsException("Can not find a metafacade implementation class for --> '" +
313 metafacadeClass + "' check your classpath");
314 }
315 metafacadeImplementationClass = ClassUtils.loadClass(metafacadeImplementationClassName);
316 }
317 catch (final Throwable throwable)
318 {
319 throw new MetafacadeImplsException(throwable);
320 }
321 return metafacadeImplementationClass;
322 }
323
324
325
326
327 void clear()
328 {
329 this.metafacadesByImpls.clear();
330 this.implsByMetafacades.clear();
331 }
332
333
334
335
336 public String toString()
337 {
338 return super.toString() + '[' + this.metafacadesByImpls + ']';
339 }
340 }
341 }