001: package org.andromda.metafacades.uml;
002:
003: import java.text.Collator;
004:
005: import java.util.Collection;
006: import java.util.Collections;
007: import java.util.Comparator;
008: import java.util.List;
009:
010: import org.apache.commons.collections.CollectionUtils;
011: import org.apache.commons.collections.Predicate;
012: import org.apache.commons.lang.StringUtils;
013:
014: /**
015: * A class containing utlities for metafacade manipulation.
016: *
017: * @author Chad Brandon
018: * @author Wouter Zoons
019: */
020: public class MetafacadeUtils {
021: /**
022: * Checks to see if the element is the specified type and if so casts it to the object and returns it, otherwise it
023: * returns null.
024: *
025: * @param element the element to check.
026: * @param type the Class type.
027: * @return the element has the given type or null.
028: */
029: public static Object getElementAsType(final Object element,
030: final Class type) {
031: Object elementAsType = null;
032: if (element != null && type != null) {
033: final Class elementClass = element.getClass();
034: if (type.isAssignableFrom(elementClass)) {
035: elementAsType = element;
036: }
037: }
038: return elementAsType;
039: }
040:
041: /**
042: * Filters out the model elements from the <code>modelElements</code> collection that don't have the specified
043: * <code>stereotype</code>
044: *
045: * @param modelElements the model elements to filter.
046: * @param stereotype the stereotype that a model element must have in order to stay remain within the
047: * <code>modelElements</code> collection.
048: */
049: public static void filterByStereotype(
050: final Collection modelElements, final String stereotype) {
051: if (StringUtils.isNotEmpty(stereotype)) {
052: CollectionUtils.filter(modelElements, new Predicate() {
053: public boolean evaluate(Object object) {
054: return ((ModelElementFacade) object)
055: .hasStereotype(stereotype);
056: }
057: });
058: }
059: }
060:
061: /**
062: * Filters out the model elements from the <code>modelElements</code> collection that are not of (or do not inherit
063: * from) the specified type <code>type</code>
064: *
065: * @param modelElements the model elements to filter.
066: * @param type the type of Class.
067: */
068: public static void filterByType(final Collection modelElements,
069: final Class type) {
070: if (type != null) {
071: CollectionUtils.filter(modelElements, new Predicate() {
072: public boolean evaluate(Object object) {
073: return type.isAssignableFrom(object.getClass());
074: }
075: });
076: }
077: }
078:
079: /**
080: * Filters out the model elements from the <code>modelElements</code> collection that are of (or inherit from) the
081: * specified type <code>type</code>
082: *
083: * @param modelElements the model elements to filter.
084: * @param type the type of Class.
085: */
086: public static void filterByNotType(final Collection modelElements,
087: final Class type) {
088: if (type != null) {
089: CollectionUtils.filter(modelElements, new Predicate() {
090: public boolean evaluate(Object object) {
091: return !type.isAssignableFrom(object.getClass());
092: }
093: });
094: }
095: }
096:
097: /**
098: * <p/>Returns a consistent name for a relation, independent from the end of the relation one is looking at. </p>
099: * <p/>In order to guarantee consistency with relation names, they must appear the same whichever angle (ie entity)
100: * that you come from. For example, if you are at Customer end of a relationship to an Address then your relation
101: * may appear with the name Customer-Address. But if you are in the Address entity looking at the Customer then you
102: * will get an error because the relation will be called Address-Customer. A simple way to guarantee that both ends
103: * of the relationship have the same name is merely to use alphabetical ordering. </p>
104: *
105: * @param roleName name of role in relation
106: * @param targetRoleName name of target role in relation
107: * @param separator character used to separate words
108: * @return uniform mapping name (in alphabetical order)
109: */
110: public static String toRelationName(final String roleName,
111: final String targetRoleName, final String separator) {
112: if (roleName.compareTo(targetRoleName) <= 0) {
113: return (roleName + separator + targetRoleName);
114: }
115: return (targetRoleName + separator + roleName);
116: }
117:
118: /**
119: * Sorts given metafacades by their fully qualified name.
120: *
121: * @param metafacades the collection of model elements to sort.
122: * @return the sorted collection.
123: */
124: public static void sortByFullyQualifiedName(final List metafacades) {
125: Collections.sort(metafacades,
126: new FullyQualifiedNameComparator());
127: }
128:
129: /**
130: * Used to sort operations by <code>fullyQualifiedName</code>.
131: */
132: private final static class FullyQualifiedNameComparator implements
133: Comparator {
134: private final Collator collator = Collator.getInstance();
135:
136: FullyQualifiedNameComparator() {
137: collator.setStrength(Collator.PRIMARY);
138: }
139:
140: public int compare(final Object objectA, final Object objectB) {
141: final ModelElementFacade a = (ModelElementFacade) objectA;
142: final ModelElementFacade b = (ModelElementFacade) objectB;
143: return collator.compare(
144: a.getFullyQualifiedName() != null ? a
145: .getFullyQualifiedName() : "", b
146: .getFullyQualifiedName() != null ? b
147: .getFullyQualifiedName() : "");
148: }
149: }
150: }
|