View Javadoc
1   package org.andromda.metafacades.emf.uml22;
2   
3   import org.andromda.metafacades.uml.ClassifierFacade;
4   import org.andromda.metafacades.uml.NameMasker;
5   import org.andromda.metafacades.uml.TypeMappings;
6   import org.andromda.metafacades.uml.UMLMetafacadeProperties;
7   import org.andromda.metafacades.uml.UMLMetafacadeUtils;
8   import org.andromda.metafacades.uml.UMLProfile;
9   import org.andromda.utils.StringUtilsHelper;
10  import org.apache.commons.lang.BooleanUtils;
11  import org.apache.commons.lang.ObjectUtils;
12  import org.apache.commons.lang.StringUtils;
13  import org.eclipse.uml2.uml.AggregationKind;
14  import org.eclipse.uml2.uml.Association;
15  import org.eclipse.uml2.uml.LiteralUnlimitedNatural;
16  import org.eclipse.uml2.uml.Type;
17  
18  /**
19   * MetafacadeLogic implementation for
20   * org.andromda.metafacades.uml.AssociationEndFacade.
21   *
22   * @see org.andromda.metafacades.uml.AssociationEndFacade
23   * @author Bob Fields
24   */
25  public class AssociationEndFacadeLogicImpl
26      extends AssociationEndFacadeLogic
27  {
28      private static final long serialVersionUID = 34L;
29      /**
30       * @param metaObjectIn
31       * @param context
32       */
33      public AssociationEndFacadeLogicImpl(
34          final AssociationEnd metaObjectIn,
35          final String context)
36      {
37          super(metaObjectIn, context);
38      }
39  
40      /**
41       * @see org.andromda.metafacades.uml.AssociationEndFacade#isOne2One()
42       */
43      @Override
44      protected boolean handleIsOne2One()
45      {
46          return !this.isMany() && !this.getOtherEnd().isMany();
47      }
48  
49      /**
50       * @see org.andromda.metafacades.uml.AssociationEndFacade#isOne2Many()
51       */
52      @Override
53      protected boolean handleIsOne2Many()
54      {
55          return !this.isMany() && this.getOtherEnd().isMany();
56      }
57  
58      /**
59       * @see org.andromda.metafacades.uml.AssociationEndFacade#isMany2One()
60       */
61      @Override
62      protected boolean handleIsMany2One()
63      {
64          return this.isMany() && !this.getOtherEnd().isMany();
65      }
66  
67      /**
68       * @see org.andromda.metafacades.uml.AssociationEndFacade#isMany2Many()
69       */
70      @Override
71      protected boolean handleIsMany2Many()
72      {
73          return this.isMany() && this.getOtherEnd().isMany();
74      }
75  
76      /**
77       * @see org.andromda.metafacades.uml.AssociationEndFacade#isAggregation()
78       */
79      @Override
80      protected boolean handleIsAggregation()
81      {
82          return UmlUtilities.getOppositeAssociationEnd(this.metaObject).getAggregation().equals(AggregationKind.SHARED_LITERAL);
83      }
84  
85      /**
86       * @see org.andromda.metafacades.uml.AssociationEndFacade#isComposition()
87       */
88      @Override
89      protected boolean handleIsComposition()
90      {
91          return UmlUtilities.getOppositeAssociationEnd(this.metaObject).getAggregation().equals(AggregationKind.COMPOSITE_LITERAL);
92      }
93  
94      /**
95       * UML2 Only: Returns false always.
96       * @see org.andromda.metafacades.uml.AssociationEndFacade#isLeaf()
97       */
98      @Override
99      public boolean handleIsLeaf()
100     {
101         return this.metaObject.isLeaf();
102     }
103 
104     /**
105      * @see org.andromda.metafacades.uml.AssociationEndFacade#isOrdered()
106      */
107     @Override
108     protected boolean handleIsOrdered()
109     {
110         return this.metaObject.isOrdered();
111     }
112 
113     /**
114      * @see org.andromda.metafacades.uml.AssociationEndFacade#isReadOnly()
115      */
116     @Override
117     protected boolean handleIsReadOnly()
118     {
119         return this.metaObject.isReadOnly();
120     }
121 
122     /**
123      * @see org.andromda.metafacades.uml.AssociationEndFacade#isNavigable()
124      */
125     @Override
126     protected boolean handleIsNavigable()
127     {
128         return this.metaObject.isNavigable();
129     }
130 
131     /**
132      * UML2 Only: Returns false always.
133      * @see org.andromda.metafacades.uml.AssociationEndFacade#isUnique()
134      */
135     @Override
136     public boolean handleIsUnique()
137     {
138         return this.metaObject.isUnique();
139     }
140 
141     /**
142      * @see org.andromda.metafacades.emf.uml22.ModelElementFacadeLogic#handleGetName()
143      */
144     @Override
145     protected String handleGetName()
146     {
147         String name = super.handleGetName();
148 
149         // if name is empty, then get the name from the type
150         if (StringUtils.isBlank(name))
151         {
152             final ClassifierFacade type = this.getType();
153             if (type != null)
154             {
155                 name = StringUtils.uncapitalize(StringUtils.trimToEmpty(type.getName()));
156             }
157         }
158         if (this.isMany() && this.isPluralizeAssociationEndNames())
159         {
160             name = StringUtilsHelper.pluralize(name);
161         }
162         final String nameMask =
163             String.valueOf(this.getConfiguredProperty(UMLMetafacadeProperties.CLASSIFIER_PROPERTY_NAME_MASK));
164         return NameMasker.mask(
165             name,
166             nameMask);
167     }
168 
169     /**
170      * Indicates whether or not we should pluralize association end names.
171      *
172      * @return true/false
173      */
174     private boolean isPluralizeAssociationEndNames()
175     {
176         final Object value = this.getConfiguredProperty(UMLMetafacadeProperties.PLURALIZE_ASSOCIATION_END_NAMES);
177         return value != null && Boolean.valueOf(String.valueOf(value)).booleanValue();
178     }
179 
180     /**
181      * @see org.andromda.metafacades.uml.AssociationEndFacade#getGetterName()
182      */
183     @Override
184     protected String handleGetGetterName()
185     {
186         return UMLMetafacadeUtils.getGetterPrefix(this.getType()) + StringUtils.capitalize(this.handleGetName());
187     }
188 
189     /**
190      * @see org.andromda.metafacades.uml.AssociationEndFacade#getSetterName()
191      */
192     @Override
193     protected String handleGetSetterName()
194     {
195         return "set" + StringUtils.capitalize(this.handleGetName());
196     }
197 
198     /**
199      * @see org.andromda.metafacades.uml.AssociationEndFacade#getAdderName()
200      */
201     @Override
202     protected String handleGetAdderName()
203     {
204         return "add" + StringUtils.capitalize(this.handleGetName());
205     }
206 
207     /**
208      * @see org.andromda.metafacades.uml.AssociationEndFacade#getRemoverName()
209      */
210     @Override
211     protected String handleGetRemoverName()
212     {
213         return "remove" + StringUtils.capitalize(this.handleGetName());
214     }
215 
216     /**
217      * @see org.andromda.metafacades.uml.AssociationEndFacade#isBindingDependenciesPresent()
218      */
219     @Override
220     protected boolean handleIsBidirectional()
221     {
222         return isNavigable() && getOtherEnd().isNavigable();
223     }
224 
225     /**
226      * @see org.andromda.metafacades.uml.AssociationEndFacade#getGetterSetterTypeName()
227      */
228     @Override
229     protected String handleGetGetterSetterTypeName()
230     {
231         String name = null;
232         if (this.getUpper() > 1 || this.getUpper() == LiteralUnlimitedNatural.UNLIMITED)
233         {
234             final TypeMappings mappings = this.getLanguageMappings();
235             if (mappings != null)
236             {
237                 // TODO Use 'Unique' attribute to determine List/Set type
238                 name = mappings.getTo(this.isOrdered() ? UMLProfile.LIST_TYPE_NAME : UMLProfile.COLLECTION_TYPE_NAME);
239             }
240 
241             // set this association end's type as a template parameter if required
242             if (this.getType() != null && BooleanUtils.toBoolean(
243                     ObjectUtils.toString(this.getConfiguredProperty(UMLMetafacadeProperties.ENABLE_TEMPLATING))))
244             {
245                 String type = this.getType().getFullyQualifiedName();
246                 /*Collection<GeneralizableElementFacade> specializations = this.getType().getAllSpecializations();
247                 if ((specializations != null && !specializations.isEmpty()))
248                 {
249                     name += "<? extends " + type + '>';
250                 }
251                 else
252                 {*/
253                     name += '<' + type + '>';
254                 //}
255             }
256         }
257         if (name == null && this.getType() != null)
258         {
259             name = this.getType().getFullyQualifiedName();
260         }
261         return name;
262     }
263 
264     /**
265      * @see org.andromda.metafacades.uml.AssociationEndFacade#isMany()
266      */
267     @Override
268     protected boolean handleIsMany()
269     {
270         // Because of MD11.5 (their multiplicity are String), we cannot use
271         // isMultiValued()
272         return this.getUpper() > 1 || this.getUpper() == LiteralUnlimitedNatural.UNLIMITED
273                || (this.getType() != null && (this.getType().isArrayType() || this.getType().isCollectionType()));
274     }
275 
276     /**
277      * @see org.andromda.metafacades.uml.AssociationEndFacade#isRequired()
278      */
279     @Override
280     protected boolean handleIsRequired()
281     {
282         return (this.getLower() > 0);
283     }
284 
285     /**
286      * @see org.andromda.metafacades.uml.AssociationEndFacade#isChild()
287      */
288     @Override
289     protected boolean handleIsChild()
290     {
291         return this.getOtherEnd() != null && this.getOtherEnd().isComposition();
292     }
293 
294     /**
295      * @see org.andromda.metafacades.uml.AssociationEndFacade#getOtherEnd()
296      */
297     @Override
298     protected AssociationEnd handleGetOtherEnd()
299     {
300         return UmlUtilities.getOppositeAssociationEnd(this.metaObject);
301     }
302 
303     /**
304      * @see org.andromda.metafacades.uml.AssociationEndFacade#getAssociation()
305      */
306     @Override
307     protected Association handleGetAssociation()
308     {
309         return this.metaObject.getAssociation();
310     }
311 
312     /**
313      * @see org.andromda.metafacades.uml.AssociationEndFacade#getAggregationKind()
314      */
315     @Override
316     protected String handleGetAggregationKind()
317     {
318         return this.metaObject.getAggregation().name();
319     }
320 
321     /**
322      * @see org.andromda.metafacades.uml.AssociationEndFacade#getType()
323      */
324     @Override
325     protected Type handleGetType()
326     {
327         // In uml1.4 facade, it returns getParticipant
328         return this.metaObject.getType();
329     }
330 
331     /**
332      * @see org.andromda.core.metafacade.MetafacadeBase#getValidationOwner()
333      */
334     @Override
335     public Object getValidationOwner()
336     {
337         return this.getType();
338     }
339 
340     /**
341      * Get the UML upper multiplicity Not implemented for UML1.4
342      * @return int upperMultiplicity, based on UML multiplicity, default 1
343      */
344     @Override
345     protected int handleGetUpper()
346     {
347         // MD11.5 Exports multiplicity as String
348         return UmlUtilities.parseMultiplicity(this.metaObject.getUpperValue(), 1);
349     }
350 
351     /**
352      * Get the UML lower multiplicity Not implemented for UML1.4
353      * @see org.andromda.metafacades.uml.AssociationEndFacade#getLower()
354      */
355     @Override
356     protected int handleGetLower()
357     {
358         // MD11.5 Exports multiplicity as String
359         return UmlUtilities.parseLowerMultiplicity(this.metaObject.getLowerValue(), this.getType(), "1");
360     }
361 
362     /**
363      * Get the UML Default Value for this AssociationEnd
364      * @see org.andromda.metafacades.uml.AssociationEndFacade#getDefault()
365      */
366     @Override
367     protected String handleGetDefault()
368     {
369         return this.metaObject.getDefault();
370     }
371 
372     /**
373      * Override to change public to private, since we provide accessors in generated code
374      * Allows for protected, package level visibility in the model
375      * @return String visibility
376      */
377     @Override
378     protected String handleGetVisibility()
379     {
380         String visibility = super.handleGetVisibility();
381         if (visibility==null || visibility.equals("private"))
382         {
383             visibility = "public";
384         }
385         return visibility;
386     }
387 
388     /**
389      * @see org.andromda.metafacades.uml.AssociationEndFacade#isDerived()
390      */
391     @Override
392     protected boolean handleIsDerived()
393     {
394         return this.metaObject.isDerived();
395     }
396 
397     /**
398      * @see org.andromda.metafacades.uml.AttributeFacade#isStatic()
399      */
400     @Override
401     protected boolean handleIsStatic()
402     {
403         return this.metaObject.isStatic();
404     }
405 }