1 package org.andromda.cartridges.meta.metafacades;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.Collections;
6 import java.util.Comparator;
7 import java.util.HashMap;
8 import java.util.LinkedHashSet;
9 import java.util.List;
10 import java.util.Map;
11 import java.util.Set;
12 import org.andromda.cartridges.meta.MetaProfile;
13 import org.andromda.core.metafacade.MetafacadeException;
14 import org.andromda.metafacades.uml.AssociationEndFacade;
15 import org.andromda.metafacades.uml.AttributeFacade;
16 import org.andromda.metafacades.uml.ClassifierFacade;
17 import org.andromda.metafacades.uml.DependencyFacade;
18 import org.andromda.metafacades.uml.GeneralizableElementFacade;
19 import org.andromda.metafacades.uml.GeneralizationFacade;
20 import org.andromda.metafacades.uml.ModelElementFacade;
21 import org.andromda.metafacades.uml.OperationFacade;
22 import org.apache.commons.collections.CollectionUtils;
23 import org.apache.commons.collections.Predicate;
24 import org.apache.commons.collections.Transformer;
25 import org.apache.commons.lang.ObjectUtils;
26 import org.apache.commons.lang.StringUtils;
27 import org.apache.log4j.Logger;
28
29
30
31
32
33
34
35 public class MetafacadeLogicImpl
36 extends MetafacadeLogic
37 {
38 private static final long serialVersionUID = 34L;
39
40
41
42
43
44
45
46 private static final String METAMODEL_VERSION_PACKAGE = "metamodelVersionPackage";
47 private Map<ClassifierFacade, Collection<MethodData>> featureMap = null;
48
49
50
51 private static final Logger logger = Logger.getLogger(MetafacadeLogicImpl.class);
52
53
54
55
56
57 public MetafacadeLogicImpl(
58 Object metaObjectIn,
59 String context)
60 {
61 super(metaObjectIn, context);
62 }
63
64
65
66
67
68
69
70
71 @Override
72 protected ClassifierFacade handleGetMetaclass()
73 {
74
75 return getMetaclass(this);
76 }
77
78
79
80
81
82
83
84
85 private ClassifierFacade getMetaclass(ClassifierFacade classifier)
86 {
87 for (DependencyFacade dep : classifier.getSourceDependencies())
88 {
89 ClassifierFacade target = (ClassifierFacade)dep.getTargetElement();
90 Collection<String> stereotypes = target.getStereotypeNames();
91 if ((stereotypes != null) && (!stereotypes.isEmpty()))
92 {
93 String stereotypeName = stereotypes.iterator().next();
94 if (stereotypeName.equals(MetaProfile.STEREOTYPE_METACLASS))
95 {
96 return target;
97 }
98 }
99 }
100
101 ClassifierFacade superclass = (ClassifierFacade)classifier.getGeneralization();
102 return (superclass != null) ? getMetaclass(superclass) : null;
103 }
104
105
106
107
108 @Override
109 protected boolean handleIsMetaclassDirectDependency()
110 {
111 boolean isMetaClassDirectDependency = false;
112 Collection<DependencyFacade> dependencies = this.getSourceDependencies();
113 if ((dependencies != null) && !dependencies.isEmpty())
114 {
115
116 DependencyFacade dependency = dependencies.iterator().next();
117 if (dependency != null)
118 {
119 ModelElementFacade targetElement = dependency.getTargetElement();
120 if (targetElement != null)
121 {
122 isMetaClassDirectDependency = targetElement.hasStereotype(MetaProfile.STEREOTYPE_METACLASS);
123 }
124 }
125 }
126 return isMetaClassDirectDependency;
127 }
128
129
130
131
132 @Override
133 protected String handleGetLogicName()
134 {
135 return this.getName() + "Logic";
136 }
137
138
139
140
141 @Override
142 protected String handleGetLogicImplName()
143 {
144 return this.getName() + "LogicImpl";
145 }
146
147
148
149
150 @Override
151 protected String handleGetFullyQualifiedLogicImplName()
152 {
153 return this.getMetafacadeSupportClassName(this.getLogicImplName());
154 }
155
156
157
158
159 @Override
160 protected String handleGetFullyQualifiedLogicName()
161 {
162 return this.getMetafacadeSupportClassName(this.getLogicName());
163 }
164
165
166
167
168 @Override
169 protected String handleGetLogicFile()
170 {
171 return this.getFullyQualifiedLogicName().replace('.', '/') + ".java";
172 }
173
174
175
176
177
178
179
180
181 private String getMetaModelVersionPackage()
182 {
183 return ObjectUtils.toString(this.getConfiguredProperty(METAMODEL_VERSION_PACKAGE));
184 }
185
186
187
188
189 @Override
190 protected String handleGetLogicPackageName()
191 {
192 String packageName = this.getMetaModelVersionPackage();
193 if (StringUtils.isEmpty(packageName))
194 {
195 packageName = this.getPackageName();
196 }
197 return packageName;
198 }
199
200
201
202
203 @Override
204 protected String handleGetLogicImplFile()
205 {
206 return this.getFullyQualifiedLogicImplName().replace('.', '/') + ".java";
207 }
208
209
210
211
212
213
214
215
216
217 private String getMetafacadeSupportClassName(String name)
218 {
219 StringBuilder fullyQualifiedName = new StringBuilder(this.getLogicPackageName());
220 if (StringUtils.isNotBlank(fullyQualifiedName.toString()))
221 {
222 fullyQualifiedName.append('.');
223 fullyQualifiedName.append(name);
224 }
225 return fullyQualifiedName.toString();
226 }
227
228
229
230
231 @Override
232 protected Collection<MethodData> handleGetMethodDataForPSM(ClassifierFacade facade)
233 {
234 return this.getMethodDataForPSM(facade, true);
235 }
236
237
238
239
240 @Override
241 protected Collection<MethodData> handleGetMethodDataForPSM()
242 {
243 return this.getMethodDataForPSM(null, false);
244 }
245
246
247
248
249
250 private final Collection<MethodData> getMethodDataForPSM(
251 final ClassifierFacade facade,
252 final boolean includeSuperclasses)
253 {
254 try
255 {
256 final Set<String> declarationSet = new LinkedHashSet<String>();
257 if (this.featureMap == null)
258 {
259 this.featureMap = new HashMap<ClassifierFacade, Collection<MethodData>>();
260 if (includeSuperclasses && this.getGeneralizations() != null)
261 {
262 for (GeneralizableElementFacade general : this.getGeneralizations())
263 {
264 final Map<String, MethodData> methodDataMap = new HashMap<String, MethodData>();
265 final ClassifierFacade metafacade = (ClassifierFacade)general;
266 for (ClassifierFacade classifier = metafacade; classifier instanceof Metafacade;
267 classifier = (ClassifierFacade)classifier.getGeneralization())
268 {
269 this.getAllFeatures(methodDataMap, declarationSet, (Metafacade)classifier);
270 }
271 this.featureMap.put(metafacade, methodDataMap.values());
272 }
273 }
274 }
275 final List<MethodData> result = new ArrayList<MethodData>();
276 if (this.featureMap != null)
277 {
278 Collection<MethodData> features = this.featureMap.get(facade);
279 if (features != null)
280 {
281 result.addAll(features);
282 }
283 }
284 if (!includeSuperclasses)
285 {
286 final Map<String, MethodData> methodDataMap = new HashMap<String, MethodData>();
287 this.getAllFeatures(methodDataMap, declarationSet, this);
288 result.addAll(methodDataMap.values());
289 }
290 Collections.sort(result);
291 return result;
292 }
293 catch (Throwable th)
294 {
295 throw new RuntimeException(th);
296 }
297 }
298
299
300
301
302
303
304
305 private final void getAllFeatures(
306 final Map<String, MethodData> methodDataMap,
307 final Set<String> declarationSet,
308 final Metafacade facade)
309 {
310 try
311 {
312 final String methodVisibility = "public";
313 final String indendation = " * ";
314 final String fullyQualifiedName = facade.getFullyQualifiedName();
315
316
317 for (final Object obj : facade.getProperties())
318 {
319 final ModelElementFacade property = (ModelElementFacade)obj;
320 MethodData method = null;
321 if (property instanceof AttributeFacade)
322 {
323 final AttributeFacade attribute = (AttributeFacade)property;
324 method =
325 new MethodData(
326 fullyQualifiedName,
327 methodVisibility,
328 false,
329 attribute.getGetterSetterTypeName(),
330 attribute.getGetterName(),
331 attribute.getDocumentation(indendation));
332 }
333 else
334 {
335 final AssociationEndFacade association = (AssociationEndFacade)property;
336 method =
337 new MethodData(
338 fullyQualifiedName,
339 methodVisibility,
340 false,
341 association.getGetterSetterTypeName(),
342 association.getGetterName(),
343 association.getDocumentation(indendation));
344 }
345 final String declaration = method.buildMethodDeclaration(true);
346
347
348
349 if (!declarationSet.contains(declaration))
350 {
351 methodDataMap.put(
352 method.buildCharacteristicKey(),
353 method);
354 declarationSet.add(declaration);
355 }
356 }
357
358
359 for (OperationFacade operation : facade.getOperations())
360 {
361 final UMLOperationData method = new UMLOperationData(fullyQualifiedName, operation);
362
363
364
365 final String declaration = method.buildMethodDeclaration(true);
366 if (!declarationSet.contains(declaration))
367 {
368 methodDataMap.put(
369 method.buildCharacteristicKey(),
370 method);
371 declarationSet.add(declaration);
372 }
373 }
374 }
375 catch (final Throwable throwable)
376 {
377 MetafacadeLogicImpl.logger.error(throwable);
378 throw new MetafacadeException(throwable);
379 }
380 }
381
382
383
384
385 @Override
386 protected boolean handleIsRequiresInheritanceDelegatation()
387 {
388 boolean requiresInheritanceDelegation = false;
389 final ModelElementFacade superMetafacade = this.getGeneralization();
390 if (superMetafacade != null)
391 {
392 requiresInheritanceDelegation =
393 !superMetafacade.getPackageName().equals(this.getPackageName()) ||
394 (this.getGeneralizations().size() > 1);
395 }
396 return requiresInheritanceDelegation;
397 }
398
399
400
401
402 @Override
403 protected boolean handleIsConstructorRequiresMetaclassCast()
404 {
405 boolean requiresCast = false;
406 final Metafacade superMetafacade = (Metafacade)this.getGeneralization();
407 if (superMetafacade != null)
408 {
409 requiresCast = superMetafacade.isMetaclassDirectDependency() && !this.isRequiresInheritanceDelegatation();
410 }
411 return requiresCast;
412 }
413
414
415
416
417 @Override
418 public Collection<GeneralizableElementFacade> getGeneralizations()
419 {
420 final List generalizations = new ArrayList(super.getGeneralizationLinks());
421 Collections.sort(
422 generalizations,
423 new GeneralizationPrecedenceComparator());
424 CollectionUtils.transform(
425 generalizations,
426 new Transformer()
427 {
428 public Object transform(final Object object)
429 {
430 return ((GeneralizationFacade)object).getParent();
431 }
432 });
433 CollectionUtils.filter(generalizations,
434 new Predicate()
435 {
436 public boolean evaluate(final Object object)
437 {
438 return object instanceof Metafacade;
439 }
440 });
441 return generalizations;
442 }
443
444
445
446
447 @Override
448 protected int handleGetGeneralizationCount()
449 {
450 int count = 0;
451 final Collection<GeneralizableElementFacade> generalizations = this.getGeneralizations();
452 if (generalizations != null)
453 {
454 count = generalizations.size();
455 }
456 return count;
457 }
458
459
460
461
462 static final class GeneralizationPrecedenceComparator
463 implements Comparator
464 {
465
466
467
468 public int compare(
469 Object objectA,
470 Object objectB)
471 {
472 MetafacadeGeneralization a = (MetafacadeGeneralization)objectA;
473 MetafacadeGeneralization b = (MetafacadeGeneralization)objectB;
474 return a.getPrecedence().compareTo(b.getPrecedence());
475 }
476 }
477
478
479
480
481 @Override
482 protected Collection<GeneralizableElementFacade> handleGetAllParents()
483 {
484 Set<GeneralizableElementFacade> allParents = new LinkedHashSet<GeneralizableElementFacade> ();
485 final Collection<GeneralizableElementFacade> parents = this.getGeneralizations();
486 allParents.addAll(parents);
487 for (Object object : parents)
488 {
489 if (object instanceof Metafacade)
490 {
491 final Metafacade metafacade = (Metafacade)object;
492 allParents.addAll(metafacade.getAllParents());
493 }
494 }
495 return allParents;
496 }
497 }