001package org.andromda.cartridges.webservice.metafacades;
002
003import java.util.Collection;
004import org.andromda.cartridges.webservice.WebServiceGlobals;
005import org.andromda.core.metafacade.MetafacadeBase;
006import org.andromda.core.metafacade.ModelValidationMessage;
007import org.andromda.metafacades.uml.ClassifierFacade;
008import org.andromda.translation.ocl.validation.OCLIntrospector;
009import org.andromda.utils.StringUtilsHelper;
010import org.apache.commons.lang.StringUtils;
011import org.apache.log4j.Logger;
012
013/**
014 * MetafacadeLogic implementation for org.andromda.cartridges.webservice.metafacades.WebServiceParameter.
015 *
016 * @see org.andromda.cartridges.webservice.metafacades.WebServiceParameter
017 * @author Bob Fields
018 */
019public class WebServiceParameterLogicImpl
020        extends WebServiceParameterLogic
021{
022    private static final long serialVersionUID = 34L;
023    // ---------------- constructor -------------------------------
024
025    /**
026     * @param metaObject
027     * @param context
028     */
029    public WebServiceParameterLogicImpl(Object metaObject, String context)
030    {
031        super(metaObject, context);
032    }
033
034    /**
035     * The logger instance.
036     */
037    private static final Logger logger = Logger.getLogger(WebServiceParameterLogicImpl.class);
038
039    /**
040     * @return !this.isRequired()
041     * @see org.andromda.cartridges.webservice.metafacades.WebServiceParameter#isNillable()
042     */
043    protected boolean handleIsNillable()
044    {
045        return !this.isRequired();
046    }
047
048    /**
049     * @return testTypeName
050     * @see org.andromda.cartridges.webservice.metafacades.WebServiceParameter#getTestTypeName()
051     */
052    protected String handleGetTestTypeName()
053    {
054        String testTypeName = null;
055        final ClassifierFacade type = this.getType();
056        if (type instanceof WSDLType || type instanceof WSDLEnumerationType)
057        {
058            ClassifierFacade service = this.getOperation().getOwner();
059            if (service instanceof WebService)
060            {
061                WebService webService = (WebService)service;
062                final String testPackageName = webService.getTestPackageName();
063                if (type instanceof WSDLType)
064                {
065                    final WSDLType wsdlType = (WSDLType)type;
066                    if (!webService.isRpcStyle() && wsdlType.isArrayType())
067                    {
068                        testTypeName = testPackageName + '.' + wsdlType.getWsdlArrayName();
069                    }
070                    else if (!type.isDataType())
071                    {
072                        testTypeName = testPackageName + '.' + wsdlType.getName();
073                    }
074                }
075                else
076                {
077                    final WSDLEnumerationType wsdlType = (WSDLEnumerationType)type;
078                    if (!webService.isRpcStyle() && wsdlType.isArrayType())
079                    {
080                        testTypeName = testPackageName + '.' + wsdlType.getWsdlArrayName();
081                    }
082                    else if (!type.isDataType())
083                    {
084                        testTypeName = testPackageName + '.' + wsdlType.getName();
085                    }
086                }
087            }
088            if (testTypeName == null)
089            {
090                testTypeName = this.getType().getFullyQualifiedName();
091            }
092        }
093        return testTypeName;
094    }
095
096    /**
097     * The property defining the web service XML Adapter for Jaxb.
098     */
099    private static final String USE_ATTRIBUTES = "useAttributes";
100
101    /**
102     * @see org.andromda.cartridges.webservice.metafacades.WebServiceParameterLogic#handleIsAttribute()
103     */
104    @Override
105    protected boolean handleIsAttribute()
106    {
107        boolean isAttribute = this.hasStereotype(WebServiceGlobals.STEREOTYPE_XML_ATTRIBUTE);
108        if (!isAttribute)
109        {
110            String attributes = String.valueOf(this.getConfiguredProperty(USE_ATTRIBUTES));
111            if (StringUtils.isEmpty(attributes))
112            {
113                attributes = "true";
114            }
115            isAttribute = Boolean.parseBoolean(attributes);
116        }
117        return isAttribute;
118    }
119
120    /**
121     * @see org.andromda.cartridges.webservice.metafacades.WebServiceParameterLogic#handleIsElement()
122     */
123    @Override
124    protected boolean handleIsElement()
125    {
126        boolean isAttribute = this.hasStereotype(WebServiceGlobals.STEREOTYPE_XML_ELEMENT);
127        if (!isAttribute)
128        {
129            String attributes = String.valueOf(this.getConfiguredProperty(USE_ATTRIBUTES));
130            if (StringUtils.isEmpty(attributes))
131            {
132                attributes = "true";
133            }
134            isAttribute = Boolean.parseBoolean(attributes);
135        }
136        return !isAttribute;
137    }
138
139    private static final String DEFAULT = "default";
140    private static final String EMPTY_STRING = "";
141    private static final String BOOLEAN_FALSE = "false";
142    //private static final String DEFAULT_TYPE = "PathParam";
143
144    private static final String QUOTE = "\"";
145    private static final String RPARENS = "(";
146    private static final String LPARENS = ")";
147    /**
148     * @see org.andromda.cartridges.webservice.metafacades.WebServiceParameterLogic#getRestParamType()
149     */
150    @Override
151    protected String handleGetRestParamType()
152    {
153        String paramType = (String)this.findTaggedValue(WebServiceGlobals.REST_PARAM_TYPE);
154        if (StringUtils.isBlank(paramType) || paramType.equals(DEFAULT))
155        {
156            paramType = EMPTY_STRING;
157        }
158        else
159        {
160            String pathSegment = handleGetRestPathSegment();
161            if (StringUtils.isBlank(pathSegment))
162            {
163                // paramType always needed with annotation
164                pathSegment = this.getName();
165            }
166            paramType = "@javax.ws.rs." + paramType + RPARENS + QUOTE + pathSegment + QUOTE + LPARENS;
167        }
168
169        return paramType;
170    }
171
172    private static final String AT = "@";
173    /**
174     * @see org.andromda.cartridges.webservice.metafacades.WebServiceParameterLogic#getRestPathParam()
175     */
176    @Override
177    protected String handleGetRestPathParam()
178    {
179        String pathParam = (String)this.findTaggedValue(WebServiceGlobals.REST_PATH_PARAM);
180        if (StringUtils.isBlank(pathParam) || pathParam.equals(DEFAULT))
181        {
182            pathParam = this.getName();
183        }
184        pathParam = AT + handleGetRestParamType() + "(\"" + pathParam + "\")";
185        return pathParam;
186    }
187
188    /**
189     * @see org.andromda.cartridges.webservice.metafacades.WebServiceParameterLogic#getRestPathSegment()
190     */
191    @Override
192    protected String handleGetRestPathSegment()
193    {
194        String pathSegment = (String)this.findTaggedValue(WebServiceGlobals.REST_PATH_SEGMENT);
195        if (StringUtils.isBlank(pathSegment) || pathSegment.equals(DEFAULT))
196        {
197            pathSegment = EMPTY_STRING;
198        }
199        return pathSegment;
200    }
201
202    /**
203     * @see org.andromda.cartridges.webservice.metafacades.WebServiceParameterLogic#isRestEncoded()
204     */
205    @Override
206    protected boolean handleIsRestEncoded()
207    {
208        String restEncoded = (String)this.findTaggedValue(WebServiceGlobals.REST_ENCODED);
209        if (StringUtils.isBlank(restEncoded) || restEncoded.equals(DEFAULT))
210        {
211            restEncoded = BOOLEAN_FALSE;
212        }
213        return Boolean.valueOf(restEncoded);
214    }
215
216    /**
217     * <p><b>Constraint:</b> org::andromda::cartridges::webservice::metafacades::WebServiceParameter::parameter must start with a lowercase letter</p>
218     * <p><b>Error:</b> Parameter name must start with a lowercase letter.</p>
219     * @param validationMessages Collection<ModelValidationMessage>
220     * @see MetafacadeBase#validateInvariants(Collection validationMessages)
221     */
222    @Override
223    public void validateInvariants(Collection<ModelValidationMessage> validationMessages)
224    {
225        super.validateInvariants(validationMessages);
226        try
227        {
228            final Object contextElement = this.THIS();
229            final String name = (String)OCLIntrospector.invoke(contextElement,"name");
230            if (name != null && name.length()>0 && !StringUtilsHelper.startsWithLowercaseLetter(name) && !this.isReturn())
231            {
232                validationMessages.add(
233                    new ModelValidationMessage(
234                        (MetafacadeBase)contextElement ,
235                        "org::andromda::cartridges::webservice::metafacades::WebServiceParameter::parameter must start with a lowercase letter",
236                        "Parameter name must start with a lowercase letter."));
237            }
238        }
239        catch (Throwable th)
240        {
241            Throwable cause = th.getCause();
242            int depth = 0; // Some throwables have infinite recursion
243            while (cause != null && depth < 7)
244            {
245                th = cause;
246                depth++;
247            }
248            logger.error("Error validating constraint 'org::andromda::cartridges::webservice::WSDLTypeAttribute::attribute must start with a lowercase letter' ON "
249                + this.THIS().toString() + ": " + th.getMessage(), th);
250        }
251    }
252}