View Javadoc

1   package org.andromda.metafacades.uml14;
2   
3   import java.util.Collection;
4   import java.util.Iterator;
5   
6   import org.andromda.metafacades.uml.ClassifierFacade;
7   import org.andromda.metafacades.uml.NameMasker;
8   import org.andromda.metafacades.uml.TypeMappings;
9   import org.andromda.metafacades.uml.UMLMetafacadeProperties;
10  import org.andromda.metafacades.uml.UMLMetafacadeUtils;
11  import org.andromda.metafacades.uml.UMLProfile;
12  import org.andromda.utils.StringUtilsHelper;
13  import org.apache.commons.lang.BooleanUtils;
14  import org.apache.commons.lang.ObjectUtils;
15  import org.apache.commons.lang.StringUtils;
16  import org.omg.uml.foundation.core.AssociationEnd;
17  import org.omg.uml.foundation.datatypes.AggregationKindEnum;
18  import org.omg.uml.foundation.datatypes.ChangeableKindEnum;
19  import org.omg.uml.foundation.datatypes.Multiplicity;
20  import org.omg.uml.foundation.datatypes.MultiplicityRange;
21  import org.omg.uml.foundation.datatypes.OrderingKind;
22  import org.omg.uml.foundation.datatypes.OrderingKindEnum;
23  
24  
25  /***
26   * Metaclass facade implementation.
27   */
28  public class AssociationEndFacadeLogicImpl
29      extends AssociationEndFacadeLogic
30      implements org.andromda.metafacades.uml.AssociationEndFacade
31  {
32      public AssociationEndFacadeLogicImpl(
33          org.omg.uml.foundation.core.AssociationEnd metaObject,
34          String context)
35      {
36          super(metaObject, context);
37      }
38  
39      /***
40       * @see org.andromda.core.metafacade.MetafacadeBase#getValidationOwner()
41       */
42      public Object getValidationOwner()
43      {
44          return this.getType();
45      }
46  
47      /***
48       * @see org.andromda.metafacades.uml.AssociationEndFacade#getOtherEnd()
49       */
50      protected Object handleGetOtherEnd()
51      {
52          final Collection ends = metaObject.getAssociation().getConnection();
53          for (final Iterator endIt = ends.iterator(); endIt.hasNext();)
54          {
55              final AssociationEnd end = (AssociationEnd)endIt.next();
56              if (!metaObject.equals(end))
57              {
58                  return end;
59              }
60          }
61          return null;
62      }
63  
64      /***
65       * @see org.andromda.metafacades.uml14.ModelElementFacadeLogic#handleGetName()
66       */
67      protected String handleGetName()
68      {
69          String name = super.handleGetName();
70  
71          // if name is empty, then get the name from the type
72          if (StringUtils.isEmpty(name))
73          {
74              final ClassifierFacade type = this.getType();
75              if (type != null)
76              {
77                  name = StringUtils.uncapitalize(StringUtils.trimToEmpty(type.getName()));
78              }
79              if (this.isMany() && this.isPluralizeAssociationEndNames())
80              {
81                  name = StringUtilsHelper.pluralize(name);
82              }
83          }
84          final String nameMask =
85              String.valueOf(this.getConfiguredProperty(UMLMetafacadeProperties.CLASSIFIER_PROPERTY_NAME_MASK));
86          return NameMasker.mask(
87              name,
88              nameMask);
89      }
90  
91      /***
92       * Indicates whether or not we should pluralize association end names.
93       *
94       * @return true/false
95       */
96      private boolean isPluralizeAssociationEndNames()
97      {
98          final Object value = this.getConfiguredProperty(UMLMetafacadeProperties.PLURALIZE_ASSOCIATION_END_NAMES);
99          return value != null && Boolean.valueOf(String.valueOf(value)).booleanValue();
100     }
101 
102     /***
103      * @see org.andromda.metafacades.uml.AssociationEndFacade#getType()
104      */
105     protected Object handleGetType()
106     {
107         return metaObject.getParticipant();
108     }
109 
110     /***
111      * @see org.andromda.metafacades.uml.AssociationEndFacade#isOne2Many()
112      */
113     protected boolean handleIsOne2Many()
114     {
115         return !this.isMany() && this.getOtherEnd().isMany();
116     }
117 
118     /***
119      * @see org.andromda.metafacades.uml.AssociationEndFacade#isMany2Many()
120      */
121     protected boolean handleIsMany2Many()
122     {
123         return this.isMany() && this.getOtherEnd().isMany();
124     }
125 
126     /***
127      * @see org.andromda.metafacades.uml.AssociationEndFacade#isOne2One()
128      */
129     protected boolean handleIsOne2One()
130     {
131         return !this.isMany() && !this.getOtherEnd().isMany();
132     }
133 
134     /***
135      * @see org.andromda.metafacades.uml.AssociationEndFacade#isMany2One()
136      */
137     protected boolean handleIsMany2One()
138     {
139         return this.isMany() && !this.getOtherEnd().isMany();
140     }
141 
142     /***
143      * @see org.andromda.metafacades.uml.AssociationEndFacade#isMany()
144      */
145     protected boolean handleIsMany()
146     {
147         boolean isMany = false;
148         final Multiplicity multiplicity = this.metaObject.getMultiplicity();
149 
150         // we'll say a null multiplicity is 1
151         if (multiplicity != null)
152         {
153             final Collection ranges = multiplicity.getRange();
154             if (ranges != null && !ranges.isEmpty())
155             {
156                 final Iterator rangeIt = ranges.iterator();
157                 while (rangeIt.hasNext())
158                 {
159                     final MultiplicityRange multiplicityRange = (MultiplicityRange)rangeIt.next();
160                     final int upper = multiplicityRange.getUpper();
161                     isMany = upper > 1 || upper < 0;
162                 }
163             }
164         }
165         return isMany;
166     }
167 
168     /***
169      * @see org.andromda.metafacades.uml.AssociationEndFacade#isOrdered()
170      */
171     protected boolean handleIsOrdered()
172     {
173         boolean ordered = false;
174 
175         final OrderingKind ordering = metaObject.getOrdering();
176 
177         // no ordering is 'unordered'
178         if (ordering != null)
179         {
180             ordered = ordering.equals(OrderingKindEnum.OK_ORDERED);
181         }
182 
183         return ordered;
184     }
185 
186     /***
187      * @see org.andromda.metafacades.uml.AssociationEndFacade#isAggregation()
188      */
189     protected boolean handleIsAggregation()
190     {
191         return AggregationKindEnum.AK_AGGREGATE.equals(metaObject.getAggregation());
192     }
193 
194     /***
195      * @see org.andromda.metafacades.uml.AssociationEndFacade#isComposition()
196      */
197     protected boolean handleIsComposition()
198     {
199         return AggregationKindEnum.AK_COMPOSITE.equals(metaObject.getAggregation());
200     }
201 
202     /***
203      * @see org.andromda.metafacades.uml.AssociationEndFacade#isReadOnly()
204      */
205     protected boolean handleIsReadOnly()
206     {
207         return ChangeableKindEnum.CK_FROZEN.equals(metaObject.getChangeability());
208     }
209 
210     /***
211      * @see org.andromda.metafacades.uml.AssociationEndFacade#isNavigable()
212      */
213     protected boolean handleIsNavigable()
214     {
215         return metaObject.isNavigable();
216     }
217 
218     /***
219      * @see org.andromda.metafacades.uml.AssociationEndFacade#getGetterName()
220      */
221     protected java.lang.String handleGetGetterName()
222     {
223         return UMLMetafacadeUtils.getGetterPrefix(this.getType()) + StringUtilsHelper.capitalize(this.getName());
224     }
225 
226     /***
227      * @see org.andromda.metafacades.uml.AssociationEndFacade#getSetterName()
228      */
229     protected java.lang.String handleGetSetterName()
230     {
231         return "set" + StringUtils.capitalize(this.getName());
232     }
233 
234     /***
235      * @see org.andromda.metafacades.uml.AssociationEndFacade#getAssociation()
236      */
237     protected Object handleGetAssociation()
238     {
239         return metaObject.getAssociation();
240     }
241 
242     /***
243      * @see org.andromda.metafacades.uml.AssociationEndFacade#getGetterSetterTypeName()
244      */
245     protected String handleGetGetterSetterTypeName()
246     {
247         String name = null;
248         if (this.isMany())
249         {
250             final TypeMappings mappings = this.getLanguageMappings();
251             if (mappings != null)
252             {
253                 name =
254                     this.isOrdered() ? mappings.getTo(UMLProfile.LIST_TYPE_NAME)
255                                      : mappings.getTo(UMLProfile.COLLECTION_TYPE_NAME);
256             }
257 
258             // set this association end's type as a template parameter if required
259             if (BooleanUtils.toBoolean(
260                     ObjectUtils.toString(this.getConfiguredProperty(UMLMetafacadeProperties.ENABLE_TEMPLATING))))
261             {
262                 name = name + "<" + this.getType().getFullyQualifiedName() + ">";
263             }
264         }
265         if (name == null && this.getType() != null)
266         {
267             name = this.getType().getFullyQualifiedName();
268         }
269         return name;
270     }
271 
272     /***
273      * @see org.andromda.metafacades.uml.AssociationEndFacade#isRequired()
274      */
275     protected boolean handleIsRequired()
276     {
277         final int lower = this.getMultiplicityRangeLower();
278         return lower >= 1;
279     }
280 
281     /***
282      * @see org.andromda.metafacades.uml.AssociationEndFacade#isChild()
283      */
284     protected boolean handleIsChild()
285     {
286         return this.getOtherEnd() != null && this.getOtherEnd().isComposition();
287     }
288 
289     /***
290      * Returns the lower range of the multiplicty for the passed in associationEnd
291      *
292      * @return int the lower range of the multiplicty or 1 if it isn't defined.
293      */
294     private int getMultiplicityRangeLower()
295     {
296         Integer lower = null;
297         final Multiplicity multiplicity = this.metaObject.getMultiplicity();
298         if (multiplicity != null)
299         {
300             final Collection ranges = multiplicity.getRange();
301             if (ranges != null && !ranges.isEmpty())
302             {
303                 final Iterator rangeIt = ranges.iterator();
304                 while (rangeIt.hasNext())
305                 {
306                     final MultiplicityRange multiplicityRange = (MultiplicityRange)rangeIt.next();
307                     lower = new Integer(multiplicityRange.getLower());
308                 }
309             }
310         }
311         if (lower == null)
312         {
313             final String defaultMultiplicity = this.getDefaultMultiplicity();
314             if (defaultMultiplicity.startsWith("0"))
315             {
316                 lower = new Integer(0);
317             }
318             else
319             {
320                 lower = new Integer(1);
321             }
322         }
323         return lower.intValue();
324     }
325 
326     /***
327      * Gets the default multiplicity for this attribute (the
328      * multiplicity if none is defined).
329      *
330      * @return the defautl multiplicity as a String.
331      */
332     private String getDefaultMultiplicity()
333     {
334         return ObjectUtils.toString(this.getConfiguredProperty(UMLMetafacadeProperties.DEFAULT_MULTIPLICITY));
335     }
336     
337     /***
338      * Get the UML upper multiplicity
339      * Not implemented for UML1.4
340      */
341     protected int handleGetUpper()
342     {
343         throw new java.lang.UnsupportedOperationException("'upper' is not a UML1.4 feature");
344      }
345 
346     /***
347      * Get the UML lower multiplicity
348      */
349     protected int handleGetLower()
350     {
351         return this.getMultiplicityRangeLower();
352     }
353 }