View Javadoc
1   // license-header java merge-point
2   //
3   // Generated by: MetafacadeLogicImpl.vsl in andromda-meta-cartridge.
4   package org.andromda.cartridges.webservice.metafacades;
5   
6   import java.text.MessageFormat;
7   import java.util.ArrayList;
8   import java.util.Collection;
9   import java.util.List;
10  import org.andromda.cartridges.webservice.WebServiceGlobals;
11  import org.andromda.cartridges.webservice.WebServiceUtils;
12  import org.andromda.core.metafacade.MetafacadeBase;
13  import org.andromda.core.metafacade.ModelValidationMessage;
14  import org.andromda.metafacades.uml.PackageFacade;
15  import org.andromda.metafacades.uml.UMLProfile;
16  import org.apache.commons.lang.StringUtils;
17  import org.apache.log4j.Logger;
18  
19  /**
20   *
21   * MetafacadeLogic implementation for org.andromda.cartridges.webservice.metafacades.WebServicePackage.
22   *
23   * @see org.andromda.cartridges.webservice.metafacades.WebServicePackage
24   */
25  public class WebServicePackageLogicImpl
26      extends WebServicePackageLogic
27  {
28      private static final long serialVersionUID = 34L;
29      private static final String DEFAULT = "default";
30  
31      /**
32       * Public constructor for WebServicePackageLogicImpl
33       * @param metaObject
34       * @param context
35       * @see org.andromda.cartridges.webservice.metafacades.WebServicePackage
36       */
37      public WebServicePackageLogicImpl (Object metaObject, String context)
38      {
39          super(metaObject, context);
40      }
41  
42      /**
43       * The logger instance.
44       */
45      private static final Logger logger = Logger.getLogger(WebServicePackageLogicImpl.class);
46  
47      /**
48       * The property defining the default style to give the web services.
49       */
50      private static final String DEFAULT_ATTRIBUTE_FORM = "UNQUALIFIED";
51  
52      /**
53       *
54       * @return findTaggedValue(WebServiceGlobals.ATTRIBUTE_FORM_DEFAULT) or DEFAULT_ATTRIBUTE_FORM
55       * @see org.andromda.cartridges.webservice.metafacades.WebServicePackage#getAttributeFormDefault()
56       */
57      protected String handleGetAttributeFormDefault()
58      {
59          String style = (String)this.findTaggedValue(WebServiceGlobals.ATTRIBUTE_FORM_DEFAULT);
60          if (StringUtils.isEmpty(style) || style.equals(DEFAULT))
61          {
62              style = DEFAULT_ATTRIBUTE_FORM;
63          }
64          return style;
65      }
66  
67      /**
68       * The property defining the default style to give the web services.
69       */
70      private static final String DEFAULT_ELEMENT_FORM = "QUALIFIED";
71  
72      /**
73       *
74       * @return findTaggedValue(WebServiceGlobals.ELEMENT_FORM_DEFAULT) or DEFAULT_ELEMENT_FORM
75       * @see org.andromda.cartridges.webservice.metafacades.WebServicePackage#getElementFormDefault()
76       */
77      protected String handleGetElementFormDefault()
78      {
79          String style = (String)this.findTaggedValue(WebServiceGlobals.ELEMENT_FORM_DEFAULT);
80          if (StringUtils.isEmpty(style) || style.equals(DEFAULT))
81          {
82              style = DEFAULT_ELEMENT_FORM;
83          }
84          return style;
85      }
86  
87      /**
88       * reverseNamespace
89       */
90      static final String REVERSE_NAMESPACE = "reverseNamespace";
91      /**
92       * Backslash char /
93       */
94      static final String BACKSLASH = "/";
95      /**
96       *
97       * @return findTaggedValue(WebServiceGlobals.XML_NAMESPACE) or REVERSE_NAMESPACE
98       * @see org.andromda.cartridges.webservice.metafacades.WebServicePackage#getNamespace()
99       */
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 }