001// license-header java merge-point
002//
003// Generated by: MetafacadeLogicImpl.vsl in andromda-meta-cartridge.
004package org.andromda.cartridges.webservice.metafacades;
005
006import java.text.MessageFormat;
007import java.util.ArrayList;
008import java.util.Collection;
009import java.util.List;
010import org.andromda.cartridges.webservice.WebServiceGlobals;
011import org.andromda.cartridges.webservice.WebServiceUtils;
012import org.andromda.core.metafacade.MetafacadeBase;
013import org.andromda.core.metafacade.ModelValidationMessage;
014import org.andromda.metafacades.uml.PackageFacade;
015import org.andromda.metafacades.uml.UMLProfile;
016import org.apache.commons.lang.StringUtils;
017import org.apache.log4j.Logger;
018
019/**
020 *
021 * MetafacadeLogic implementation for org.andromda.cartridges.webservice.metafacades.WebServicePackage.
022 *
023 * @see org.andromda.cartridges.webservice.metafacades.WebServicePackage
024 */
025public class WebServicePackageLogicImpl
026    extends WebServicePackageLogic
027{
028    private static final long serialVersionUID = 34L;
029    private static final String DEFAULT = "default";
030
031    /**
032     * Public constructor for WebServicePackageLogicImpl
033     * @param metaObject
034     * @param context
035     * @see org.andromda.cartridges.webservice.metafacades.WebServicePackage
036     */
037    public WebServicePackageLogicImpl (Object metaObject, String context)
038    {
039        super(metaObject, context);
040    }
041
042    /**
043     * The logger instance.
044     */
045    private static final Logger logger = Logger.getLogger(WebServicePackageLogicImpl.class);
046
047    /**
048     * The property defining the default style to give the web services.
049     */
050    private static final String DEFAULT_ATTRIBUTE_FORM = "UNQUALIFIED";
051
052    /**
053     *
054     * @return findTaggedValue(WebServiceGlobals.ATTRIBUTE_FORM_DEFAULT) or DEFAULT_ATTRIBUTE_FORM
055     * @see org.andromda.cartridges.webservice.metafacades.WebServicePackage#getAttributeFormDefault()
056     */
057    protected String handleGetAttributeFormDefault()
058    {
059        String style = (String)this.findTaggedValue(WebServiceGlobals.ATTRIBUTE_FORM_DEFAULT);
060        if (StringUtils.isEmpty(style) || style.equals(DEFAULT))
061        {
062            style = DEFAULT_ATTRIBUTE_FORM;
063        }
064        return style;
065    }
066
067    /**
068     * The property defining the default style to give the web services.
069     */
070    private static final String DEFAULT_ELEMENT_FORM = "QUALIFIED";
071
072    /**
073     *
074     * @return findTaggedValue(WebServiceGlobals.ELEMENT_FORM_DEFAULT) or DEFAULT_ELEMENT_FORM
075     * @see org.andromda.cartridges.webservice.metafacades.WebServicePackage#getElementFormDefault()
076     */
077    protected String handleGetElementFormDefault()
078    {
079        String style = (String)this.findTaggedValue(WebServiceGlobals.ELEMENT_FORM_DEFAULT);
080        if (StringUtils.isEmpty(style) || style.equals(DEFAULT))
081        {
082            style = DEFAULT_ELEMENT_FORM;
083        }
084        return style;
085    }
086
087    /**
088     * reverseNamespace
089     */
090    static final String REVERSE_NAMESPACE = "reverseNamespace";
091    /**
092     * Backslash char /
093     */
094    static final String BACKSLASH = "/";
095    /**
096     *
097     * @return findTaggedValue(WebServiceGlobals.XML_NAMESPACE) or REVERSE_NAMESPACE
098     * @see org.andromda.cartridges.webservice.metafacades.WebServicePackage#getNamespace()
099     */
100    protected String handleGetNamespace()
101    {
102        String namespace = (String)this.findTaggedValue(WebServiceGlobals.XML_NAMESPACE);
103        if (StringUtils.isEmpty(namespace))
104        {
105            if (Boolean.valueOf(String.valueOf(this.getConfiguredProperty(REVERSE_NAMESPACE))).booleanValue())
106            {
107                namespace = WebServiceUtils.reversePackage(this.getName());
108            }
109            String namespacePattern = (String)this.getConfiguredProperty(WebServiceLogicImpl.NAMESPACE_PATTERN);
110            namespace = MessageFormat.format(
111                namespacePattern,
112                new Object[] {StringUtils.trimToEmpty(namespace)});
113            Boolean addNamespaceBackslash = Boolean.valueOf((String)this.getConfiguredProperty(WebServiceGlobals.ADD_NAMESPACE_BACKSLASH));
114            if (addNamespaceBackslash && !namespace.endsWith(BACKSLASH))
115            {
116                namespace += BACKSLASH;
117            }
118        }
119        return namespace;
120    }
121
122    /**
123     * @return findTaggedValue(WebServiceGlobals.XML_XMLNS) or WebServiceUtils.getPkgAbbr(this)
124     * @see org.andromda.cartridges.webservice.WebServiceUtils#getPkgAbbr(PackageFacade)
125     */
126    protected String handleGetXmlns()
127    {
128        WebServiceUtils utils = new WebServiceUtils();
129        String abbr = (String)this.findTaggedValue(WebServiceGlobals.XML_XMLNS);
130        if (StringUtils.isEmpty(abbr))
131        {
132            abbr = utils.getPkgAbbr(this);
133        }
134        else
135        {
136            utils.addPkgAbbr(this, abbr);
137        }
138        return abbr;
139    }
140
141    /**
142     * @return findTaggedValue(WebServiceGlobals.XML_XMLNS) or WebServiceUtils.getPkgAbbr(this)
143     * @see org.andromda.cartridges.webservice.WebServiceUtils#getPkgAbbr(PackageFacade)
144     */
145    protected String handleGetSchemaLocation()
146    {
147        String packageNamespace = this.getNamespace().substring(7) + ".xsd";
148        packageNamespace = StringUtils.replaceChars(packageNamespace, "/\\", ".");
149        packageNamespace = "xsd/" + StringUtils.replace(packageNamespace, "..", ".");
150        return packageNamespace;
151    }
152
153    /**
154     *
155     * @return new WebServiceUtils().getPackageReferences(this, true)
156     * @see org.andromda.cartridges.webservice.WebServiceUtils#getPackageReferences(PackageFacade, boolean)
157     */
158    protected Collection<PackageFacade> handleGetPackages()
159    {
160        return new WebServiceUtils().getPackageReferences(this, true);
161    }
162
163    /**
164     * <p>
165     * Package Abbreviation
166     * </p>
167     * @return findTaggedValue(WebServiceGlobals.XML_XMLNS) or WebServiceUtils.getPkgAbbr(this)
168     * @see org.andromda.cartridges.webservice.metafacades.WebServicePackage#getPackageAbbr()
169     */
170    protected String handleGetPackageAbbr()
171    {
172        WebServiceUtils utils = new WebServiceUtils();
173        String namespace = (String)this.findTaggedValue(WebServiceGlobals.XML_XMLNS);
174        if (StringUtils.isEmpty(namespace))
175        {
176            namespace = utils.getPkgAbbr(this);
177        }
178        else
179        {
180            utils.addPkgAbbr(this, namespace);
181        }
182        return namespace;
183    }
184
185    /**
186     * <p>
187     * Packages referenced by this package
188     * </p>
189     * @return WebServiceUtils.getPackageReferences(this, true)
190     * @see org.andromda.cartridges.webservice.metafacades.WebServicePackage#getPackageReferences()
191     * @see org.andromda.cartridges.webservice.WebServiceUtils#getPackageReferences(WebServiceLogicImpl, java.util.Set, String, boolean)
192     */
193    protected Collection<PackageFacade> handleGetPackageReferences()
194    {
195        WebServiceUtils utils = new WebServiceUtils();
196        return utils.getPackageReferences(this, true);
197    }
198
199    /**
200     *
201     * @param follow
202     * @return WebServiceUtils.getPackageReferences(this, follow)
203     * @see org.andromda.cartridges.webservice.metafacades.WebServicePackage#getPackageReferences(boolean)
204     */
205    protected Collection<PackageFacade> handleGetPackageReferences(boolean follow)
206    {
207        WebServiceUtils utils = new WebServiceUtils();
208        return utils.getPackageReferences(this, follow);
209    }
210
211    /**
212     * Allow sorting and use in TreeSet
213     * @see Comparable#compareTo(Object)
214     */
215    public int compareTo(Object object)
216    {
217        if (object==null || !(object instanceof WebServicePackageLogic))
218        {
219            return -1;
220        }
221        return ((WebServicePackageLogic)object).getFullyQualifiedName().compareTo(this.getFullyQualifiedName());
222    }
223
224    private static List<WebServiceOperation> warnedOperations = new ArrayList<WebServiceOperation>();
225    /**
226     * @see org.andromda.cartridges.webservice.metafacades.WebServicePackageLogic#handleGetAllowedOperations()
227     */
228    @Override
229    protected Collection<WebServiceOperation> handleGetAllowedOperations()
230    {
231        Collection<WebServiceOperation> operations = new WebServiceUtils().getAllowedOperations(this);
232        // Log the actual offending operation name, since validator only shows the package name
233        String webserviceStack = String.valueOf(this.getConfiguredProperty("webserviceStack"));
234        if (webserviceStack.equals("cxf") || webserviceStack.equals("jaxws"))
235        {
236            for (WebServiceOperation operation : operations)
237            {
238                int matchCount = 0;
239                String operationName = operation.getName();
240                for (WebServiceOperation operationToCheck : operations)
241                {
242                    if (operationName.equals(operationToCheck.getName()))
243                    {
244                        matchCount++;
245                    }
246                }
247                if (matchCount > 1 && !warnedOperations.contains(operation))
248                {
249                    warnedOperations.add(operation);
250                    logger.warn(operation.getFullyQualifiedName() + " Duplicate webservice operation in package " + this.getFullyQualifiedName());
251                }
252            }
253        }
254        return operations;
255    }
256
257    private static List<String> checkedPackages = new ArrayList<String>();
258    /**
259     * @see org.andromda.cartridges.webservice.metafacades.WebServicePackageLogic#handleGetAllowedOperations()
260     */
261    @Override
262    protected boolean handleIsMissingXmlSchema()
263    {
264        boolean result = false;
265        // If the cartridge is configured to use CXF or JAX-WS, and schemas are imported...
266        String webserviceStack = String.valueOf(this.getConfiguredProperty("webserviceStack"));
267        String importedSchema = String.valueOf(this.getConfiguredProperty("importedXSD"));
268        if (importedSchema.equals("true") && (webserviceStack.equals("cxf") || webserviceStack.equals("jaxws")))
269        {
270            int serviceCount = this.getAllowedOperations().size();
271            // Check this package is it contains services
272            if (serviceCount > 0 && !this.hasStereotype(UMLProfile.STEREOTYPE_XMLSCHEMA))
273            {
274                // the packages containing the webservices must be labeled with XmlSchema
275                result = true;
276                if (!checkedPackages.contains(this.getFullyQualifiedName()))
277                {
278                    // Only display the error message once for each referenced package
279                    checkedPackages.add(this.getFullyQualifiedName());
280                }
281            }
282            // Check packages referenced by this package
283            if (serviceCount > 0 || this.hasStereotype(UMLProfile.STEREOTYPE_XMLSCHEMA))
284            {
285                Collection<PackageFacade> references = new WebServiceUtils().getPackageReferences(this, true);
286                for (PackageFacade pkg : references)
287                {
288                    if (!pkg.hasStereotype(UMLProfile.STEREOTYPE_XMLSCHEMA))
289                    {
290                        result = true;
291                        if (!checkedPackages.contains(pkg.getFullyQualifiedName()))
292                        {
293                            // Only display the error message once for each referenced package
294                            checkedPackages.add(pkg.getFullyQualifiedName());
295                            logger.warn(pkg.getFullyQualifiedName() + " package is missing XmlSchema stereotype");
296                        }
297                    }
298                }
299            }
300        }
301        return result;
302    }
303
304    /**
305     * <p><b>Constraint:</b> org::andromda::cartridges::webservice::metafacades::WebServicePackage::package must be lowercase</p>
306     * <p><b>Error:</b>XmlSchema Package name must be lowercase.</p>
307     * @param validationMessages Collection<ModelValidationMessage>
308     * @see MetafacadeBase#validateInvariants(Collection validationMessages)
309     */
310    @Override
311    public void validateInvariants(Collection<ModelValidationMessage> validationMessages)
312    {
313        super.validateInvariants(validationMessages);
314        try
315        {
316            final Object contextElement = this.THIS();
317            final String name = this.getName();
318            boolean constraintValid = name != null && name.toLowerCase().equals(name);
319            // Exclude common package names from validation
320            //boolean common = name.equals("PrimitiveTypes") || name.equals("datatype") || name.startsWith("UML");
321            if (!constraintValid && this.hasStereotype(UMLProfile.STEREOTYPE_XMLSCHEMA))
322            {
323                validationMessages.add(
324                    new ModelValidationMessage(
325                        (MetafacadeBase)contextElement ,
326                        "org::andromda::cartridges::webservice::metafacades::WebServicePackage::package must be lowercase",
327                        "Package name must be lowercase."));
328            }
329        }
330        catch (Throwable th)
331        {
332            Throwable cause = th.getCause();
333            int depth = 0; // Some throwables have infinite recursion
334            while (cause != null && depth < 7)
335            {
336                th = cause;
337                depth++;
338            }
339            logger.error("Error validating constraint 'org::andromda::cartridges::webservice::metafacades::WebServicePackage::package must be lowercase' ON "
340                + this.THIS().toString() + ": " + th.getMessage(), th);
341        }
342    }
343}