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
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
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
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
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 }