001: package org.andromda.metafacades.uml14;
002:
003: import java.security.MessageDigest;
004: import java.security.NoSuchAlgorithmException;
005: import java.util.ArrayList;
006: import java.util.Collection;
007: import java.util.Iterator;
008: import java.util.LinkedHashSet;
009: import java.util.List;
010: import java.util.Set;
011:
012: import org.andromda.metafacades.uml.AssociationEndFacade;
013: import org.andromda.metafacades.uml.AttributeFacade;
014: import org.andromda.metafacades.uml.ClassifierFacade;
015: import org.andromda.metafacades.uml.DependencyFacade;
016: import org.andromda.metafacades.uml.FilteredCollection;
017: import org.andromda.metafacades.uml.GeneralizableElementFacade;
018: import org.andromda.metafacades.uml.ModelElementFacade;
019: import org.andromda.metafacades.uml.NameMasker;
020: import org.andromda.metafacades.uml.OperationFacade;
021: import org.andromda.metafacades.uml.ParameterFacade;
022: import org.andromda.metafacades.uml.TypeMappings;
023: import org.andromda.metafacades.uml.UMLMetafacadeProperties;
024: import org.andromda.metafacades.uml.UMLMetafacadeUtils;
025: import org.andromda.metafacades.uml.UMLProfile;
026: import org.apache.commons.collections.CollectionUtils;
027: import org.apache.commons.collections.Predicate;
028: import org.apache.commons.collections.Transformer;
029: import org.apache.commons.lang.StringUtils;
030: import org.omg.uml.foundation.core.Abstraction;
031: import org.omg.uml.foundation.core.AssociationClass;
032: import org.omg.uml.foundation.core.Attribute;
033: import org.omg.uml.foundation.core.DataType;
034: import org.omg.uml.foundation.core.Interface;
035: import org.omg.uml.foundation.core.Operation;
036:
037: /**
038: * Metaclass facade implementation.
039: */
040: public class ClassifierFacadeLogicImpl extends ClassifierFacadeLogic {
041: public ClassifierFacadeLogicImpl(
042: org.omg.uml.foundation.core.Classifier metaObject,
043: String context) {
044: super (metaObject, context);
045: }
046:
047: /**
048: * Overridden to provide name masking.
049: *
050: * @see org.andromda.metafacades.uml.ModelElementFacade#getName()
051: */
052: protected String handleGetName() {
053: final String nameMask = String
054: .valueOf(this
055: .getConfiguredProperty(UMLMetafacadeProperties.CLASSIFIER_NAME_MASK));
056: return NameMasker.mask(super .handleGetName(), nameMask);
057: }
058:
059: protected Collection handleGetOperations() {
060: return new FilteredCollection(this .metaObject.getFeature()) {
061: public boolean evaluate(Object object) {
062: return object instanceof org.omg.uml.foundation.core.Operation;
063: }
064: };
065: }
066:
067: /**
068: * Note: if this instance represents an actual class we resolve any realized interfaces recursively, in case this
069: * instance represents an interface we return only the owned operations.
070: *
071: * @see org.andromda.metafacades.uml.ClassifierFacade#getOperations()
072: */
073: protected java.util.Collection handleGetImplementationOperations() {
074: final Collection operations = new LinkedHashSet();
075:
076: // add all of this classifier's operations
077: operations.addAll(new FilteredCollection(metaObject
078: .getFeature()) {
079: public boolean evaluate(Object object) {
080: return object instanceof Operation;
081: }
082: });
083:
084: if (!this .isInterface()) {
085: final Collection interfaces = this
086: .getInterfaceAbstractions();
087: for (Iterator interfaceIterator = interfaces.iterator(); interfaceIterator
088: .hasNext();) {
089: final ClassifierFacade interfaceElement = (ClassifierFacade) interfaceIterator
090: .next();
091: operations
092: .addAll(resolveInterfaceOperationsRecursively(interfaceElement));
093: }
094: }
095:
096: return operations;
097: }
098:
099: private static Collection resolveInterfaceOperationsRecursively(
100: ClassifierFacade interfaceClassifier) {
101: final Collection operations = new LinkedHashSet(
102: interfaceClassifier.getOperations()); // preserve ordering
103:
104: final Collection generalizations = interfaceClassifier
105: .getGeneralizations();
106: for (Iterator generalizationIterator = generalizations
107: .iterator(); generalizationIterator.hasNext();) {
108: final ClassifierFacade parent = (ClassifierFacade) generalizationIterator
109: .next();
110: if (parent.isInterface()) {
111: operations
112: .addAll(resolveInterfaceOperationsRecursively(parent));
113: }
114: }
115:
116: return operations;
117: }
118:
119: /**
120: * @see org.andromda.metafacades.uml.ClassifierFacade#getAssociationEnds()
121: */
122: protected java.util.List handleGetAssociationEnds() {
123: List associationEnds;
124: Collection participantAssociation = UML14MetafacadeUtils
125: .getCorePackage().getAParticipantAssociation()
126: .getAssociation(metaObject);
127:
128: if (participantAssociation instanceof List) {
129: associationEnds = (List) participantAssociation;
130: } else {
131: associationEnds = new ArrayList();
132: associationEnds.addAll(participantAssociation);
133: }
134:
135: return associationEnds;
136: }
137:
138: /**
139: * @see org.andromda.metafacades.uml.ClassifierFacade#isPrimitive()
140: */
141: protected boolean handleIsPrimitive() {
142: // If this type has a wrapper then its a primitive,
143: // otherwise it isn't
144: return this .getWrapperMappings() != null
145: && this .getWrapperMappings().getMappings()
146: .containsFrom(this .getFullyQualifiedName());
147: }
148:
149: /**
150: * @see org.andromda.metafacades.uml.ClassifierFacade#isArrayType()
151: */
152: protected boolean handleIsArrayType() {
153: return this .getFullyQualifiedName(true).endsWith(
154: this .getArraySuffix());
155: }
156:
157: /**
158: * Gets the array suffix from the configured metafacade properties.
159: *
160: * @return the array suffix.
161: */
162: private String getArraySuffix() {
163: return String
164: .valueOf(this
165: .getConfiguredProperty(UMLMetafacadeProperties.ARRAY_NAME_SUFFIX));
166: }
167:
168: /**
169: * @see org.andromda.metafacades.uml.ClassifierFacade#getWrapperName()
170: */
171: protected String handleGetWrapperName() {
172: String wrapperName = null;
173: if (this .getWrapperMappings() != null) {
174: if (this .getWrapperMappings().getMappings().containsFrom(
175: this .getFullyQualifiedName())) {
176: wrapperName = this .getWrapperMappings().getTo(
177: this .getFullyQualifiedName());
178: }
179: }
180: return wrapperName;
181: }
182:
183: /**
184: * Gets the mappings from primitive types to wrapper types. Some languages have primitives (i.e., Java) and some
185: * languages don't, so therefore this property is optional.
186: *
187: * @return the wrapper mappings
188: */
189: protected TypeMappings getWrapperMappings() {
190: final String propertyName = UMLMetafacadeProperties.WRAPPER_MAPPINGS_URI;
191: final Object property = this
192: .getConfiguredProperty(propertyName);
193: TypeMappings mappings = null;
194: String uri;
195: if (property instanceof String) {
196: uri = (String) property;
197: try {
198: mappings = TypeMappings.getInstance(uri);
199: this .setProperty(propertyName, mappings);
200: } catch (final Throwable throwable) {
201: final String errMsg = "Error getting '" + propertyName
202: + "' --> '" + uri + "'";
203: logger.error(errMsg, throwable);
204:
205: // don't throw the exception
206: }
207: } else {
208: mappings = (TypeMappings) property;
209: }
210: return mappings;
211: }
212:
213: /**
214: * @see org.andromda.metafacades.uml.ClassifierFacade#isCollectionType()
215: */
216: protected boolean handleIsCollectionType() {
217: return UMLMetafacadeUtils.isType(this ,
218: UMLProfile.COLLECTION_TYPE_NAME);
219: }
220:
221: /**
222: * @see org.andromda.metafacades.uml.ClassifierFacade#isListType()
223: */
224: protected boolean handleIsListType() {
225: return UMLMetafacadeUtils.isType(this ,
226: UMLProfile.LIST_TYPE_NAME);
227: }
228:
229: /**
230: * @see org.andromda.metafacades.uml.ClassifierFacade#isSetType()
231: */
232: protected boolean handleIsSetType() {
233: return UMLMetafacadeUtils
234: .isType(this , UMLProfile.SET_TYPE_NAME);
235: }
236:
237: /**
238: * @see org.andromda.metafacades.uml.ClassifierFacade#isBooleanType()
239: */
240: protected boolean handleIsBooleanType() {
241: return UMLMetafacadeUtils.isType(this ,
242: UMLProfile.BOOLEAN_TYPE_NAME);
243: }
244:
245: /**
246: * @see org.andromda.metafacades.uml.ClassifierFacade#isDateType()
247: */
248: protected boolean handleIsDateType() {
249: return UMLMetafacadeUtils.isType(this ,
250: UMLProfile.DATE_TYPE_NAME);
251: }
252:
253: /**
254: * @see org.andromda.metafacades.uml.ClassifierFacade#isTimeType()
255: */
256: protected boolean handleIsTimeType() {
257: return UMLMetafacadeUtils.isType(this ,
258: UMLProfile.TIME_TYPE_NAME);
259: }
260:
261: /**
262: * @see org.andromda.metafacades.uml.ClassifierFacade#isFileType()
263: */
264: protected boolean handleIsFileType() {
265: return UMLMetafacadeUtils.isType(this ,
266: UMLProfile.FILE_TYPE_NAME);
267: }
268:
269: /**
270: * @see org.andromda.metafacades.uml.ClassifierFacade#isBlobType()
271: */
272: protected boolean handleIsBlobType() {
273: return UMLMetafacadeUtils.isType(this ,
274: UMLProfile.BLOB_TYPE_NAME);
275: }
276:
277: /**
278: * @see org.andromda.metafacades.uml.ClassifierFacade#isClobType()
279: */
280: protected boolean handleIsClobType() {
281: return UMLMetafacadeUtils.isType(this ,
282: UMLProfile.CLOB_TYPE_NAME);
283: }
284:
285: /**
286: * @see org.andromda.metafacades.uml.ClassifierFacade#isMapType()
287: */
288: public boolean handleIsMapType() {
289: return UMLMetafacadeUtils
290: .isType(this , UMLProfile.MAP_TYPE_NAME);
291: }
292:
293: /**
294: * @see org.andromda.metafacades.uml.ClassifierFacade#isStringType()
295: */
296: protected boolean handleIsStringType() {
297: return UMLMetafacadeUtils.isType(this ,
298: UMLProfile.STRING_TYPE_NAME);
299: }
300:
301: /**
302: * @see org.andromda.metafacades.uml.ClassifierFacade#getAttributes()
303: */
304: protected java.util.Collection handleGetAttributes() {
305: final Collection attributes = new ArrayList(this .metaObject
306: .getFeature());
307: for (final Iterator iterator = attributes.iterator(); iterator
308: .hasNext();) {
309: if (!(iterator.next() instanceof Attribute)) {
310: iterator.remove();
311: }
312: }
313: return attributes;
314: }
315:
316: /**
317: * @see org.andromda.metafacades.uml.ClassifierFacade#getAttributes(boolean)
318: */
319: protected Collection handleGetAttributes(boolean follow) {
320: final Collection attributes = new ArrayList(this
321: .getAttributes());
322: for (ClassifierFacade super Class = (ClassifierFacade) getGeneralization(); super Class != null
323: && follow; super Class = (ClassifierFacade) super Class
324: .getGeneralization()) {
325: for (final Iterator iterator = super Class.getAttributes()
326: .iterator(); iterator.hasNext();) {
327: final AttributeFacade super Attribute = (AttributeFacade) iterator
328: .next();
329: boolean present = false;
330: for (final Iterator attributeIterator = this
331: .getAttributes().iterator(); attributeIterator
332: .hasNext();) {
333: final AttributeFacade attribute = (AttributeFacade) attributeIterator
334: .next();
335: if (attribute.getName().equals(
336: super Attribute.getName())) {
337: present = true;
338: break;
339: }
340: }
341: if (!present) {
342: attributes.add(super Attribute);
343: }
344: }
345: }
346: return attributes;
347: }
348:
349: /**
350: * @see org.andromda.metafacades.uml.ClassifierFacade#getProperties()
351: */
352: protected java.util.Collection handleGetProperties() {
353: final Collection properties = new ArrayList(this
354: .getAttributes());
355: properties.addAll(this .getNavigableConnectingEnds());
356: return properties;
357: }
358:
359: /**
360: * @see org.andromda.metafacades.uml.ClassifierFacade#getAllProperties()
361: */
362: public Collection handleGetAllProperties() {
363: return this .getProperties(true);
364: }
365:
366: /**
367: * @see org.andromda.metafacades.uml.ClassifierFacade#getAllRequiredConstructorParameters()
368: */
369: public Collection handleGetAllRequiredConstructorParameters() {
370: final Collection allRequiredConstructorParameters = new ArrayList();
371: allRequiredConstructorParameters.addAll(this
372: .getRequiredConstructorParameters());
373:
374: final Collection generalizations = this .getGeneralizations();
375: for (Iterator parents = generalizations.iterator(); parents
376: .hasNext();) {
377: final Object parent = parents.next();
378: if (parent instanceof ClassifierFacade) {
379: allRequiredConstructorParameters
380: .addAll(((ClassifierFacade) parent)
381: .getAllRequiredConstructorParameters());
382: }
383: }
384:
385: return allRequiredConstructorParameters;
386: }
387:
388: /**
389: * @see org.andromda.metafacades.uml.ClassifierFacade#getRequiredConstructorParameters()
390: */
391: public Collection handleGetRequiredConstructorParameters() {
392: final Collection requiredConstructorParameters = new ArrayList();
393:
394: final Collection properties = this .getProperties();
395: for (Iterator propertyIterator = properties.iterator(); propertyIterator
396: .hasNext();) {
397: final Object property = propertyIterator.next();
398: if (property instanceof AttributeFacade) {
399: final AttributeFacade attribute = (AttributeFacade) property;
400: if (attribute.isRequired() || attribute.isReadOnly()) {
401: requiredConstructorParameters.add(attribute);
402: }
403: } else if (property instanceof AssociationEndFacade) {
404: final AssociationEndFacade associationEnd = (AssociationEndFacade) property;
405: if (associationEnd.isRequired()
406: || associationEnd.isReadOnly()) {
407: requiredConstructorParameters.add(associationEnd);
408: }
409: }
410: }
411:
412: return requiredConstructorParameters;
413: }
414:
415: /**
416: * @see org.andromda.metafacades.uml.ClassifierFacade#getProperties(boolean)
417: */
418: protected Collection handleGetProperties(boolean follow) {
419: final Collection properties = new ArrayList(this
420: .getAttributes(follow));
421: properties.addAll(this .getNavigableConnectingEnds());
422: if (follow) {
423: for (ClassifierFacade super Class = (ClassifierFacade) getGeneralization(); super Class != null
424: && follow; super Class = (ClassifierFacade) super Class
425: .getGeneralization()) {
426: for (final Iterator iterator = super Class
427: .getNavigableConnectingEnds().iterator(); iterator
428: .hasNext();) {
429: final AssociationEndFacade super AssociationEnd = (AssociationEndFacade) iterator
430: .next();
431: boolean present = false;
432: for (final Iterator endIterator = this
433: .getAssociationEnds().iterator(); endIterator
434: .hasNext();) {
435: final AssociationEndFacade associationEnd = (AssociationEndFacade) endIterator
436: .next();
437: if (associationEnd.getName().equals(
438: super AssociationEnd.getName())) {
439: present = true;
440: break;
441: }
442: }
443: if (!present) {
444: properties.add(super AssociationEnd);
445: }
446: }
447: }
448: }
449: return properties;
450: }
451:
452: /**
453: * @see org.andromda.metafacades.uml.ClassifierFacade#getOperationCallFromAttributes()
454: */
455: protected String handleGetOperationCallFromAttributes() {
456: final StringBuffer call = new StringBuffer();
457: String separator = "";
458: call.append("(");
459: for (final Iterator iterator = getAttributes().iterator(); iterator
460: .hasNext();) {
461: AttributeFacade attribute = (AttributeFacade) iterator
462: .next();
463:
464: call.append(separator);
465: String typeName = attribute.getType()
466: .getFullyQualifiedName();
467: call.append(typeName);
468: call.append(" ");
469: call.append(attribute.getName());
470: separator = ", ";
471: }
472: call.append(")");
473: return call.toString();
474: }
475:
476: /**
477: * @see org.andromda.metafacades.uml.ClassifierFacade#isAbstract()
478: */
479: protected boolean handleIsAbstract() {
480: return this .metaObject.isAbstract();
481: }
482:
483: /**
484: * @see org.andromda.metafacades.uml.ClassifierFacade#getStaticAttributes()
485: */
486: protected Collection handleGetStaticAttributes() {
487: return new FilteredCollection(this .getAttributes()) {
488: public boolean evaluate(Object object) {
489: return ((AttributeFacade) object).isStatic();
490: }
491: };
492: }
493:
494: /**
495: * @see org.andromda.metafacades.uml.ClassifierFacade#getInterfaceAbstractions()
496: */
497: protected Collection handleGetInterfaceAbstractions() {
498: final Collection interfaceAbstractions = new LinkedHashSet();
499: if (this .getAbstractions() != null) {
500: for (Iterator abstractionIterator = this .getAbstractions()
501: .iterator(); abstractionIterator.hasNext();) {
502: final DependencyFacade abstraction = (DependencyFacade) abstractionIterator
503: .next();
504: final ModelElementFacade element = abstraction
505: .getTargetElement();
506:
507: if (element instanceof ClassifierFacade) {
508: final ClassifierFacade classifier = (ClassifierFacade) element;
509: if (classifier.isInterface()) {
510: interfaceAbstractions.add(classifier);
511: }
512: }
513: }
514: }
515:
516: return interfaceAbstractions;
517: }
518:
519: /**
520: * @see org.andromda.metafacades.uml.ClassifierFacade#getImplementedInterfaceList()
521: */
522: protected String handleGetImplementedInterfaceList() {
523: final String interfaceList;
524:
525: final Collection interfaces = this .getInterfaceAbstractions();
526: if (interfaces.isEmpty()) {
527: interfaceList = "";
528: } else {
529: final StringBuffer list = new StringBuffer();
530: for (final Iterator iterator = interfaces.iterator(); iterator
531: .hasNext();) {
532: final ModelElementFacade element = (ModelElementFacade) iterator
533: .next();
534: list.append(element.getFullyQualifiedName());
535: if (iterator.hasNext()) {
536: list.append(", ");
537: }
538: }
539: interfaceList = list.toString();
540: }
541:
542: return interfaceList;
543: }
544:
545: /**
546: * @see org.andromda.metafacades.uml.ClassifierFacade#getInstanceAttributes()
547: */
548: protected java.util.Collection handleGetInstanceAttributes() {
549: return new FilteredCollection(this .getAttributes()) {
550: public boolean evaluate(Object object) {
551: return !((AttributeFacade) object).isStatic();
552: }
553: };
554: }
555:
556: /**
557: * @see org.andromda.metafacades.uml.ClassifierFacade#getAbstractions()
558: */
559: protected Collection handleGetAbstractions() {
560: return new FilteredCollection(this .metaObject
561: .getClientDependency()) {
562: public boolean evaluate(Object object) {
563: return object instanceof Abstraction;
564: }
565: };
566: }
567:
568: /**
569: * @see org.andromda.metafacades.uml.ClassifierFacade#isDataType()
570: */
571: protected boolean handleIsDataType() {
572: return DataType.class.isAssignableFrom(this .metaObject
573: .getClass());
574: }
575:
576: /**
577: * @see org.andromda.metafacades.uml.ClassifierFacade#isInterface()
578: */
579: protected boolean handleIsInterface() {
580: return Interface.class.isAssignableFrom(this .metaObject
581: .getClass());
582: }
583:
584: /**
585: * @see org.andromda.metafacades.uml.ClassifierFacade#getNonArray()
586: */
587: protected Object handleGetNonArray() {
588: ClassifierFacade nonArrayType = this ;
589: if (this .getFullyQualifiedName().indexOf(this .getArraySuffix()) != -1) {
590: nonArrayType = (ClassifierFacade) this .getRootPackage()
591: .findModelElement(
592: StringUtils.replace(this
593: .getFullyQualifiedName(true), this
594: .getArraySuffix(), ""));
595: }
596: return nonArrayType;
597: }
598:
599: /**
600: * @see org.andromda.metafacades.uml.ClassifierFacade#getArray()
601: */
602: protected Object handleGetArray() {
603: ClassifierFacade arrayType = this ;
604: String name = this .getFullyQualifiedName(true);
605: if (name.indexOf(this .getArraySuffix()) == -1) {
606: name = name + this .getArraySuffix();
607: arrayType = (ClassifierFacade) this .getRootPackage()
608: .findModelElement(name);
609: }
610: return arrayType;
611: }
612:
613: /**
614: * @see org.andromda.metafacades.uml.ClassifierFacade#isEnumeration()
615: */
616: protected boolean handleIsEnumeration() {
617: return this .hasStereotype(UMLProfile.STEREOTYPE_ENUMERATION);
618: }
619:
620: /**
621: * @see org.andromda.metafacades.uml.ClassifierFacade#getJavaNullString()
622: */
623: protected String handleGetJavaNullString() {
624: String javaNullString;
625: if (isPrimitive()) {
626: if (UMLMetafacadeUtils.isType(this ,
627: UMLProfile.BOOLEAN_TYPE_NAME)) {
628: javaNullString = "false";
629: } else {
630: javaNullString = "0";
631: }
632: } else {
633: javaNullString = "null";
634: }
635: return javaNullString;
636: }
637:
638: /**
639: * @see org.andromda.metafacades.uml.ClassifierFacade#getStaticOperations()
640: */
641: protected Collection handleGetStaticOperations() {
642: return new FilteredCollection(this .getOperations()) {
643: public boolean evaluate(Object object) {
644: return ((OperationFacade) object).isStatic();
645: }
646: };
647: }
648:
649: /**
650: * @see org.andromda.metafacades.uml.ClassifierFacade#getInstanceOperations()
651: */
652: protected Collection handleGetInstanceOperations() {
653: return new FilteredCollection(this .getOperations()) {
654: public boolean evaluate(Object object) {
655: return !((OperationFacade) object).isStatic();
656: }
657: };
658: }
659:
660: /**
661: * @see org.andromda.metafacades.uml.ClassifierFacade#findAttribute(java.lang.String)
662: */
663: protected AttributeFacade handleFindAttribute(final String name) {
664: return (AttributeFacade) CollectionUtils.find(this
665: .getAttributes(), new Predicate() {
666: public boolean evaluate(Object object) {
667: final AttributeFacade attribute = (AttributeFacade) object;
668: return StringUtils.trimToEmpty(attribute.getName())
669: .equals(name);
670: }
671: });
672: }
673:
674: /**
675: * @see org.andromda.metafacades.uml.ClassifierFacade#getArrayName()
676: */
677: protected String handleGetArrayName() {
678: return this .getName() + this .getArraySuffix();
679: }
680:
681: /**
682: * @see org.andromda.metafacades.uml.ClassifierFacade#getFullyQualifiedArrayName()
683: */
684: protected String handleGetFullyQualifiedArrayName() {
685: return this .getFullyQualifiedName() + this .getArraySuffix();
686: }
687:
688: /**
689: * Calculates the serial version UID of this classifier based on the
690: * signature of the classifier (name, visibility, attributes and methods).
691: * The algorithm is inspired by
692: * {@link java.io.ObjectStreamClass#getSerialVersionUID()}.
693: *
694: * The value should be stable as long as the classifier remains unchanged
695: * and should change as soon as there is any change in the signature of the
696: * classifier.
697: *
698: * @return the serial version UID of this classifier.
699: */
700: private Long calculateDefaultSUID() {
701: final StringBuffer buffer = new StringBuffer();
702:
703: // class name
704: buffer.append(this .getName());
705:
706: // generalizations
707: for (final Iterator iterator = this .getAllGeneralizations()
708: .iterator(); iterator.hasNext();) {
709: ClassifierFacade classifier = (ClassifierFacade) iterator
710: .next();
711: buffer.append(classifier.getName());
712: }
713:
714: // declared fields
715: for (final Iterator iterator = this .getAttributes().iterator(); iterator
716: .hasNext();) {
717: AttributeFacade attribute = (AttributeFacade) iterator
718: .next();
719: buffer.append(attribute.getName());
720: buffer.append(attribute.getVisibility());
721: buffer.append(attribute.getType().getName());
722: }
723:
724: // operations
725: for (final Iterator iter = this .getOperations().iterator(); iter
726: .hasNext();) {
727: OperationFacade operation = (OperationFacade) iter.next();
728: buffer.append(operation.getName());
729: buffer.append(operation.getVisibility());
730: buffer.append(operation.getReturnType().getName());
731: for (final Iterator iterator = operation.getArguments()
732: .iterator(); iterator.hasNext();) {
733: final ParameterFacade parameter = (ParameterFacade) iterator
734: .next();
735: buffer.append(parameter.getName());
736: buffer.append(parameter.getType().getName());
737: }
738: }
739: final String signature = buffer.toString();
740:
741: Long serialVersionUID = new Long(0L);
742: try {
743: MessageDigest md = MessageDigest.getInstance("SHA");
744: byte[] hashBytes = md.digest(signature.getBytes());
745:
746: long hash = 0;
747: for (int ctr = Math.min(hashBytes.length, 8) - 1; ctr >= 0; ctr--) {
748: hash = (hash << 8) | (hashBytes[ctr] & 0xFF);
749: }
750: serialVersionUID = new Long(hash);
751: } catch (final NoSuchAlgorithmException exception) {
752: final String errMsg = "Error performing ModelElementFacadeImpl.getSerialVersionUID";
753: logger.error(errMsg, exception);
754: }
755: return serialVersionUID;
756: }
757:
758: /**
759: * @see org.andromda.metafacades.uml.ClassifierFacade#getSerialVersionUID()
760: */
761: protected Long handleGetSerialVersionUID() {
762: Long serialVersionUID;
763: final String serialVersionString = UML14MetafacadeUtils
764: .getSerialVersionUID(this );
765: if (serialVersionString != null) {
766: serialVersionUID = Long.valueOf(serialVersionString);
767: } else {
768: serialVersionUID = calculateDefaultSUID();
769: }
770: return serialVersionUID;
771: }
772:
773: /**
774: * @see org.andromda.metafacades.uml.ClassifierFacade#getNavigableConnectingEnds()
775: */
776: protected Collection handleGetNavigableConnectingEnds() {
777: final Collection connectingEnds = new ArrayList(this
778: .getAssociationEnds());
779: CollectionUtils.transform(connectingEnds, new Transformer() {
780: public Object transform(final Object object) {
781: return ((AssociationEndFacade) object).getOtherEnd();
782: }
783: });
784: CollectionUtils.filter(connectingEnds, new Predicate() {
785: public boolean evaluate(final Object object) {
786: return ((AssociationEndFacade) object).isNavigable();
787: }
788: });
789: return connectingEnds;
790: }
791:
792: /**
793: * @see org.andromda.metafacades.uml.ClassifierFacade#getNavigableConnectingEnds(boolean)
794: */
795: protected Collection handleGetNavigableConnectingEnds(boolean follow) {
796: final Collection connectionEnds = new ArrayList(this
797: .getNavigableConnectingEnds());
798:
799: for (ClassifierFacade super Class = (ClassifierFacade) getGeneralization(); super Class != null
800: && follow; super Class = (ClassifierFacade) super Class
801: .getGeneralization()) {
802: for (final Iterator iterator = super Class
803: .getNavigableConnectingEnds().iterator(); iterator
804: .hasNext();) {
805: final AssociationEndFacade super AssociationEnd = (AssociationEndFacade) iterator
806: .next();
807: boolean present = false;
808: for (final Iterator endIterator = this
809: .getAssociationEnds().iterator(); endIterator
810: .hasNext();) {
811: final AssociationEndFacade associationEnd = (AssociationEndFacade) endIterator
812: .next();
813: if (associationEnd.getName().equals(
814: super AssociationEnd.getName())) {
815: present = true;
816: break;
817: }
818: }
819: if (!present) {
820: connectionEnds.add(super AssociationEnd);
821: }
822: }
823: }
824: return connectionEnds;
825: }
826:
827: /**
828: * @see org.andromda.metafacades.uml.ClassifierFacade#isLeaf()
829: */
830: protected boolean handleIsLeaf() {
831: return this .metaObject.isLeaf();
832: }
833:
834: /**
835: * @see org.andromda.metafacades.uml14.ClassifierFacadeLogic#handleIsAssociationClass()
836: */
837: protected boolean handleIsAssociationClass() {
838: return AssociationClass.class.isAssignableFrom(this .metaObject
839: .getClass());
840: }
841:
842: protected Collection handleGetAssociatedClasses() {
843: final Set associatedClasses = new LinkedHashSet();
844:
845: final List associationEnds = this .getAssociationEnds();
846: for (int i = 0; i < associationEnds.size(); i++) {
847: final AssociationEndFacade associationEndFacade = (AssociationEndFacade) associationEnds
848: .get(i);
849: associatedClasses.add(associationEndFacade.getOtherEnd()
850: .getType());
851: }
852:
853: return associatedClasses;
854: }
855:
856: protected Collection handleGetAllAssociatedClasses() {
857: final Set associatedClasses = new LinkedHashSet();
858: associatedClasses.addAll(this .getAssociatedClasses());
859: for (Iterator parentIterator = this .getGeneralizations()
860: .iterator(); parentIterator.hasNext();) {
861: final ClassifierFacade parent = (ClassifierFacade) parentIterator
862: .next();
863: associatedClasses.addAll(parent.getAllAssociatedClasses());
864: }
865:
866: return associatedClasses;
867: }
868:
869: protected Object handleGetSuperClass() {
870: final GeneralizableElementFacade super Class = this
871: .getGeneralization();
872: return super Class instanceof ClassifierFacade ? superClass
873: : null;
874: }
875: }
|