1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.nuiton.eugene.models.object.xml;
24
25 import org.apache.commons.lang3.StringUtils;
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.codehaus.plexus.component.annotations.Component;
29 import org.nuiton.eugene.ModelHelper;
30 import org.nuiton.eugene.ModelReader;
31 import org.nuiton.eugene.models.Model;
32 import org.nuiton.eugene.models.object.ObjectModel;
33 import org.nuiton.eugene.models.object.ObjectModelAttribute;
34 import org.nuiton.eugene.models.object.ObjectModelClass;
35 import org.nuiton.eugene.models.object.ObjectModelClassifier;
36 import org.nuiton.eugene.models.object.ObjectModelEnumeration;
37 import org.nuiton.eugene.models.object.ObjectModelInterface;
38 import org.nuiton.eugene.models.object.ObjectModelPackage;
39
40 import java.util.ArrayList;
41 import java.util.Collection;
42 import java.util.HashMap;
43 import java.util.Iterator;
44 import java.util.LinkedHashSet;
45 import java.util.List;
46 import java.util.Map;
47 import java.util.Set;
48
49
50
51
52
53
54
55
56
57
58
59
60 @Component(role = Model.class, hint = "objectmodel")
61 public class ObjectModelImpl implements ObjectModel {
62
63
64 private static final Log log = LogFactory.getLog(ObjectModelImpl.class);
65
66 protected String name;
67
68 protected String version;
69
70 protected Map<String, ObjectModelClass> classes = new HashMap<>();
71
72 protected Map<String, ObjectModelPackage> packages = new HashMap<>();
73
74 protected Map<String, ObjectModelInterface> interfaces = new HashMap<>();
75
76 protected Map<String, ObjectModelClassifier> classifiers = new HashMap<>();
77
78 protected Map<String, ObjectModelEnumeration> enumerations = new HashMap<>();
79
80 protected List<String> comments = new ArrayList<>();
81
82 protected Map<String, String> tagValues = new HashMap<>();
83
84
85
86
87
88 private Map<String, Object> extensions = new HashMap<>();
89
90 @Override
91 public String getModelType() {
92 return ModelHelper.ModelType.OBJECT.getAlias();
93 }
94
95 public void setName(String name) {
96 this.name = name;
97 }
98
99 public void setVersion(String version) {
100 this.version = version;
101 }
102
103 @Override
104 public String getVersion() {
105 return version;
106 }
107
108 public void addPackage(ObjectModelPackageImpl aPackage) {
109 aPackage.postInit();
110 aPackage.setObjectModelImpl(this);
111
112 if (!aPackage.isExtern()) {
113 ObjectModelPackageImpl initialElement = (ObjectModelPackageImpl)
114 packages.get(aPackage.getName());
115 if (initialElement == null) {
116 packages.put(aPackage.getName(), aPackage);
117 } else {
118
119
120
121
122 mergePackages(initialElement, aPackage);
123 }
124 }
125 }
126
127 public void addClass(ObjectModelClassImpl clazz) {
128
129
130 clazz.postInit();
131 clazz.setObjectModelImpl(this);
132
133 if (!clazz.isExtern()) {
134 ObjectModelElementImpl initialElement = (ObjectModelElementImpl)
135 classes.get(clazz.getQualifiedName());
136 if (initialElement == null) {
137 classes.put(clazz.getQualifiedName(), clazz);
138 classifiers.put(clazz.getQualifiedName(), clazz);
139 } else {
140 if (!(initialElement instanceof ObjectModelClassImpl)) {
141 throw new IllegalArgumentException(
142 "\"" + clazz + "\" is incompatible with already " +
143 "defined element \"" + initialElement + "\"");
144 }
145 ObjectModelClassImpl initialClazz =
146 (ObjectModelClassImpl) initialElement;
147
148
149
150
151 mergeClasses(initialClazz, clazz);
152
153 }
154 }
155
156 }
157
158 public void addAssociationClass(ObjectModelAssociationClassImpl clazz) {
159
160
161 clazz.postInit();
162 clazz.setObjectModelImpl(this);
163
164 if (!clazz.isExtern()) {
165 ObjectModelElementImpl initialElement = (ObjectModelElementImpl)
166 classes.get(clazz.getQualifiedName());
167 if (initialElement == null) {
168 classes.put(clazz.getQualifiedName(), clazz);
169 classifiers.put(clazz.getQualifiedName(), clazz);
170 } else {
171 if (!(initialElement instanceof ObjectModelAssociationClassImpl)) {
172 throw new IllegalArgumentException(
173 "\"" + clazz + "\" is incompatible with " +
174 "already defined element \"" + initialElement +
175 "\""
176 );
177 }
178 ObjectModelAssociationClassImpl initialClazz =
179 (ObjectModelAssociationClassImpl) initialElement;
180
181 mergeAssociationClasses(initialClazz, clazz);
182
183 }
184 }
185
186 }
187
188 public void addComment(String comment) {
189 comments.add(comment);
190 }
191
192
193
194
195
196
197 @Override
198 public String getName() {
199 return name;
200 }
201
202
203 @Override
204 public Collection<ObjectModelPackage> getPackages() {
205 return packages.values();
206 }
207
208 @Override
209 public ObjectModelPackage getPackage(String packageName) {
210 return packages.get(packageName);
211 }
212
213 @Override
214 public ObjectModelPackage getPackage(ObjectModelClassifier classifier) {
215 return getPackage(classifier.getPackageName());
216 }
217
218 @Override
219 public boolean hasPackage(String packageName) {
220 return packages.containsKey(packageName);
221 }
222
223
224
225
226
227
228
229 @Override
230 public Collection<ObjectModelClassifier> getClassifiers() {
231 return classifiers.values();
232 }
233
234
235
236
237
238
239
240
241
242
243 @Override
244 public ObjectModelClassifier getClassifier(String qualifiedClassifierName) {
245 return qualifiedClassifierName == null ? null
246 : classifiers.get(qualifiedClassifierName);
247 }
248
249
250
251
252
253
254
255 @Override
256 public Collection<ObjectModelClass> getClasses() {
257 return classes.values();
258 }
259
260
261
262
263
264
265
266
267
268
269 @Override
270 public ObjectModelClass getClass(String qualifiedClassName) {
271 if (qualifiedClassName == null) {
272 return null;
273 }
274 if (!hasClass(qualifiedClassName)) {
275 if (log.isDebugEnabled()) {
276 log.debug("Class " + qualifiedClassName + " not found in model");
277 }
278 return null;
279 }
280 return classes.get(qualifiedClassName);
281 }
282
283 @Override
284 public boolean hasClass(String qualifiedClassName) {
285 boolean hasClass = classes.containsKey(qualifiedClassName);
286 return hasClass;
287 }
288
289 public void addInterface(ObjectModelInterfaceImpl interfacez) {
290
291
292 interfacez.postInit();
293 interfacez.setObjectModelImpl(this);
294
295 if (!interfacez.isExtern()) {
296 ObjectModelElementImpl initialElement = (ObjectModelElementImpl)
297 interfaces.get(interfacez.getQualifiedName());
298 if (initialElement == null) {
299 interfaces.put(interfacez.getQualifiedName(), interfacez);
300 classifiers.put(interfacez.getQualifiedName(), interfacez);
301 } else {
302 if (!(initialElement instanceof ObjectModelInterfaceImpl)) {
303 throw new IllegalArgumentException(
304 "\"" + interfacez + "\" is incompatible with " +
305 "already defined element \"" + initialElement +
306 "\"");
307 }
308 ObjectModelInterfaceImpl initialInterfacez =
309 (ObjectModelInterfaceImpl) initialElement;
310
311 mergeClassifiers(initialInterfacez, interfacez);
312
313 }
314 }
315
316 }
317
318
319
320
321
322
323
324
325
326
327 @Override
328 public ObjectModelInterface getInterface(String qualifiedInterfaceName) {
329 ObjectModelInterface result = interfaces.get(qualifiedInterfaceName);
330 if (result == null) {
331 if (log.isDebugEnabled()) {
332 log.debug("Interface " + qualifiedInterfaceName +
333 " not found in model");
334 }
335 }
336 return result;
337 }
338
339
340
341
342
343
344
345 @Override
346 public Collection<ObjectModelInterface> getInterfaces() {
347 return interfaces.values();
348 }
349
350 public void addEnumeration(ObjectModelEnumerationImpl enumeration) {
351 enumeration.postInit();
352 enumeration.setObjectModelImpl(this);
353 classifiers.put(enumeration.getQualifiedName(), enumeration);
354 enumerations.put(enumeration.getQualifiedName(), enumeration);
355 }
356
357 @Override
358 public Collection<ObjectModelEnumeration> getEnumerations() {
359 return enumerations.values();
360 }
361
362 @Override
363 public ObjectModelEnumeration getEnumeration(String qualifiedEnumerationName) {
364 ObjectModelEnumeration result =
365 enumerations.get(qualifiedEnumerationName);
366 if (result == null) {
367 if (log.isDebugEnabled()) {
368 log.debug("Enumeration " + qualifiedEnumerationName +
369 " not found in model");
370 }
371 }
372 return result;
373 }
374
375
376
377
378
379
380 @Override
381 public List<String> getComments() {
382 return comments;
383 }
384
385 @Override
386 public Set<String> getStereotypes() {
387 Set<String> result = new LinkedHashSet<>();
388 for (Map.Entry<String, String> entry : tagValues.entrySet()) {
389 if ("true".equals(entry.getValue())) {
390 result.add(entry.getKey());
391 }
392 }
393 return result;
394 }
395
396 @Override
397 public boolean hasStereotype(String stereotypeName) {
398 return tagValues.containsKey(stereotypeName);
399 }
400
401 @Override
402 public void addStereotype(String stereotype) {
403 tagValues.put(stereotype, "true");
404 }
405
406 @Override
407 public void removeStereotype(String stereotype) {
408 tagValues.remove(stereotype);
409 }
410
411 public void removePackage(String packageName) {
412
413 for (ObjectModelClass objectModelClass : new LinkedHashSet<>(classes.values())) {
414 if (objectModelClass.getQualifiedName().startsWith(packageName + ".")) {
415 classes.remove(objectModelClass.getQualifiedName());
416 }
417 }
418 for (ObjectModelInterface objectModelInterface : new LinkedHashSet<>(interfaces.values())) {
419 if (objectModelInterface.getQualifiedName().startsWith(packageName + ".")) {
420 classes.remove(objectModelInterface.getQualifiedName());
421 }
422 }
423 for (ObjectModelEnumeration objectModelEnumeration : new LinkedHashSet<>(enumerations.values())) {
424 if (objectModelEnumeration.getQualifiedName().startsWith(packageName + ".")) {
425 classes.remove(objectModelEnumeration.getQualifiedName());
426 }
427 }
428 packages.remove(packageName);
429
430 }
431
432 public void removeClass(String className) {
433
434 classes.remove(className);
435
436 }
437
438 public void removeInterface(String interfaceName) {
439 interfaces.remove(interfaceName);
440 }
441
442 public void removeEnumeration(String enumerationName) {
443 enumerations.remove(enumerationName);
444 }
445
446 protected void mergePackages(
447 ObjectModelPackageImpl initialPackage,
448 ObjectModelPackageImpl additionalPackage) {
449 Iterator<?> it;
450
451 String description = "";
452 String sourceDoc = "";
453 if (initialPackage.documentation != null) {
454 description += initialPackage.getDescription();
455 if (initialPackage.documentation.contains("--")) {
456 sourceDoc += initialPackage.getSourceDocumentation();
457 }
458 }
459 if (additionalPackage.documentation != null) {
460 if (!description.equals("")) {
461 description += " - ";
462 }
463 description += additionalPackage.getDescription();
464 if (additionalPackage.documentation.contains("--")) {
465 if (!sourceDoc.equals("")) {
466 sourceDoc += " - ";
467 }
468 sourceDoc += additionalPackage.getSourceDocumentation();
469 }
470 }
471 if (!description.equals("") || !sourceDoc.equals("")) {
472 initialPackage.documentation = description + "--" + sourceDoc;
473 }
474
475 for (it = additionalPackage.getComments().iterator(); it.hasNext(); ) {
476 String comment = (String) it.next();
477 if (!initialPackage.comments.contains(comment)) {
478 initialPackage.comments.add(comment);
479 }
480 }
481 for (it = additionalPackage.getStereotypes().iterator(); it.hasNext(); ) {
482 String stereotype = (String) it.next();
483 if (!initialPackage.getStereotypes().contains(stereotype)) {
484 initialPackage.stereotypes.add(stereotype);
485 }
486 }
487
488 for (it = additionalPackage.getTagValues().keySet().iterator(); it.hasNext(); ) {
489 String tagName = (String) it.next();
490 if (!initialPackage.getTagValues().containsKey(tagName)) {
491 initialPackage.tagValues.put(
492 tagName,
493 additionalPackage.getTagValue(tagName)
494 );
495 }
496 }
497 }
498
499 protected void mergeClassifiers(
500 ObjectModelClassifierImpl initialClazzifier,
501 ObjectModelClassifierImpl additionalClazzifier) {
502 Iterator<?> it;
503
504
505
506
507
508
509
510
511 String description = "";
512 String sourceDoc = "";
513 if (initialClazzifier.documentation != null) {
514 description += initialClazzifier.getDescription();
515 if (initialClazzifier.documentation.contains("--")) {
516 sourceDoc += initialClazzifier.getSourceDocumentation();
517 }
518 }
519 if (additionalClazzifier.documentation != null) {
520 if (!description.equals("")) {
521 description += " - ";
522 }
523 description += additionalClazzifier.getDescription();
524 if (additionalClazzifier.documentation.contains("--")) {
525 if (!sourceDoc.equals("")) {
526 sourceDoc += " - ";
527 }
528 sourceDoc += additionalClazzifier.getSourceDocumentation();
529 }
530 }
531 if (!description.equals("") || !sourceDoc.equals("")) {
532 initialClazzifier.documentation = description + "--" + sourceDoc;
533 }
534
535
536 for (it = additionalClazzifier.interfacesRefs.iterator(); it.hasNext(); ) {
537 ObjectModelImplRef interfaceRef = (ObjectModelImplRef) it.next();
538 if (!contains(initialClazzifier.interfacesRefs, interfaceRef)) {
539 initialClazzifier.interfacesRefs.add(interfaceRef);
540 }
541 initialClazzifier.interfaces = null;
542
543 }
544 for (it = additionalClazzifier.getOperations().iterator(); it.hasNext(); ) {
545 ObjectModelOperationImpl operation = (ObjectModelOperationImpl) it.next();
546 if (!contains(initialClazzifier.getOperations(), operation)) {
547 initialClazzifier.operations.add(operation);
548 }
549 }
550 for (it = additionalClazzifier.getDependencies().iterator(); it.hasNext(); ) {
551 ObjectModelDependencyImpl dependency = (ObjectModelDependencyImpl) it.next();
552 if (!contains(initialClazzifier.getDependencies(), dependency)) {
553 initialClazzifier.dependencies.add(dependency);
554 }
555 }
556 for (it = additionalClazzifier.getComments().iterator(); it.hasNext(); ) {
557 String comment = (String) it.next();
558 if (!initialClazzifier.comments.contains(comment)) {
559 initialClazzifier.comments.add(comment);
560 }
561 }
562 for (it = additionalClazzifier.getStereotypes().iterator(); it.hasNext(); ) {
563 String stereotype = (String) it.next();
564 if (!initialClazzifier.getStereotypes().contains(stereotype)) {
565 initialClazzifier.addStereotype(stereotype);
566 }
567 }
568
569 for (it = additionalClazzifier.getTagValues().keySet().iterator(); it.hasNext(); ) {
570 String tagName = (String) it.next();
571 if (!initialClazzifier.getTagValues().containsKey(tagName)) {
572 initialClazzifier.tagValues.put(
573 tagName,
574 additionalClazzifier.getTagValue(tagName)
575 );
576 }
577 }
578 }
579
580
581
582
583
584
585
586
587 private void mergeClasses(ObjectModelClassImpl initialClazz,
588 ObjectModelClassImpl additionalClazz) {
589 Iterator<?> it;
590 mergeClassifiers(initialClazz, additionalClazz);
591
592 for (it = additionalClazz.getAttributes().iterator(); it.hasNext(); ) {
593 ObjectModelAttributeImpl attribute =
594 (ObjectModelAttributeImpl) it.next();
595 if (!contains(initialClazz.getAttributes(), attribute)) {
596 initialClazz.attributes.put(attribute.getName(), attribute);
597 initialClazz.orderedAttributes.add(attribute);
598 }
599 }
600 for (it = additionalClazz.superclassesRefs.iterator(); it.hasNext(); ) {
601 ObjectModelImplRef superclassRef = (ObjectModelImplRef) it.next();
602 if (!contains(initialClazz.superclassesRefs, superclassRef)) {
603 initialClazz.superclassesRefs.add(superclassRef);
604 }
605 initialClazz.superclasses = null;
606
607 }
608 }
609
610 private void mergeAssociationClasses(
611 ObjectModelAssociationClassImpl initialAssocClazz,
612 ObjectModelAssociationClassImpl additionalAssocClazz) {
613 mergeClasses(initialAssocClazz, additionalAssocClazz);
614 Iterator<?> it;
615 for (it = additionalAssocClazz.participantsRefs.iterator(); it.hasNext(); ) {
616 ObjectModeImplAssociationClassParticipant participant =
617 (ObjectModeImplAssociationClassParticipant) it.next();
618 if (!contains(initialAssocClazz.participantsRefs, participant)) {
619 initialAssocClazz.participantsRefs.add(participant);
620 }
621 initialAssocClazz.participantsAttributes = null;
622
623
624
625 initialAssocClazz.participantsClassifiers = null;
626
627
628
629 }
630 }
631
632 private boolean contains(Collection<ObjectModelAttribute> coll,
633 ObjectModelAttributeImpl toFind) {
634 for (ObjectModelAttribute attribute : coll) {
635 if (attribute.getName().equals(toFind.getName())) {
636
637
638 return true;
639 }
640 }
641 return false;
642 }
643
644 private boolean contains(Collection<?> coll, ObjectModelOperationImpl toFind) {
645 return coll.contains(toFind);
646
647 }
648
649 private boolean contains(Collection<?> coll, ObjectModelImplRef toFind) {
650 return coll.contains(toFind);
651
652 }
653
654 public ObjectModelImplTagValue addTagValue(ObjectModelImplTagValue tagValue) {
655 if (tagValue == null) {
656 return new ObjectModelImplTagValue();
657 }
658 tagValues.put(tagValue.getName(), tagValue.getValue());
659 return tagValue;
660 }
661
662 @Override
663 public Map<String, String> getTagValues() {
664 return tagValues;
665 }
666
667 @Override
668 public String getTagValue(String tagValue) {
669 return tagValue == null ? null : tagValues.get(tagValue);
670 }
671
672 @Override
673 public void addTagValue(String tagValue, String value) {
674 String oldValue = getTagValue(tagValue);
675 if (StringUtils.isNotEmpty(oldValue) && !oldValue.equals(value)) {
676 if (log.isWarnEnabled()) {
677 log.warn("Replace tagValue '" + tagValue + "' (old:" +
678 oldValue + ", new: " + value + ")");
679 }
680 }
681 tagValues.put(tagValue, value);
682 }
683
684 @Override
685 public boolean hasTagValue(String tagValue) {
686 return tagValues.containsKey(tagValue);
687 }
688
689 @Override
690 public void removeTagValue(String tagvalue) {
691 tagValues.remove(tagvalue);
692 }
693
694
695
696
697
698
699
700
701
702
703
704 @Override
705 @SuppressWarnings("unchecked")
706 public <O> O getExtension(String reference, Class<O> extensionClass) throws RuntimeException {
707 if (reference == null) {
708 throw new NullPointerException("reference parameter can not be null in method ObjectModelImpl#getExtension");
709 }
710 if (extensionClass == null) {
711 throw new NullPointerException("extensionClass parameter can not be null in method ObjectModelImpl#getExtension.");
712 }
713 Object object = extensions.get(reference);
714 O result;
715 if (object != null && !extensionClass.isAssignableFrom(object.getClass())) {
716 throw new ClassCastException("Invalid cast for " + extensionClass.getName());
717 }
718 if (object == null) {
719 try {
720 result = extensionClass.newInstance();
721 } catch (Exception eee) {
722 throw new RuntimeException("Unable to create new extension '" + extensionClass.getName() +
723 "' for '" + reference + "'", eee);
724 }
725 extensions.put(reference, result);
726 } else {
727 result = (O) object;
728 }
729 return result;
730 }
731 }