001package org.andromda.metafacades.uml14;
002
003import java.util.Collection;
004import java.util.Iterator;
005import org.andromda.metafacades.uml.NameMasker;
006import org.andromda.metafacades.uml.UMLMetafacadeProperties;
007import org.andromda.metafacades.uml.UMLMetafacadeUtils;
008import org.andromda.metafacades.uml.UMLProfile;
009import org.andromda.utils.StringUtilsHelper;
010import org.apache.commons.lang.StringUtils;
011import org.omg.uml.behavioralelements.statemachines.Event;
012import org.omg.uml.foundation.core.Classifier;
013import org.omg.uml.foundation.core.Operation;
014import org.omg.uml.foundation.core.Parameter;
015import org.omg.uml.foundation.datatypes.Expression;
016import org.omg.uml.foundation.datatypes.ParameterDirectionKindEnum;
017
018/**
019 * Metaclass facade implementation.
020 * @author Bob Fields
021 */
022public class ParameterFacadeLogicImpl
023    extends ParameterFacadeLogic
024{
025    private static final long serialVersionUID = 34L;
026    /**
027     * @param metaObject
028     * @param context
029     */
030    public ParameterFacadeLogicImpl(
031        Parameter metaObject,
032        String context)
033    {
034        super(metaObject, context);
035    }
036
037    /**
038     * Overridden to provide name masking.
039     *
040     * @see org.andromda.metafacades.uml.ModelElementFacade#getName()
041     */
042    @Override
043    protected String handleGetName()
044    {
045        final String nameMask = String.valueOf(this.getConfiguredProperty(UMLMetafacadeProperties.PARAMETER_NAME_MASK));
046        String name = NameMasker.mask(
047            super.handleGetName(),
048            nameMask);
049        // UML14 does not support multiplicity * on parameters
050        /*final boolean templating = Boolean.parseBoolean(String.valueOf(
051            this.getConfiguredProperty(UMLMetafacadeProperties.ENABLE_TEMPLATING)));
052        final boolean arrayType = this.getType().isArrayType();
053        if (this.handleIsMany() && this.isPluralizeParameterNames())
054        {
055            name = StringUtilsHelper.pluralize(name);
056        }*/
057
058        return name;
059    }
060
061    /*
062     * Indicates whether or not we should pluralize association end names.
063     *
064     * @return true/false
065    private boolean isPluralizeParameterNames()
066    {
067        final Object value = this.getConfiguredProperty(UMLMetafacadeProperties.PLURALIZE_PARAMETER_NAMES);
068        return value != null && Boolean.valueOf(String.valueOf(value)).booleanValue();
069    }
070     */
071
072    /**
073     * @see org.andromda.metafacades.uml.ParameterFacade#getGetterName()
074     */
075    @Override
076    protected String handleGetGetterName()
077    {
078        return UMLMetafacadeUtils.getGetterPrefix(this.getType(), this.getLower()) + StringUtilsHelper.capitalize(this.getName());
079    }
080
081    /**
082     * @see org.andromda.metafacades.uml.ParameterFacade#getSetterName()
083     */
084    @Override
085    protected String handleGetSetterName()
086    {
087        return "set" + StringUtilsHelper.capitalize(this.getName());
088    }
089
090    /**
091     * @see org.andromda.core.metafacade.MetafacadeBase#getValidationOwner()
092     */
093    public Object getValidationOwner()
094    {
095        Object owner = this.getOperation();
096
097        if (owner == null)
098        {
099            owner = this.getEvent();
100        }
101
102        return owner;
103    }
104
105    /**
106     * @see org.andromda.metafacades.uml.ParameterFacade#getDefaultValue()
107     */
108    //@SuppressWarnings("null")
109    @Override
110    public String handleGetDefaultValue()
111    {
112        String defaultValue = null;
113        final Expression expression = this.metaObject.getDefaultValue();
114        //return expression == null ? "" : expression.getBody();
115        if (expression != null)
116        {
117            defaultValue = expression.getBody();
118        }
119        // Put single or double quotes around default in case modeler forgot to do it. Most templates
120        // declare Type parameter = $parameter.defaultValue, requiring quotes around the value
121        if (StringUtils.isNotBlank(defaultValue) && defaultValue != null)
122        {
123            String typeName = this.metaObject.getType().getName();
124            if ("String".equals(typeName) && defaultValue.indexOf('"')<0)
125            {
126                defaultValue = '"' + defaultValue + '"';
127            }
128            else if (("char".equals(typeName) || "Character".equals(typeName))
129                && defaultValue.indexOf('\'')<0)
130            {
131                defaultValue = "'" + defaultValue.charAt(0) + '\'';
132            }
133            //if (!defaultValue.equals("")) System.out.println("Attribute.handleGetDefaultValue " + this.getName() + " typeName=" + typeName + " defaultValue=" + defaultValue + " upper=" + this.metaObject.getUpper());
134        }
135        if (defaultValue==null) defaultValue="";
136        return defaultValue;
137    }
138
139    /**
140     * @see org.andromda.metafacades.uml.ParameterFacade#isDefaultValuePresent()
141     */
142    @Override
143    public boolean handleIsDefaultValuePresent()
144    {
145        return StringUtils.isNotBlank(this.getDefaultValue());
146    }
147
148    /**
149     * @return this.getType().getFullyQualifiedName()
150     * @see org.andromda.metafacades.uml.ParameterFacade#getType()
151     */
152    protected String handleGetGetterSetterTypeName()
153    {
154        if (this.getType()==null)
155        {
156            return "";
157        }
158        else
159        {
160            // Multiplicity in return type is only supported in UML2
161            return this.getType().getFullyQualifiedName();
162        }
163    }
164
165    /**
166     * @see org.andromda.metafacades.uml.ParameterFacade#getGetterSetterTypeNameImpl()
167     */
168    @Override
169    protected String handleGetGetterSetterTypeNameImpl()
170    {
171        return getGetterSetterTypeName();
172    }
173
174    /**
175     * @see org.andromda.metafacades.uml.ParameterFacade#getType()
176     */
177    @Override
178    protected Classifier handleGetType()
179    {
180        return this.metaObject.getType();
181    }
182
183    /**
184     * UML2 Only: Returns "NONE" always.
185     * @return "NONE"
186     * @see org.andromda.metafacades.uml.ParameterFacade#isException()
187     */
188    @Override
189    public String handleGetEffect()
190    {
191        return "NONE";
192    }
193
194    /**
195     * UML2 Only: Returns false always.
196     * @return false
197     * @see org.andromda.metafacades.uml.ParameterFacade#isException()
198     */
199    @Override
200    public boolean handleIsException()
201    {
202        return false;
203    }
204
205    /**
206     * NOT IMPLEMENTED: UML2 only: returns false always
207     * @return false
208     * @see org.andromda.metafacades.uml.ParameterFacade#isOrdered()
209     */
210    @Override
211    protected boolean handleIsOrdered()
212    {
213        return false;
214    }
215
216    /**
217     * @see org.andromda.metafacades.uml.ParameterFacade#isReturn()
218     */
219    @Override
220    public boolean handleIsReturn()
221    {
222        return ParameterDirectionKindEnum.PDK_RETURN.equals(this.metaObject.getKind());
223    }
224
225    /**
226     * @see org.andromda.metafacades.uml.ParameterFacade#isRequired()
227     */
228    @Override
229    protected boolean handleIsRequired()
230    {
231        return !this.hasStereotype(UMLProfile.STEREOTYPE_NULLABLE);
232    }
233
234    /**
235     * @return !this.hasStereotype(UMLProfile.STEREOTYPE_UNIQUE)
236     * @see org.andromda.metafacades.uml.ParameterFacade#isUnique()
237     */
238    @Override
239    protected boolean handleIsUnique()
240    {
241        return !this.hasStereotype(UMLProfile.STEREOTYPE_UNIQUE);
242    }
243
244    /**
245     * @see org.andromda.metafacades.uml.ParameterFacade#getOperation()
246     */
247    @Override
248    protected Operation handleGetOperation()
249    {
250        Operation parameterOperation = null;
251        final Collection<Operation> allOperations = UML14MetafacadeUtils.getModel().getCore().getOperation().refAllOfType();
252        for (final Iterator iterator = allOperations.iterator(); iterator.hasNext() && parameterOperation == null;)
253        {
254            final Operation operation = (Operation)iterator.next();
255            if (operation.getParameter().contains(this.metaObject))
256            {
257                parameterOperation = operation;
258            }
259        }
260        return parameterOperation;
261    }
262
263    /**
264     * @see org.andromda.metafacades.uml.ParameterFacade#getEvent()
265     */
266    @Override
267    protected Event handleGetEvent()
268    {
269        Event parameterEvent = null;
270        final Collection<Event> allEvents = UML14MetafacadeUtils.getModel().getStateMachines().getEvent().refAllOfType();
271        for (final Iterator<Event> iterator = allEvents.iterator(); iterator.hasNext() && parameterEvent == null;)
272        {
273            final Event event = iterator.next();
274            if (event.getParameter().contains(this.metaObject))
275            {
276                parameterEvent = event;
277            }
278        }
279        return parameterEvent;
280    }
281
282    /**
283     * @see org.andromda.metafacades.uml.ParameterFacade#isReadable()
284     */
285    @Override
286    protected boolean handleIsReadable()
287    {
288        return this.isInParameter() || this.isInoutParameter();
289    }
290
291    /**
292     * @see org.andromda.metafacades.uml.ParameterFacade#isWritable()
293     */
294    @Override
295    protected boolean handleIsWritable()
296    {
297        return this.isOutParameter() || this.isInoutParameter();
298    }
299
300    /**
301     * @see org.andromda.metafacades.uml.ParameterFacade#isInParameter()
302     */
303    @Override
304    protected boolean handleIsInParameter()
305    {
306        return ParameterDirectionKindEnum.PDK_IN.equals(this.metaObject.getKind());
307    }
308
309    /**
310     * @see org.andromda.metafacades.uml.ParameterFacade#isOutParameter()
311     */
312    @Override
313    protected boolean handleIsOutParameter()
314    {
315        return ParameterDirectionKindEnum.PDK_OUT.equals(this.metaObject.getKind());
316    }
317
318    /**
319     * @see org.andromda.metafacades.uml.ParameterFacade#isInoutParameter()
320     */
321    @Override
322    protected boolean handleIsInoutParameter()
323    {
324        return ParameterDirectionKindEnum.PDK_INOUT.equals(this.metaObject.getKind());
325    }
326
327    /**
328     * Get the UML upper multiplicity
329     * Not implemented for UML1.4
330     * @return false always
331     * @see org.andromda.metafacades.uml.ParameterFacade#isMany()
332     */
333    //@Override
334    protected boolean handleIsMany()
335    {
336        boolean isMany = false;
337        if (null!=this.getType())
338        {
339            isMany = this.getType().isArrayType();
340        }
341        return isMany;
342     }
343
344    /**
345     * Get the UML upper multiplicity
346     * Not implemented for UML1.4
347     * @return -1 (UnlimitedNatural) is isMany, otherwise 1
348     * @see org.andromda.metafacades.uml.ParameterFacade#getUpper()
349     */
350    protected int handleGetUpper()
351    {
352        if (this.isMany())
353        {
354            return -1;
355        }
356        return 1;
357     }
358
359    /**
360     * Get the UML lower multiplicity
361     * @return 1 if primitive, 0 otherwise
362     * @see org.andromda.metafacades.uml.ParameterFacade#getLower()
363     */
364    protected int handleGetLower()
365    {
366        if (!this.hasStereotype("Nullable")
367            && this.getType().isPrimitive())
368        {
369            return 1;
370        }
371        return 0;
372    }
373
374    /**
375     * Indicates whether or not we should pluralize parameter names.
376     *
377     * @return true/false
378     */
379    @SuppressWarnings("unused")
380    private boolean isPluralizeParameterNames()
381    {
382        final Object value = this.getConfiguredProperty(UMLMetafacadeProperties.PLURALIZE_PARAMETER_NAMES);
383        return value != null && Boolean.valueOf(String.valueOf(value));
384    }
385}