View Javadoc
1   package org.andromda.cartridges.webservice;
2   
3   import java.util.ArrayList;
4   import java.util.Collection;
5   import java.util.Collections;
6   import java.util.Date;
7   import java.util.HashSet;
8   import java.util.LinkedHashSet;
9   import java.util.List;
10  import java.util.Map;
11  import java.util.Set;
12  import java.util.TreeMap;
13  import java.util.TreeSet;
14  import org.andromda.cartridges.webservice.metafacades.WSDLEnumerationType;
15  import org.andromda.cartridges.webservice.metafacades.WSDLEnumerationTypeLogic;
16  import org.andromda.cartridges.webservice.metafacades.WSDLType;
17  import org.andromda.cartridges.webservice.metafacades.WSDLTypeAssociationEnd;
18  import org.andromda.cartridges.webservice.metafacades.WSDLTypeAssociationEndLogic;
19  import org.andromda.cartridges.webservice.metafacades.WSDLTypeAttributeLogic;
20  import org.andromda.cartridges.webservice.metafacades.WSDLTypeLogic;
21  import org.andromda.cartridges.webservice.metafacades.WebServiceLogicImpl;
22  import org.andromda.cartridges.webservice.metafacades.WebServiceLogicImpl.OperationNameComparator;
23  import org.andromda.cartridges.webservice.metafacades.WebServiceOperation;
24  import org.andromda.cartridges.webservice.metafacades.WebServiceParameterLogic;
25  import org.andromda.core.common.Introspector;
26  import org.andromda.core.metafacade.MetafacadeBase;
27  import org.andromda.core.metafacade.MetafacadeException;
28  import org.andromda.metafacades.uml.AssociationEndFacade;
29  import org.andromda.metafacades.uml.AttributeFacade;
30  import org.andromda.metafacades.uml.ClassifierFacade;
31  import org.andromda.metafacades.uml.DependencyFacade;
32  import org.andromda.metafacades.uml.EnumerationFacade;
33  import org.andromda.metafacades.uml.EnumerationLiteralFacade;
34  import org.andromda.metafacades.uml.GeneralizableElementFacade;
35  import org.andromda.metafacades.uml.ModelElementFacade;
36  import org.andromda.metafacades.uml.OperationFacade;
37  import org.andromda.metafacades.uml.PackageFacade;
38  import org.andromda.metafacades.uml.ParameterFacade;
39  import org.andromda.metafacades.uml.Role;
40  import org.andromda.metafacades.uml.Service;
41  import org.andromda.metafacades.uml.TypeMappings;
42  import org.andromda.metafacades.uml.UMLProfile;
43  import org.apache.commons.collections.Closure;
44  import org.apache.commons.collections.CollectionUtils;
45  import org.apache.commons.lang.StringUtils;
46  import org.apache.commons.lang.time.FastDateFormat;
47  import org.apache.log4j.Logger;
48  
49  /**
50   * Contains utilities used within the WebService cartridge.
51   *
52   * @author Chad Brandon
53   * @author Bob Fields
54   */
55  public class WebServiceUtils
56  {
57      /**
58       * The logger instance.
59       */
60      private static final Logger logger = Logger.getLogger(WebServiceUtils.class);
61  
62      /**
63       * Retrieves all roles from the given <code>services</code> collection.
64       *
65       * @param services the collection services.
66       * @return all roles from the collection.
67       */
68      public Collection<Role> getAllRoles(Collection<Service> services)
69      {
70          final Collection<Role> allRoles = new LinkedHashSet<Role>();
71          CollectionUtils.forAllDo(services, new Closure()
72          {
73              public void execute(Object object)
74              {
75                  if (object != null && Service.class.isAssignableFrom(object.getClass()))
76                  {
77                      allRoles.addAll(((Service)object).getAllRoles());
78                  }
79              }
80          });
81          return allRoles;
82      }
83  
84      /**
85       * Cross reference between package name and namespace abbreviation, used to annotate foreign schema elements
86       */
87      private static Map<PackageFacade, String> packageAbbr = new TreeMap<PackageFacade, String>();
88  
89      /**
90       * Creates a list of referenced packages for the service. Populates pkgAbbr static map.
91       * I tried this in the WebServiceLogicImpl metafacade but couldn't get repeatable results.
92       * Called from jaxws-included.xsd for CXF implementation
93       * @param service WebServiceLogicImpl The service for which to find referenced packages
94       * @param types Set<MetafacadeBase> of all serviceOperations, from $service.allowedOperations
95       * @param follow Follow Inheritance references $extensionInheritanceDisabled
96       * @return pkgRefs Collection<PackageFacade> - all referenced packages
97       */
98      public Collection<PackageFacade> getPackages(WebServiceLogicImpl service, Set<ModelElementFacade> types, boolean follow)
99      {
100         return setPkgAbbr(service, types, follow);
101     }
102 
103     /** Adds the package namespace abbreviation for this package
104      * @param pkg Package for which to get the abbreviation. Uses a static Map so that
105      * all schemas globally for this model will use the same namespace abbreviations
106      * @param pkgAbbr Package Abbreviation to be added to namespace map
107      * @return PackageMap TreeMap of package <-> abbreviation cross references
108      */
109     public Map<PackageFacade, String> addPkgAbbr(PackageFacade pkg, String pkgAbbr)
110     {
111         if (packageAbbr==null)
112         {
113             packageAbbr = new TreeMap<PackageFacade, String>();
114         }
115         if (pkg!=null && pkg.getFullyQualifiedName().indexOf('.') > 0)
116         {
117             if (packageAbbr.containsKey(pkg))
118             {
119                 logger.debug(pkg + " abbreviation " + pkgAbbr + " already exists in Package namespace Map");
120             }
121             else
122             {
123                 packageAbbr.put(pkg, pkgAbbr);
124             }
125         }
126         return packageAbbr;
127     }
128 
129     /** Get the package namespace abbreviation for this package
130      * @param pkg Package for which to get the abbreviation. Uses a static Map so that
131      * all schemas globally for this model will use the same namespace abbreviations
132      * @return Package abbreviation nsX
133      */
134     public String getPkgAbbr(PackageFacade pkg)
135     {
136         return this.getPkgAbbr(pkg, null);
137     }
138 
139     /** Get the package namespace abbreviation for this package
140      * @param pkg Package for which to get the abbreviation. Uses a static Map so that
141      * all schemas globally for this model will use the same namespace abbreviations
142      * @param currentPackage The package which is referencing the pkg. Return 'impl' if the same as pkg.
143      * @return Package abbreviation nsX
144      */
145     public String getPkgAbbr(PackageFacade pkg, PackageFacade currentPackage)
146     {
147         if (pkg==null)
148         {
149             logger.error("getPkgAbbr Null pkg " + packageAbbr.size() + ": " + packageAbbr);
150             return "impl";
151         }
152         if (currentPackage != null && pkg.getFullyQualifiedName().equals(currentPackage.getFullyQualifiedName()))
153         {
154             return "impl";
155         }
156         if (packageAbbr==null)
157         {
158             packageAbbr = new TreeMap<PackageFacade, String>();
159         }
160         String rtn = packageAbbr.get(pkg);
161         String pkgName = pkg.getFullyQualifiedName();
162         if (StringUtils.isEmpty(pkgName) || pkgName.startsWith("java.lang") || pkgName.startsWith("java.util")
163             || pkgName.endsWith("PrimitiveTypes") || pkgName.endsWith("datatype"))
164         {
165             // Assume simple types if no package
166             rtn="xs";
167         }
168         if (logger.isDebugEnabled())
169         {
170             logger.debug("getPkgAbbr " + pkg + ' ' + rtn + ' ' + packageAbbr.size() + ' ' + pkgName);
171         }
172         if (StringUtils.isEmpty(rtn))
173         {
174             rtn = (String)pkg.findTaggedValue(WebServiceGlobals.XML_XMLNS);
175             if (StringUtils.isEmpty(rtn))
176             {
177                 // Package reference was never added originally - needs to be fixed in getPackageReferences()
178                 int namespaceCount = packageAbbr.size()+1;
179                 rtn = "ns" + namespaceCount;
180             }
181             packageAbbr.put(pkg, rtn);
182             if (logger.isDebugEnabled())
183             {
184                 logger.debug("getPkgAbbr " + pkg + ' ' + rtn + ' ' + packageAbbr.size());
185             }
186             if (logger.isDebugEnabled())
187             {
188                 logger.debug("Missing PkgAbbr for " + pkgName + ": added " + rtn);
189             }
190         }
191         return rtn;
192     }
193 
194     /**
195      * Creates a list of sorted unique package names and namespace abbreviations for each one.
196      * Run this after running getTypeMappingElements(), to populate the namespace Map.
197      * Namespaces are in order ns1 through x
198      * @param types
199      * @return pkgAbbr
200      */
201     private Set<PackageFacade> setPkgAbbr(WebServiceLogicImpl service, Set<ModelElementFacade> types, boolean follow)
202     {
203         // Contains references to only packages needed from this service
204         Set<PackageFacade> pkgSet = new TreeSet<PackageFacade>();
205         if (logger.isDebugEnabled())
206         {
207             logger.debug(service.getName() + " setPkgAbbr");
208         }
209         int namespaceCount = packageAbbr.size() + 1;
210         PackageFacade pkg = (PackageFacade) service.getPackage();
211         String name = null;
212         if (pkg!=null && pkg.getFullyQualifiedName().indexOf('.') > 0)
213         {
214             if (!pkgSet.contains(pkg))
215             {
216                 pkgSet.add(pkg);
217             }
218             if (!packageAbbr.containsKey(pkg))
219             {
220                 packageAbbr.put(pkg, "ns" + namespaceCount);
221                 if (logger.isDebugEnabled())
222                 {
223                     logger.debug(service.getName() + " ns" + namespaceCount + ' ' + pkg + ' ' + service.getName() + " servicePackage");
224                 }
225                 namespaceCount++;
226             }
227         }
228         // Copy package names and abbreviations to package list
229         for (final WebServiceOperation op : service.getAllowedOperations())
230         {
231             for (final ModelElementFacade arg : (Collection<ModelElementFacade>)op.getExceptions())
232             {
233                 pkg = (PackageFacade) arg.getPackage();
234                 if (pkg!=null && pkg.getFullyQualifiedName().indexOf('.') > 0)
235                 {
236                     if (!pkgSet.contains(pkg))
237                     {
238                         pkgSet.add(pkg);
239                     }
240                     if (!packageAbbr.containsKey(pkg))
241                     {
242                         packageAbbr.put(pkg, "ns" + namespaceCount);
243                         if (logger.isDebugEnabled())
244                         {
245                             logger.debug(service.getName() + " ns" + namespaceCount + ' ' + pkg + ' ' + op.getName() + " getExceptions " + arg.getName());
246                         }
247                         namespaceCount++;
248                     }
249                 }
250             }
251             for (final ParameterFacade arg : op.getParameters())
252             {
253                 pkg = (PackageFacade) arg.getType().getPackage();
254                 if (pkg!=null && pkg.getFullyQualifiedName().indexOf('.') > 0)
255                 {
256                     if (!pkgSet.contains(pkg))
257                     {
258                         pkgSet.add(pkg);
259                     }
260                     if (!packageAbbr.containsKey(pkg))
261                     {
262                         packageAbbr.put(pkg, "ns" + namespaceCount);
263                         if (logger.isDebugEnabled())
264                         {
265                             logger.debug(service.getName() + " ns" + namespaceCount + ' ' + pkg + ' ' + op.getName() + " getParameters " + arg.getName());
266                         }
267                         namespaceCount++;
268                     }
269                 }
270             }
271             if (op.getReturnType()!=null)
272             {
273                 pkg = (PackageFacade) op.getReturnType().getPackage();
274                 if (pkg!=null && pkg.getFullyQualifiedName().indexOf('.') > 0)
275                 {
276                     if (!pkgSet.contains(pkg))
277                     {
278                         pkgSet.add(pkg);
279                     }
280                     if (!packageAbbr.containsKey(pkg))
281                     {
282                         packageAbbr.put(pkg, "ns" + namespaceCount);
283                         if (logger.isDebugEnabled())
284                         {
285                             logger.debug(service.getName() + " ns" + namespaceCount + ' ' + pkg + ' ' + op.getName() + " getReturnType " + op.getReturnType().getName());
286                         }
287                         namespaceCount++;
288                     }
289                 }
290             }
291         }
292         for (final ModelElementFacade element : types)
293         {
294             ClassifierFacade facade = service.getType(element);
295             if (facade != null)
296             {
297                 pkg = (PackageFacade) facade.getPackage();
298                 if (logger.isDebugEnabled())
299                 {
300                     name = facade.getName();
301                     logger.debug("setPkgAbbr facade " + pkg + '.' + name);
302                 }
303                 if (pkg != null && pkg.getFullyQualifiedName().indexOf('.') > 0)
304                 {
305                     // This element is contained in this package, see what it references
306                     for (ModelElementFacade attr : (Collection<ModelElementFacade>)facade.getProperties(follow))
307                     {
308                         try
309                         {
310                             ClassifierFacade attrType = getType(attr);
311                             if (attrType != null)
312                             {
313                                 pkg = (PackageFacade) attrType.getPackage();
314                                 name = attrType.getName();
315                                 if (pkg!=null && pkg.getFullyQualifiedName().indexOf('.') > 0)
316                                 {
317                                     if (!pkgSet.contains(pkg))
318                                     {
319                                         pkgSet.add(pkg);
320                                     }
321                                     if (!packageAbbr.containsKey(pkg))
322                                     {
323                                         packageAbbr.put(pkg, "ns" + namespaceCount);
324                                         if (logger.isDebugEnabled())
325                                         {
326                                             logger.debug(service.getName() + " ns" + namespaceCount + ' ' + pkg + ' ' + facade.getName());
327                                         }
328                                         namespaceCount++;
329                                     }
330                                 }
331                             }
332                         }
333                         catch (RuntimeException e)
334                         {
335                             logger.debug("setPkgAbbr error in service " + service.getName() + " ns" + namespaceCount + ' ' + pkg + ' ' + facade.getName());
336                         }
337                     }
338                     for (AssociationEndFacade otherEnd : (List<AssociationEndFacade>)facade.getNavigableConnectingEnds(follow))
339                     {
340                         try
341                         {
342                             ClassifierFacade endType = getType(otherEnd);
343                             if (endType != null)
344                             {
345                                 pkg = (PackageFacade) endType.getPackage();
346                                 name = endType.getName();
347                                 if (pkg!=null && pkg.getFullyQualifiedName().indexOf('.') > 0)
348                                 {
349                                     if (!pkgSet.contains(pkg))
350                                     {
351                                         pkgSet.add(pkg);
352                                     }
353                                     if (!packageAbbr.containsKey(pkg))
354                                     {
355                                         packageAbbr.put(pkg, "ns" + namespaceCount);
356                                         if (logger.isDebugEnabled())
357                                         {
358                                             logger.debug(service.getName() + " ns" + namespaceCount + ' ' + pkg + ' ' + facade.getName());
359                                         }
360                                         namespaceCount++;
361                                     }
362                                 }
363                             }
364                         }
365                         catch (RuntimeException e)
366                         {
367                             logger.debug("setPkgAbbr error in service " + service.getName() + " ns" + namespaceCount + ' ' + pkg + ' ' + facade.getName());
368                         }
369                     }
370                 }
371             }
372             // TODO remove 'else' and add ParameterFacade logic type
373             else if (element instanceof ClassifierFacade)
374             {
375                 ClassifierFacade type = (ClassifierFacade)element;
376                 if (getType(type) != null)
377                 {
378                     type = getType(type);
379                 }
380                 pkg = (PackageFacade) type.getPackage();
381                 if (pkg != null && pkg.getFullyQualifiedName().indexOf('.') > 0)
382                 {
383                     //int cnt = type.getAttributes(follow).size();
384                     /*if (logger.isDebugEnabled())
385                     {
386                         logger.debug("WSDLTypeLogicImpl pkg=" + pkg + " name=" + type.getName() + " size=" + cnt + " propsize=" + type.getProperties(follow).size());
387                     }*/
388                     // Duplicates logic in jaxws-included.vsl so that referenced packages are the same.
389                     // Except that vsl uses getAttributes, not getProperties. getProperties returns all attributes, getAttributes does not.
390                     for (ModelElementFacade attr : (List<ModelElementFacade>)type.getProperties(follow))
391                     {
392                         try
393                         {
394                             ClassifierFacade attrType = getType(attr);
395                             if (getType(attrType) != null)
396                             {
397                                 pkg = (PackageFacade) attrType.getPackage();
398                                 name = attrType.getName();
399                                 if (pkg!=null && pkg.getFullyQualifiedName().indexOf('.') > 0)
400                                 {
401                                     if (!pkgSet.contains(pkg))
402                                     {
403                                         pkgSet.add(pkg);
404                                     }
405                                     if (!packageAbbr.containsKey(pkg))
406                                     {
407                                         packageAbbr.put(pkg, "ns" + namespaceCount);
408                                         if (logger.isDebugEnabled())
409                                         {
410                                             logger.debug(service.getName() + " ns" + namespaceCount + ' ' + pkg + ' ' + type.getName() + '.' + name);
411                                         }
412                                         namespaceCount++;
413                                     }
414                                 }
415                             }
416                         }
417                         catch (RuntimeException e)
418                         {
419                             logger.debug("setPkgAbbr error in service " + service.getName() + " ns" + namespaceCount + ' ' + pkg + ' ' + type.getName() + ": " + e);
420                         }
421                     }
422                     for (AssociationEndFacade otherEnd : (List<AssociationEndFacade>)type.getNavigableConnectingEnds(follow))
423                     {
424                         try
425                         {
426                             ClassifierFacade endType = getType(otherEnd);
427                             if (endType != null)
428                             {
429                                 pkg = (PackageFacade) endType.getPackage();
430                                 name = endType.getName();
431                                 if (pkg!=null && pkg.getFullyQualifiedName().indexOf('.') > 0)
432                                 {
433                                     if (!pkgSet.contains(pkg))
434                                     {
435                                         pkgSet.add(pkg);
436                                     }
437                                     if (!packageAbbr.containsKey(pkg))
438                                     {
439                                         packageAbbr.put(pkg, "ns" + namespaceCount);
440                                         if (logger.isDebugEnabled())
441                                         {
442                                             logger.debug(service.getName() + " ns" + namespaceCount + ' ' + pkg + ' ' + type.getName() + '.' + name);
443                                         }
444                                         namespaceCount++;
445                                     }
446                                 }
447                             }
448                         }
449                         catch (RuntimeException e)
450                         {
451                             logger.debug("setPkgAbbr error in service " + service.getName() + " ns" + namespaceCount + ' ' + pkg + ' ' + type.getName() + ": " + e);
452                         }
453                     }
454                 }
455             }
456             else if (element instanceof AssociationEndFacade)
457             {
458                 AssociationEndFacade type = (AssociationEndFacade)element;
459                 facade = getType(type);
460                 if (facade instanceof AssociationEndFacade)
461                 {
462                     type = (AssociationEndFacade)facade;
463                 }
464                 pkg = (PackageFacade) type.getPackage();
465                 if (pkg != null && pkg.getFullyQualifiedName().indexOf('.') > 0)
466                 {
467                     if (facade != null && facade instanceof ClassifierFacade)
468                     {
469                         ClassifierFacade typeLogic = facade;
470                         pkg = (PackageFacade) typeLogic.getPackage();
471                         name = typeLogic.getName();
472                         if (pkg!=null && pkg.getFullyQualifiedName().indexOf('.') > 0)
473                         {
474                             if (!pkgSet.contains(pkg))
475                             {
476                                 pkgSet.add(pkg);
477                             }
478                             if (!packageAbbr.containsKey(pkg))
479                             {
480                                 packageAbbr.put(pkg, "ns" + namespaceCount);
481                                 if (logger.isDebugEnabled())
482                                 {
483                                     logger.debug(service.getName() + " ns" + namespaceCount + ' ' + pkg + ' ' + type.getName());
484                                 }
485                                 namespaceCount++;
486                             }
487                         }
488                     }
489                     else
490                     {
491                         if (logger.isDebugEnabled())
492                         {
493                             logger.debug("setPkgAbbr element association " + pkg + '.' + name);
494                         }
495                         name = type.getName();
496                         // Duplicates logic in wsdl.vsl so that referenced packages are the same.
497                         for (AssociationEndFacade otherEnd : (List<AssociationEndFacade>)type.getType().getNavigableConnectingEnds(follow))
498                         {
499                             try
500                             {
501                                 ClassifierFacade endType = getType(otherEnd);
502                                 if (endType != null)
503                                 {
504                                     pkg = (PackageFacade) endType.getPackage();
505                                     name = endType.getName();
506                                     if (pkg!=null && pkg.getFullyQualifiedName().indexOf('.') > 0)
507                                     {
508                                         if (!pkgSet.contains(pkg))
509                                         {
510                                             pkgSet.add(pkg);
511                                         }
512                                         if (!packageAbbr.containsKey(pkg))
513                                         {
514                                             packageAbbr.put(pkg, "ns" + namespaceCount);
515                                             if (logger.isDebugEnabled())
516                                             {
517                                                 logger.debug(service.getName() + " ns" + namespaceCount + ' ' + pkg + ' ' + type.getName());
518                                             }
519                                             namespaceCount++;
520                                         }
521                                     }
522                                 }
523                             }
524                             catch (RuntimeException e)
525                             {
526                                 logger.debug("setPkgAbbr error in service " + pkg + '.' + name + " ns" + namespaceCount);
527                             }
528                         }
529                     }
530                 }
531             }
532             else if (element instanceof EnumerationFacade)
533             {
534                 EnumerationFacade type = (EnumerationFacade)element;
535                 if (getType(type) != null)
536                 {
537                     type = (EnumerationFacade)getType(type);
538                 }
539                 pkg = (PackageFacade) type.getPackage();
540                 if (pkg!=null && pkg.getFullyQualifiedName().indexOf('.') > 0)
541                 {
542                     if (!pkgSet.contains(pkg))
543                     {
544                         pkgSet.add(pkg);
545                     }
546                     if (!packageAbbr.containsKey(pkg))
547                     {
548                         packageAbbr.put(pkg, "ns" + namespaceCount);
549                         if (logger.isDebugEnabled())
550                         {
551                             logger.debug(service.getName() + " ns" + namespaceCount + ' ' + pkg + ' ' + type.getName() + '.' + name);
552                         }
553                         namespaceCount++;
554                     }
555                 }
556             }
557             else if (element.getName().endsWith("[]"))
558             {
559                 // Ignore modeled array types - assume non-array type is already in the package
560             }
561             else
562             {
563                 // Log the type so we can extend this logic later...
564                 logger.error("setPkgAbbr Unexpected element in service " + pkg + '.' + name + " type: " + element);
565             }
566         }
567         return pkgSet;
568     }
569 
570     /**
571      * Creates a list of referenced packages for each package.
572      * Run this after running getTypeMappingElements(), to populate the namespace Map and referenced imports from each namespace.
573      * @param service WebService containing WS operations with references.
574      * @param types Collection<String> of all schemaTypeMappings referenced in the WebService class operations
575      * @param packageName Package / namespace for which to find all related (referenced) packages
576      * @param follow Follow Inheritance references $extensionInheritanceDisabled
577      * @return pkgRefs
578      */
579     public Collection<PackageFacade> getPackageReferences(WebServiceLogicImpl service, Set<MetafacadeBase> types, String packageName, boolean follow)
580     {
581         Collection<PackageFacade> pkgRef = new TreeSet<PackageFacade>();
582         if (StringUtils.isNotBlank(packageName))
583         {
584             String name = null;
585             PackageFacade pkg = null;
586             String pkgRefs = "";
587             if (types!=null)
588             {
589                 // Copy package names and collection of related packages to package references list
590                 for (final MetafacadeBase element : types)
591                 {
592                     ClassifierFacade facade = service.getType(element);
593                     if (facade != null)
594                     {
595                         pkg = (PackageFacade) facade.getPackage();
596                         if (logger.isDebugEnabled())
597                         {
598                             name = facade.getName();
599                             //logger.debug("getPackageReferences packageName=" + packageName + " facade " + pkg + "." + name);
600                         }
601                         if (pkg != null && pkg.getFullyQualifiedName().indexOf('.') > 0 && pkg.getFullyQualifiedName().equals(packageName))
602                         {
603                             // This element is contained in this package, see what it references
604                             // Add reference to immediate ancestor to import packages
605                             GeneralizableElementFacade generalization = facade.getGeneralization();
606                             if (generalization != null)
607                             {
608                                 pkg = (PackageFacade) generalization.getPackage();
609                                 if (pkg!=null && !pkg.getFullyQualifiedName().equals(packageName) && !pkgRef.contains(pkg))
610                                 {
611                                     pkgRef.add(pkg);
612                                     if (logger.isDebugEnabled())
613                                     {
614                                         pkgRefs += pkg + ",";
615                                         logger.debug("getPackageReferences packageName=" + packageName + " add facadeAttribute " + pkg + '.' + name);
616                                     }
617                                 }
618                             }
619                             for (ModelElementFacade attr : (List<ModelElementFacade>)facade.getProperties(follow))
620                             {
621                                 try
622                                 {
623                                     ClassifierFacade attrType = getType(attr);
624                                     if (attrType != null)
625                                     {
626                                         pkg = (PackageFacade) attrType.getPackage();
627                                         name = attrType.getName();
628                                         if (pkg!=null && !pkg.getFullyQualifiedName().equals(packageName) && !pkgRef.contains(pkg) && pkg.getFullyQualifiedName().indexOf('.') > 0)
629                                         {
630                                             pkgRef.add(pkg);
631                                             if (logger.isDebugEnabled())
632                                             {
633                                                 pkgRefs += pkg + ",";
634                                                 logger.debug("getPackageReferences packageName=" + packageName + " add facadeAttribute " + pkg + '.' + name);
635                                             }
636                                         }
637                                     }
638                                 }
639                                 catch (RuntimeException e)
640                                 {
641                                     logger.error("getPackageReferences packageName=" + packageName + " add facadeAttribute " + pkg + '.' + name + ": " + e);
642                                 }
643                             }
644                             for (final AssociationEndFacade endFacade : (List<AssociationEndFacade>)facade.getNavigableConnectingEnds(follow))
645                             {
646                                 try
647                                 {
648                                     if (getType(endFacade) != null)
649                                     {
650                                         ClassifierFacade otherEnd = getType(endFacade);
651                                         pkg = (PackageFacade) otherEnd.getPackage();
652                                         name = otherEnd.getName();
653                                         if (pkg!=null && !pkg.getFullyQualifiedName().equals(packageName) && !pkgRef.contains(pkg) && pkg.getFullyQualifiedName().indexOf('.') > 0)
654                                         {
655                                             pkgRef.add(pkg);
656                                             if (logger.isDebugEnabled())
657                                             {
658                                                 pkgRefs += pkg + ",";
659                                                 logger.debug("getPackageReferences packageName=" + packageName + " add facadeOtherEnd " + pkg + '.' + name);
660                                             }
661                                         }
662                                     }
663                                 }
664                                 catch (RuntimeException e)
665                                 {
666                                     logger.error("getPackageReferences packageName=" + packageName + " add facadeOtherEnd " + pkg + '.' + name + ": " + e);
667                                 }
668                             }
669                         }
670                     }
671                     // TODO remove 'else' and add ParameterFacade logic type
672                     else if (element instanceof ClassifierFacade)
673                     {
674                         ClassifierFacade type = (ClassifierFacade)element;
675                         if (getType(type) != null)
676                         {
677                             type = getType(type);
678                         }
679                         pkg = (PackageFacade) type.getPackage();
680                         if (logger.isDebugEnabled())
681                         {
682                             logger.debug("getPackageReferences packageName=" + packageName + " ClassifierFacade " + pkg + '.' + name);
683                         }
684                         if (pkg != null && pkg.getFullyQualifiedName().indexOf('.') > 0 && pkg.getFullyQualifiedName().equals(packageName))
685                         {
686                             // Duplicates logic in wsdl.vsl so that referenced packages are the same.
687                             for (ModelElementFacade attr : (List<ModelElementFacade>)type.getProperties(follow))
688                             {
689                                 try
690                                 {
691                                     ClassifierFacade attrType = getType(attr);
692                                     if (attrType != null)
693                                     {
694                                         pkg = (PackageFacade) attr.getPackage();
695                                         name = attr.getName();
696                                     }
697                                     if (pkg!=null && !pkg.getFullyQualifiedName().equals(packageName) && !pkgRef.contains(pkg) && pkg.getFullyQualifiedName().indexOf('.') > 0)
698                                     {
699                                         pkgRef.add(pkg);
700                                         if (logger.isDebugEnabled())
701                                         {
702                                             pkgRefs += pkg + ",";
703                                             logger.debug("getPackageReferences packageName=" + packageName + " add attribute " + pkg + '.' + name);
704                                         }
705                                     }
706                                 }
707                                 catch (RuntimeException e)
708                                 {
709                                     logger.error("getPackageReferences packageName=" + packageName + " add attribute " + pkg + '.' + name + ": " + e);
710                                 }
711                             }
712                             for (final Object object : type.getNavigableConnectingEnds(follow))
713                             {
714                                 try
715                                 {
716                                     ModelElementFacade endFacade = (ModelElementFacade)object;
717                                     if (getType(endFacade) != null)
718                                     {
719                                         ClassifierFacade otherEnd = getType(endFacade);
720                                         pkg = (PackageFacade) otherEnd.getPackage();
721                                         name = otherEnd.getName();
722                                         if (pkg!=null && !pkg.getFullyQualifiedName().equals(packageName) && !pkgRef.contains(pkg) && pkg.getFullyQualifiedName().indexOf('.') > 0)
723                                         {
724                                             pkgRef.add(pkg);
725                                             if (logger.isDebugEnabled())
726                                             {
727                                                 pkgRefs += pkg + ",";
728                                                 logger.debug("getPackageReferences packageName=" + packageName + " add otherEnd " + pkg + '.' + name);
729                                             }
730                                         }
731                                     }
732                                 }
733                                 catch (RuntimeException e)
734                                 {
735                                     logger.error("getPackageReferences packageName=" + packageName + " add otherEnd " + pkg + '.' + name + ": " + e);
736                                 }
737                             }
738                         }
739                     }
740                     else if (element instanceof AssociationEndFacade)
741                     {
742                         AssociationEndFacade type = (AssociationEndFacade)element;
743                         facade = getType(type);
744                         // TODO: When can ClassifierFacade ever be an instanceof AssociationEndFacade
745                         if (facade instanceof AssociationEndFacade)
746                         {
747                             type = (AssociationEndFacade)facade;
748                         }
749                         pkg = (PackageFacade) type.getPackage();
750                         if (logger.isDebugEnabled())
751                         {
752                             logger.debug("getPackageReferences packageName=" + packageName + " AssociationEndFacade " + pkg + '.' + name);
753                         }
754                         if (pkg != null && pkg.getFullyQualifiedName().indexOf('.') > 0 && pkg.getFullyQualifiedName().equals(packageName))
755                         {
756                             if (facade != null && facade instanceof ClassifierFacade)
757                             {
758                                 ClassifierFacade typeLogic = facade;
759                                 pkg = (PackageFacade) typeLogic.getPackage();
760                                 if (logger.isDebugEnabled())
761                                 {
762                                     name = typeLogic.getName();
763                                     logger.debug("getPackageReferences packageName=" + packageName + " element typeLogic " + pkg + '.' + name);
764                                 }
765                                 if (pkg != null && pkg.getFullyQualifiedName().indexOf('.') > 0 && !pkg.getFullyQualifiedName().equals(packageName) && !pkgRef.contains(pkg))
766                                 {
767                                     pkgRef.add(pkg);
768                                     if (logger.isDebugEnabled())
769                                     {
770                                         pkgRefs += pkg + ",";
771                                         logger.debug("getPackageReferences packageName=" + packageName + " add typeLogic " + pkg + '.' + name);
772                                     }
773                                 }
774                             }
775                             else
776                             {
777                                 if (logger.isDebugEnabled())
778                                 {
779                                     logger.debug("getPackageReferences packageName=" + packageName + " element association " + pkg + '.' + name);
780                                 }
781                                 name = type.getName();
782                                 // Duplicates logic in wsdl.vsl so that referenced packages are the same.
783                                 for (final Object object : type.getType().getNavigableConnectingEnds(follow))
784                                 {
785                                     try
786                                     {
787                                         ModelElementFacade endFacade = (ModelElementFacade)object;
788                                         if (getType(endFacade) != null)
789                                         {
790                                             ClassifierFacade otherEnd = getType(endFacade);
791                                             pkg = (PackageFacade) otherEnd.getPackage();
792                                             name = otherEnd.getName();
793                                             if (pkg!=null && !pkg.getFullyQualifiedName().equals(packageName) && !pkgRef.contains(pkg) && pkg.getFullyQualifiedName().indexOf('.') > 0)
794                                             {
795                                                 pkgRef.add(pkg);
796                                                 if (logger.isDebugEnabled())
797                                                 {
798                                                     pkgRefs += pkg + ",";
799                                                     logger.debug("getPackageReferences packageName=" + packageName + " add otherEnd " + pkg + '.' + name);
800                                                 }
801                                             }
802                                         }
803                                     }
804                                     catch (RuntimeException e)
805                                     {
806                                         logger.error("getPackageReferences packageName=" + packageName + " add otherEnd " + pkg + '.' + name + ": " + e);
807                                     }
808                                 }
809                             }
810                         }
811                     }
812                     else if (element instanceof EnumerationFacade)
813                     {
814                         EnumerationFacade type = (EnumerationFacade)element;
815                         if (getType(type) != null)
816                         {
817                             type = (EnumerationFacade)getType(type);
818                         }
819                         pkg = (PackageFacade) type.getPackage();
820                         if (pkg != null && pkg.getFullyQualifiedName().indexOf('.') > 0 && pkg.getFullyQualifiedName().equals(packageName))
821                         {
822                             for (ModelElementFacade attr : (List<ModelElementFacade>)type.getAllProperties())
823                             {
824                                 ClassifierFacade attrType = getType(attr);
825                                 if (attrType != null)
826                                 {
827                                     pkg = (PackageFacade) attr.getPackage();
828                                     name = attr.getName();
829                                 }
830                                 if (!pkg.getFullyQualifiedName().equals(packageName) && !pkgRef.contains(pkg) && pkg.getFullyQualifiedName().indexOf('.') > 0)
831                                 {
832                                     pkgRef.add(pkg);
833                                     if (logger.isDebugEnabled())
834                                     {
835                                         pkgRefs += pkg + ",";
836                                         logger.debug("getPackageReferences packageName=" + packageName + " add enumeration attribute " + pkg + '.' + name);
837                                     }
838                                 }
839                             }
840                         }
841                     }
842                     else if (element.getValidationName() != null && element.getValidationName().endsWith("[]"))
843                     {
844                         // Ignore modeled array types - assume non-array type is already in the package
845                     }
846                     else
847                     {
848                         // Log the type so we can extend this logic later...
849                         logger.error("getPackageReferences Unexpected element type in service " + packageName + '.' + name + " : " + element);
850                     }
851                 }
852             }
853             if (packageName.equals(service.getPackageName()))
854             {
855                 // Add references from the operations of the service package itself
856                 for (WebServiceOperation op : service.getAllowedOperations())
857                 {
858                     for (Object opit : op.getExceptions())
859                     {
860                         if (opit instanceof ModelElementFacade)
861                         {
862                             ModelElementFacade arg = (ModelElementFacade)opit;
863                             pkg = (PackageFacade) arg.getPackage();
864                             name = arg.getName();
865                         }
866                         else if (opit instanceof PackageFacade)
867                         {
868                             pkg = (PackageFacade) opit;
869                         }
870                         else if (opit instanceof WSDLType)
871                         {
872                             WSDLType type = (WSDLType) opit;
873                             if (!type.getAssociationEnds().isEmpty())
874                             {
875                                 // Get the first Exception attribute (the FaultBean)
876                                 ClassifierFacade fault = type.getAssociationEnds().get(0).getOtherEnd().getType();
877                                 pkg = (PackageFacade) fault.getPackage();
878                                 name = fault.getName();
879                             }
880                         }
881                         else
882                         {
883                             pkg = null;
884                         }
885                         if (pkg!=null && !pkg.getFullyQualifiedName().equals(service.getPackageName()) && pkg.getFullyQualifiedName().indexOf('.') > 0 && !pkgRef.contains(pkg))
886                         {
887                             pkgRef.add(pkg);
888                             if (logger.isDebugEnabled())
889                             {
890                                 pkgRefs += pkg + ",";
891                                 logger.debug("getPackageReferences packageName=" + packageName + " add exception " + pkg + '.' + name);
892                             }
893                         }
894                     }
895                     for (final ParameterFacade arg : op.getParameters())
896                     {
897                         pkg = (PackageFacade) arg.getType().getPackage();
898                         name = arg.getType().getName();
899                         if (pkg!=null && !pkg.getFullyQualifiedName().equals(service.getPackageName()) && pkg.getFullyQualifiedName().indexOf('.') > 0 && !pkgRef.contains(pkg))
900                         {
901                             pkgRef.add(pkg);
902                             if (logger.isDebugEnabled())
903                             {
904                                 pkgRefs += pkg + ",";
905                                 logger.debug("getPackageReferences packageName=" + packageName + " add parameter " + pkg + '.' + name);
906                             }
907                         }
908                     }
909                     if (op.getReturnType()!=null)
910                     {
911                         pkg = (PackageFacade) op.getReturnType().getPackage();
912                         name = op.getReturnType().getName();
913                         if (logger.isDebugEnabled())
914                         {
915                             logger.debug("getPackageReferences packageName=" + packageName + " return " + pkg + '.' + name);
916                         }
917                         if (pkg!=null && !pkg.getFullyQualifiedName().equals(service.getPackageName()) && pkg.getFullyQualifiedName().indexOf('.') > 0 && !pkgRef.contains(pkg))
918                         {
919                             pkgRef.add(pkg);
920                             if (logger.isDebugEnabled())
921                             {
922                                 pkgRefs += pkg + ",";
923                                 logger.debug("getPackageReferences packageName=" + packageName + " add return " + pkg + '.' + name);
924                             }
925                         }
926                     }
927                 }
928             }
929             if (logger.isDebugEnabled())
930             {
931                 logger.debug("getPackageReferences packageName=" + packageName + ' ' + pkgRefs);
932             }
933         }
934         else
935         {
936             if (logger.isDebugEnabled())
937             {
938                 logger.debug("getPackageReferences packageName=null");
939             }
940         }
941         return pkgRef;
942     }
943 
944     /**
945      * Creates a list of referenced exception packages for each package.
946      * Populates schema reference list for import for the wsdl
947      * @param packageFacade Package / namespace for which to find all related (referenced) packages
948      * @return pkgRefs Collection<String> package names
949      */
950     public Collection<PackageFacade> getExceptionReferences(PackageFacade packageFacade)
951     {
952         Collection<PackageFacade> pkgRef = new TreeSet<PackageFacade>();
953         if (packageFacade != null)
954         {
955             String name = null;
956             PackageFacade pkg = null;
957             String packageName = packageFacade.getFullyQualifiedName();
958             @SuppressWarnings("unused")
959             String pkgRefs = "";
960             // Copy package names and collection of related packages to package references list
961             for (final ClassifierFacade classifier : packageFacade.getClasses())
962             {
963                 //logger.debug("getPackageReferences packageName=" + packageName);
964                 if (classifier != null)
965                 {
966                     pkg = (PackageFacade) classifier.getPackage();
967                     if (classifier.hasStereotype(UMLProfile.STEREOTYPE_WEBSERVICE))
968                     {
969                         // Add references from the operations of the service package itself
970                         for (final OperationFacade op : classifier.getOperations())
971                         {
972                             for (final ModelElementFacade arg : (Collection<ModelElementFacade>)op.getExceptions())
973                             {
974                                 // TODO Why does MEF.getPackage return a ModelElementFacade instead of Package?
975                                 pkg = (PackageFacade) arg.getPackage();
976                                 if (pkg != null && !pkg.getFullyQualifiedName().equals(classifier.getPackageName()) && pkg.getFullyQualifiedName().indexOf('.') > 0 && !pkgRef.contains(pkg))
977                                 {
978                                     pkgRef.add(pkg);
979                                     if (logger.isDebugEnabled())
980                                     {
981                                         pkgRefs += pkg + ",";
982                                         logger.debug("getPackageReferences packageName=" + packageName + " add parameter " + pkg + '.' + name);
983                                     }
984                                 }
985                             }
986                         }
987                     }
988                 }
989             }
990         }
991         return pkgRef;
992     }
993 
994     /**
995      * Creates a list of referenced packages for each package.
996      * Populates schema reference list for import
997      * @param packageFacade Package / namespace for which to find all related (referenced) packages
998      * @param follow Follow Inheritance references $extensionInheritanceDisabled
999      * @return pkgRefs Collection<String> package names
1000      */
1001     public Collection<PackageFacade> getPackageReferences(PackageFacade packageFacade, boolean follow)
1002     {
1003         Collection<PackageFacade> pkgRef = new TreeSet<PackageFacade>();
1004         if (packageFacade != null)
1005         {
1006             String name = null;
1007             PackageFacade pkg = null;
1008             String packageName = packageFacade.getFullyQualifiedName();
1009             String pkgRefs = "";
1010             // Copy package names and collection of related packages to package references list
1011             for (final ClassifierFacade facade : packageFacade.getClasses())
1012             {
1013                 //logger.debug("getPackageReferences packageName=" + packageName);
1014                 if (facade != null)
1015                 {
1016                     pkg = (PackageFacade) facade.getPackage();
1017                     if (logger.isDebugEnabled())
1018                     {
1019                         name = facade.getName();
1020                         logger.debug("getPackageReferences packageName=" + packageName + " facade " + pkg + '.' + name);
1021                     }
1022                     // Add reference to immediate ancestor to import packages
1023                     GeneralizableElementFacade generalization = facade.getGeneralization();
1024                     if (generalization != null)
1025                     {
1026                         pkg = (PackageFacade) generalization.getPackage();
1027                         if (pkg!=null && !pkg.getFullyQualifiedName().equals(packageName) && !pkgRef.contains(pkg))
1028                         {
1029                             pkgRef.add(pkg);
1030                             if (logger.isDebugEnabled())
1031                             {
1032                                 pkgRefs += pkg + ",";
1033                                 logger.debug("getPackageReferences packageName=" + packageName + " add facadeAttribute " + pkg + '.' + name);
1034                             }
1035                         }
1036                     }
1037                     if (facade.hasStereotype("ValueObject") || facade.hasStereotype("Exception") || facade.hasStereotype("UnexpectedException") || facade.hasStereotype("ApplicationException"))
1038                     {
1039                         // This element is contained in this package, see what it references
1040                         for (ModelElementFacade attr : (List<ModelElementFacade>)facade.getProperties(follow))
1041                         {
1042                             try
1043                             {
1044                                 ClassifierFacade attrType = getType(attr);
1045                                 if (attrType != null)
1046                                 {
1047                                     pkg = (PackageFacade) attrType.getPackage();
1048                                     name = attrType.getName();
1049                                     if (pkg!=null && !pkg.getFullyQualifiedName().equals(packageName) && !pkgRef.contains(pkg) && pkg.getFullyQualifiedName().indexOf('.') > 0)
1050                                     {
1051                                         pkgRef.add(pkg);
1052                                         if (logger.isDebugEnabled())
1053                                         {
1054                                             pkgRefs += pkg + ",";
1055                                             logger.debug("getPackageReferences packageName=" + packageName + " add facadeAttribute " + pkg + '.' + name);
1056                                         }
1057                                     }
1058                                 }
1059                             }
1060                             catch (RuntimeException e)
1061                             {
1062                                 logger.error("getPackageReferences packageName=" + packageName + " add facadeAttribute " + pkg + '.' + name + ": " + e);
1063                             }
1064                         }
1065                         for (final AssociationEndFacade endFacade : (List<AssociationEndFacade>)facade.getNavigableConnectingEnds(follow))
1066                         {
1067                             try
1068                             {
1069                                 if (getType(endFacade) != null)
1070                                 {
1071                                     ClassifierFacade otherEnd = getType(endFacade);
1072                                     pkg = (PackageFacade) otherEnd.getPackage();
1073                                     name = otherEnd.getName();
1074                                     if (pkg!=null && !pkg.getFullyQualifiedName().equals(packageName) && !pkgRef.contains(pkg) && pkg.getFullyQualifiedName().indexOf('.') > 0)
1075                                     {
1076                                         pkgRef.add(pkg);
1077                                         if (logger.isDebugEnabled())
1078                                         {
1079                                             pkgRefs += pkg + ",";
1080                                             logger.debug("getPackageReferences packageName=" + packageName + " add facadeOtherEnd " + pkg + '.' + name);
1081                                         }
1082                                     }
1083                                 }
1084                             }
1085                             catch (RuntimeException e)
1086                             {
1087                                 logger.error("getPackageReferences packageName=" + packageName + " add facadeOtherEnd " + pkg + '.' + name + ": " + e);
1088                             }
1089                         }
1090                     }
1091                     else if (facade.hasStereotype(UMLProfile.STEREOTYPE_WEBSERVICE))
1092                     {
1093                         // Add references from the operations of the service package itself
1094                         for (final OperationFacade op : facade.getOperations())
1095                         {
1096                             for (final ModelElementFacade arg : (Collection<ModelElementFacade>)op.getExceptions())
1097                             {
1098                                 // TODO Why does MEF.getPackage return a ModelElementFacade instead of Package?
1099                                 pkg = (PackageFacade) arg.getPackage();
1100                                 if (pkg != null && !pkg.getFullyQualifiedName().equals(facade.getPackageName()) && pkg.getFullyQualifiedName().indexOf('.') > 0 && !pkgRef.contains(pkg))
1101                                 {
1102                                     pkgRef.add(pkg);
1103                                     if (logger.isDebugEnabled())
1104                                     {
1105                                         pkgRefs += pkg + ",";
1106                                         logger.debug("getPackageReferences packageName=" + packageName + " add parameter " + pkg + '.' + name);
1107                                     }
1108                                 }
1109                             }
1110                             for (final ParameterFacade arg : op.getParameters())
1111                             {
1112                                 pkg = (PackageFacade) arg.getType().getPackage();
1113                                 name = arg.getType().getName();
1114                                 if (pkg!=null && !pkg.getFullyQualifiedName().equals(facade.getPackageName()) && pkg.getFullyQualifiedName().indexOf('.') > 0 && !pkgRef.contains(pkg))
1115                                 {
1116                                     pkgRef.add(pkg);
1117                                     if (logger.isDebugEnabled())
1118                                     {
1119                                         pkgRefs += pkg + ",";
1120                                         logger.debug("getPackageReferences packageName=" + packageName + " add parameter " + pkg + '.' + name);
1121                                     }
1122                                 }
1123                             }
1124                             if (op.getReturnType()!=null)
1125                             {
1126                                 pkg = (PackageFacade) op.getReturnType().getPackage();
1127                                 name = op.getReturnType().getName();
1128                                 if (pkg!=null && !pkg.getFullyQualifiedName().equals(facade.getPackageName()) && pkg.getFullyQualifiedName().indexOf('.') > 0 && !pkgRef.contains(pkg))
1129                                 {
1130                                     pkgRef.add(pkg);
1131                                     if (logger.isDebugEnabled())
1132                                     {
1133                                         pkgRefs += pkg + ",";
1134                                         logger.debug("getPackageReferences packageName=" + packageName + " add return " + pkg + '.' + name);
1135                                     }
1136                                 }
1137                             }
1138                         }
1139                     }
1140                     /*else if (facade.isEnumeration() || facade.hasStereotype("Enumeration"))
1141                     {
1142 
1143                     }*/
1144                 }
1145             }
1146             if (logger.isDebugEnabled())
1147             {
1148                 logger.debug("getPackageReferences packageName=" + packageName + ' ' + pkgRefs);
1149             }
1150         }
1151         else
1152         {
1153             if (logger.isDebugEnabled())
1154             {
1155                 logger.debug("getPackageReferences packageName=null");
1156             }
1157         }
1158         return pkgRef;
1159     }
1160 
1161     /**
1162      * Get all operations under WebService or with WebServiceOperation in a package
1163      * @param packageFacade Package / namespace for which to find all service operations
1164      * @return operations
1165      */
1166     public List<WebServiceOperation> getAllowedOperations(PackageFacade packageFacade)
1167     {
1168         List<WebServiceOperation> operations = new ArrayList<WebServiceOperation>();
1169         for (final ModelElementFacade mefacade : packageFacade.getOwnedElements())
1170         {
1171             if (mefacade != null && mefacade instanceof ClassifierFacade)
1172             {
1173                 ClassifierFacade facade = (ClassifierFacade)mefacade;
1174                 boolean webService = facade.hasStereotype(UMLProfile.STEREOTYPE_WEBSERVICE);
1175                 for (final OperationFacade op : facade.getOperations())
1176                 {
1177                     boolean visibility = op.getVisibility().equals("public") || op.getVisibility().equals("protected");
1178                     if (visibility && (webService || op.hasStereotype(UMLProfile.STEREOTYPE_WEBSERVICE_OPERATION)))
1179                     {
1180                         operations.add((WebServiceOperation) op);
1181                     }
1182                 }
1183             }
1184         }
1185         // Always sort by name so that operations can be easily found in a long list.
1186         Collections.sort(
1187                 operations,
1188                 new OperationNameComparator());
1189         return operations;
1190     }
1191 
1192     /**
1193      * Get all operations under WebService or with WebServiceOperation in a package
1194      * @param packageFacade Package / namespace for which to find all service operations
1195      * @return operations
1196      */
1197     public Collection<ModelElementFacade> getAllowedOperationExceptions(PackageFacade packageFacade)
1198     {
1199         final Collection<ModelElementFacade> exceptions = new HashSet<ModelElementFacade>();
1200 
1201         // collect the exceptions of all allowed operations into a single set
1202         for (final OperationFacade operation : this.getAllowedOperations(packageFacade))
1203         {
1204             exceptions.addAll(operation.getExceptions());
1205         }
1206 
1207         return exceptions;
1208     }
1209 
1210     /**
1211      * Filter schema types list and related object to only a single package. Called for each referenced package.
1212      * Run this after running getTypeMappingElements(), to populate the namespace Map and referenced imports from each namespace.
1213      * @param packageFacade Package / namespace for which to find all related (referenced) packages
1214      * @param follow Follow Inheritance references $extensionInheritanceDisabled
1215      * @return pkgRefs
1216      */
1217     public Collection<ModelElementFacade> getPackageTypes(PackageFacade packageFacade, boolean follow)
1218     {
1219         Collection<ModelElementFacade> pkgTypes = new HashSet<ModelElementFacade>();
1220         if (packageFacade != null)
1221         {
1222             String name = null;
1223             String pkg = null;
1224             String packageName = packageFacade.getFullyQualifiedName();
1225             String pkgRefs = "";
1226             // Copy package names and collection of related packages to package references list
1227             //ClassifierFacade facade = null;
1228             for (final ModelElementFacade mefacade : packageFacade.getOwnedElements())
1229             {
1230                 if (logger.isDebugEnabled())
1231                 {
1232                     logger.debug("getPackageTypes packageName=" + packageName + " element " + mefacade);
1233                 }
1234                 if (mefacade != null && mefacade instanceof ClassifierFacade)
1235                 {
1236                     ClassifierFacade facade = (ClassifierFacade)mefacade;
1237                     if (logger.isDebugEnabled())
1238                     {
1239                         name = facade.getName();
1240                         logger.debug("getPackageTypes packageName=" + packageName + " facade " + name);
1241                     }
1242                     if (facade.hasStereotype("ValueObject"))
1243                     {
1244                         if (!pkgTypes.contains(facade))
1245                         {
1246                             pkgTypes.add(facade);
1247                             if (logger.isDebugEnabled())
1248                             {
1249                                 name = facade.getName();
1250                                 pkgRefs += name + ',';
1251                                 logger.debug("getPackageTypes packageName=" + packageName + " add facadeValueObject " + name);
1252                             }
1253                         }
1254                     }
1255                     else if (facade.isEnumeration() || facade.hasStereotype("Enumeration"))
1256                     {
1257                         if (!pkgTypes.contains(facade))
1258                         {
1259                             pkgTypes.add(facade);
1260                             if (logger.isDebugEnabled())
1261                             {
1262                                 name = facade.getName();
1263                                 pkgRefs += name + ',';
1264                                 logger.debug("getPackageTypes packageName=" + packageName + " add facadeEnumeration " + name);
1265                             }
1266                         }
1267                     }
1268                     else if (facade.hasStereotype("Exception") || facade.hasStereotype("ApplicationException")
1269                             || facade.hasStereotype("UnexpectedException") || facade.hasStereotype("WebFault"))
1270                     {
1271                         if (!pkgTypes.contains(facade))
1272                         {
1273                             pkgTypes.add(facade);
1274                             if (logger.isDebugEnabled())
1275                             {
1276                                 name = facade.getName();
1277                                 pkgRefs += name + ',';
1278                                 logger.debug("getPackageTypes packageName=" + packageName + " add facadeEnumeration " + name);
1279                             }
1280                         }
1281                     }
1282                     else if (facade.hasStereotype(UMLProfile.STEREOTYPE_WEBSERVICE))
1283                     {
1284                         // Add references from the operations of the service package itself
1285                         for (final OperationFacade op : facade.getOperations())
1286                         {
1287                             for (final ModelElementFacade arg : (Collection<ModelElementFacade>)op.getExceptions())
1288                             {
1289                                 pkg = arg.getPackageName();
1290                                 if (pkg!=null && pkg.equals(facade.getPackageName()) && pkg.indexOf('.') > 0 && !pkgTypes.contains(arg))
1291                                 {
1292                                     pkgTypes.add(arg);
1293                                     if (logger.isDebugEnabled())
1294                                     {
1295                                         name = arg.getName();
1296                                         pkgRefs += name + ',';
1297                                         logger.debug("getPackageTypes packageName=" + packageName + " add exception " + pkg + '.' + name);
1298                                     }
1299                                 }
1300                             }
1301                             for (final ParameterFacade arg : op.getParameters())
1302                             {
1303                                 pkg = arg.getType().getPackageName();
1304                                 name = arg.getType().getName();
1305                                 //ClassifierFacade arg = ((ParameterFacade)opiterator.next()).getType();
1306                                 //pkg = arg.getPackageName();
1307                                 if (pkg!=null && pkg.equals(facade.getPackageName()) && pkg.indexOf('.') > 0 && !pkgTypes.contains(arg.getType()))
1308                                 {
1309                                     pkgTypes.add(arg.getType());
1310                                     if (logger.isDebugEnabled())
1311                                     {
1312                                         name = arg.getName();
1313                                         pkgRefs += name + ',';
1314                                         logger.debug("getPackageTypes packageName=" + packageName + " add parameter " + pkg + '.' + name);
1315                                     }
1316                                 }
1317                             }
1318                             if (op.getReturnType()!=null)
1319                             {
1320                                 pkg = op.getReturnType().getPackageName();
1321                                 if (logger.isDebugEnabled())
1322                                 {
1323                                     name = op.getReturnType().getName();
1324                                     logger.debug("getPackageTypes packageName=" + packageName + " return " + pkg + '.' + name);
1325                                 }
1326                                 if (pkg!=null && pkg.equals(facade.getPackageName()) && pkg.indexOf('.') > 0 && !pkgTypes.contains(op.getReturnType()))
1327                                 {
1328                                     pkgTypes.add(op.getReturnType());
1329                                     if (logger.isDebugEnabled())
1330                                     {
1331                                         pkgRefs += name + ',';
1332                                         logger.debug("getPackageTypes packageName=" + packageName + " add return " + pkg + '.' + name);
1333                                     }
1334                                 }
1335                             }
1336                         }
1337                     }
1338                 }
1339             }
1340             if (logger.isDebugEnabled())
1341             {
1342                 logger.debug("getPackageTypes packageName=" + packageName + ' ' + pkgRefs);
1343             }
1344         }
1345         else
1346         {
1347             if (logger.isDebugEnabled())
1348             {
1349                 logger.debug("getPackageTypes packageName=null");
1350             }
1351         }
1352         return pkgTypes;
1353     }
1354 
1355     /**
1356      * Filter schema types list and related object to only a single package. Called for each referenced package.
1357      * Run this after running getTypeMappingElements(), to populate the namespace Map and referenced imports from each namespace.
1358      * @param service WebService containing WS operations with references.
1359      * @param types Collection<ModelElementFacade> of all schemaTypeMappings referenced in the WebService class operations
1360      * @param packageName Package / namespace for which to find all related (referenced) packages
1361      * @param follow Follow Inheritance references $extensionInheritanceDisabled
1362      * @return pkgRefs
1363      */
1364     public Collection<ModelElementFacade> getPackageTypes(WebServiceLogicImpl service, Set<MetafacadeBase> types, String packageName, boolean follow)
1365     {
1366         Collection<ModelElementFacade> pkgTypes = new TreeSet<ModelElementFacade>(service.new TypeComparator());
1367         if (StringUtils.isNotBlank(packageName))
1368         {
1369             String name = null;
1370             String pkg = null;
1371             String pkgRefs = "";
1372             // Copy package names and collection of related packages to package references list
1373             for (final MetafacadeBase element : types)
1374             {
1375                 //TreeSet pkgRef = new TreeSet(new TypeComparator());
1376                 ClassifierFacade facade = service.getType(element);
1377                 if (facade != null)
1378                 {
1379                     pkg = facade.getPackageName();
1380                     if (logger.isDebugEnabled())
1381                     {
1382                         name = facade.getName();
1383                         logger.debug("getPackageTypes packageName=" + packageName + " facade " + pkg + '.' + name);
1384                     }
1385                     if (pkg != null && pkg.indexOf('.') > 0 && pkg.equals(packageName) && !pkgTypes.contains(facade))
1386                     {
1387                         pkgTypes.add(facade);
1388                         if (logger.isDebugEnabled())
1389                         {
1390                             pkgRefs += facade.getName() + ',';
1391                             logger.debug("getPackageTypes packageName=" + packageName + " add facade " + facade.getPackageName() + '.' + facade.getName());
1392                         }
1393                     }
1394                     /*if (facade instanceof ClassifierFacade)
1395                     {
1396                         ClassifierFacade type = (ClassifierFacade)facade;
1397                         pkg = type.getPackageName();
1398                         name = type.getName();
1399                     }
1400                     else if (facade instanceof AssociationEndFacade)
1401                     {
1402                         AssociationEndFacade type = (AssociationEndFacade)facade;
1403                         pkg = type.getPackageName();
1404                         name = type.getName();
1405                     }*/
1406                 }
1407                 // TODO remove 'else' and add ParameterFacade logic type
1408                 if (element instanceof ClassifierFacade)
1409                 {
1410                     ClassifierFacade type = (ClassifierFacade)element;
1411                     facade = getType(type);
1412                     if (facade != null)
1413                     {
1414                         if (facade instanceof ClassifierFacade)
1415                         {
1416                             type = getType(type);
1417                         }
1418                     }
1419                     pkg = type.getPackageName();
1420                     if (logger.isDebugEnabled())
1421                     {
1422                         name = type.getName();
1423                         logger.debug("getPackageTypes packageName=" + packageName + " elementTypeLogic " + pkg + '.' + name);
1424                     }
1425                     if (pkg != null)
1426                     {
1427                         if (pkg.indexOf('.') > 0 && pkg.equals(packageName) && !pkgTypes.contains(type))
1428                         {
1429                             pkgTypes.add(type);
1430                             if (logger.isDebugEnabled())
1431                             {
1432                                 pkgRefs += type.getName() + ',';
1433                                 logger.debug("getPackageTypes packageName=" + packageName + " add typeLogic " + type.getPackageName() + '.' + type.getName());
1434                             }
1435                         }
1436                         if (logger.isDebugEnabled())
1437                         {
1438                             logger.debug("ClassifierFacade pkg=" + packageName + " refPkg=" + pkg + " name=" + type.getName());
1439                         }
1440                         // Duplicates logic in wsdl.vsl so that referenced packages are the same.
1441                         for (ModelElementFacade attr : (List<ModelElementFacade>)type.getProperties(follow))
1442                         {
1443                             try
1444                             {
1445                                 ClassifierFacade attrType = getType(attr);
1446                                 if (attrType != null)
1447                                 {
1448                                     pkg = attrType.getPackageName();
1449                                     if (pkg!=null && pkg.equals(packageName) && pkg.indexOf('.') > 0 && !pkgTypes.contains(attrType))
1450                                     {
1451                                         pkgTypes.add(attrType);
1452                                         if (logger.isDebugEnabled())
1453                                         {
1454                                             name = attrType.getName();
1455                                             pkgRefs += attrType.getName() + ',';
1456                                             logger.debug("getPackageTypes packageName=" + packageName + " add attr " + attrType.getPackageName() + '.' + attrType.getName());
1457                                         }
1458                                     }
1459                                 }
1460                             }
1461                             catch (RuntimeException e)
1462                             {
1463                                 logger.error("getPackageTypes packageName=" + packageName + " add attr " + pkg + '.' + name + ": " + e);
1464                             }
1465                         }
1466                     }
1467                 }
1468                 else if (element instanceof AssociationEndFacade)
1469                 {
1470                     AssociationEndFacade type = (AssociationEndFacade)element;
1471                     facade = getType(type);
1472                     // TODO When can ClassifierFacade ever be an instanceof AssociationEndFacade
1473                     if (facade instanceof AssociationEndFacade)
1474                     {
1475                         type = (AssociationEndFacade)facade;
1476                     }
1477                     if (facade != null && facade instanceof ClassifierFacade)
1478                     {
1479                         ClassifierFacade typeLogic = facade;
1480                         pkg = typeLogic.getPackageName();
1481                         if (pkg != null && pkg.indexOf('.') > 0 && pkg.equals(packageName) && !pkgTypes.contains(typeLogic))
1482                         {
1483                             pkgTypes.add(typeLogic);
1484                             if (logger.isDebugEnabled())
1485                             {
1486                                 name = typeLogic.getName();
1487                                 pkgRefs += typeLogic.getName() + ',';
1488                                 logger.debug("getPackageTypes packageName=" + packageName + " add typeLogic " + type.getPackageName() + '.' + type.getName());
1489                             }
1490                         }
1491                     }
1492                     else
1493                     {
1494                         pkg = type.getPackageName();
1495                         if (logger.isDebugEnabled())
1496                         {
1497                             name = type.getName();
1498                             logger.debug("getPackageTypes packageName=" + packageName + " associationEnd " + pkg + '.' + name);
1499                         }
1500                         if (pkg != null)
1501                         {
1502                             if (pkg.indexOf('.') > 0 && pkg.equals(packageName) && !pkgTypes.contains(type))
1503                             {
1504                                 pkgTypes.add(type);
1505                                 if (logger.isDebugEnabled())
1506                                 {
1507                                     pkgRefs += type.getName() + ',';
1508                                     logger.debug("getPackageTypes packageName=" + packageName + " add typeAssoc " + type.getPackageName() + '.' + type.getName());
1509                                 }
1510                             }
1511                             // Get the other end reference itself, then get the navigable connecting ends
1512                             try
1513                             {
1514                                 AssociationEndFacade otherEnd = (type.getOtherEnd());
1515                                 ClassifierFacade endType = getType(otherEnd);
1516                                 if (endType != null)
1517                                 {
1518                                     pkg = endType.getPackageName();
1519                                     if (logger.isDebugEnabled())
1520                                     {
1521                                         name = endType.getName();
1522                                         logger.debug("getPackageTypes packageName=" + packageName + " otherEnd " + pkg + '.' + name);
1523                                     }
1524                                     if (pkg!=null && pkg.equals(packageName) && pkg.indexOf('.') > 0 && !pkgTypes.contains(endType))
1525                                     {
1526                                         pkgTypes.add(endType);
1527                                         if (logger.isDebugEnabled())
1528                                         {
1529                                             pkgRefs += endType.getName() + ',';
1530                                             logger.debug("getPackageTypes packageName=" + packageName + " add otherEnd " + endType.getPackageName() + '.' + otherEnd.getName());
1531                                         }
1532                                     }
1533                                 }
1534                             }
1535                             catch (RuntimeException e)
1536                             {
1537                                 logger.error("getPackageTypes packageName=" + packageName + " add otherEnd " + pkg + '.' + name + ": " + e);
1538                             }
1539                             // Duplicates logic in wsdl.vsl so that referenced packages are the same.
1540                             for (final Object object : type.getType().getNavigableConnectingEnds(follow))
1541                             {
1542                                 ClassifierFacade otherEnd = null;
1543                                 try
1544                                 {
1545                                     AssociationEndFacade endFacade = (AssociationEndFacade)object;
1546                                     if (getType(endFacade) != null)
1547                                     {
1548                                         otherEnd = getType(endFacade);
1549                                         pkg = otherEnd.getPackageName();
1550                                         if (logger.isDebugEnabled())
1551                                         {
1552                                             name = otherEnd.getName();
1553                                             logger.debug("getPackageTypes packageName=" + packageName + " NavOtherEnd " + otherEnd.getPackageName() + '.' + otherEnd.getName());
1554                                         }
1555                                         if (pkg!=null && pkg.equals(packageName) && pkg.indexOf('.') > 0 && !pkgTypes.contains(otherEnd))
1556                                         {
1557                                             pkgTypes.add(otherEnd);
1558                                             if (logger.isDebugEnabled())
1559                                             {
1560                                                 pkgRefs += otherEnd.getName() + ',';
1561                                                 logger.debug("getPackageTypes packageName=" + packageName + " add NavOtherEnd " + otherEnd.getPackageName() + '.' + otherEnd.getName());
1562                                             }
1563                                         }
1564                                     }
1565                                 }
1566                                 catch (RuntimeException e)
1567                                 {
1568                                     if (otherEnd!=null)
1569                                     {
1570                                         logger.error("getPackageTypes packageName=" + packageName + " add NavOtherEnd " + otherEnd.getPackageName() + '.' + otherEnd.getName() + ": " + e);
1571                                     }
1572                                     else
1573                                     {
1574                                         logger.error("getPackageTypes packageName=" + packageName + " add NavOtherEnd " + type.getType().getPackageName() + '.' + type.getType().getName() + ": " + e);
1575                                     }
1576                                 }
1577                             }
1578                         }
1579                     }
1580                 }
1581                 else if (element instanceof EnumerationFacade)
1582                 {
1583                     EnumerationFacade type = (EnumerationFacade)element;
1584                     if (getType(type) != null)
1585                     {
1586                         type = (EnumerationFacade)getType(type);
1587                     }
1588                     pkg = type.getPackageName();
1589                     if (pkg!=null && pkg.equals(packageName) && pkg.indexOf('.') > 0 && !pkgTypes.contains(type))
1590                     {
1591                         pkgTypes.add(type);
1592                         if (logger.isDebugEnabled())
1593                         {
1594                             pkgRefs += type.getName() + ',';
1595                             logger.debug("getPackageTypes packageName=" + packageName + " add NavOtherEnd " + type.getPackageName() + '.' + type.getName());
1596                         }
1597                     }
1598                 }
1599                 else if (facade != null && facade.getName().endsWith("[]"))
1600                 {
1601                     // Ignore modeled array types - assume non-array type is already in the package
1602                 }
1603                 else
1604                 {
1605                     // Log the type so we can extend this logic later...
1606                     logger.error("getPackageTypes Unexpected element in service " + pkg + '.' + element + " type: " + facade);
1607                 }
1608             }
1609             // Add package types from the operations of the service package itself
1610             for (final WebServiceOperation op : service.getAllowedOperations())
1611             {
1612                 for (final ModelElementFacade arg : (Collection<ModelElementFacade>)op.getExceptions())
1613                 {
1614                     pkg = arg.getPackageName();
1615                     if (pkg!=null && pkg.equals(packageName) && pkg.indexOf('.') > 0 && !pkgTypes.contains(arg))
1616                     {
1617                         pkgTypes.add(arg);
1618                         if (logger.isDebugEnabled())
1619                         {
1620                             name = arg.getName();
1621                             pkgRefs += arg.getName() + ',';
1622                             logger.debug("getPackageTypes packageName=" + packageName + " add service exception " + arg.getPackageName() + '.' + arg.getName());
1623                         }
1624                     }
1625                 }
1626                 for (final ParameterFacade arg : op.getParameters())
1627                 {
1628                     pkg = arg.getType().getPackageName();
1629                     if (pkg!=null && pkg.equals(packageName) && pkg.indexOf('.') > 0 && !pkgTypes.contains(arg.getType()))
1630                     {
1631                         pkgTypes.add(arg.getType());
1632                         if (logger.isDebugEnabled())
1633                         {
1634                             name = arg.getName();
1635                             pkgRefs += arg.getName() + ',';
1636                             logger.debug("getPackageTypes packageName=" + packageName + " add service parameter " + arg.getPackageName() + '.' + arg.getName());
1637                         }
1638                     }
1639                 }
1640                 if (op.getReturnType()!=null)
1641                 {
1642                     pkg = op.getReturnType().getPackageName();
1643                     if (pkg!=null && pkg.equals(packageName) && pkg.indexOf('.') > 0 && !pkgTypes.contains(op.getReturnType()))
1644                     {
1645                         pkgTypes.add(op.getReturnType());
1646                         if (logger.isDebugEnabled())
1647                         {
1648                             name = op.getReturnType().getName();
1649                             pkgRefs += op.getReturnType().getName() + ',';
1650                             logger.debug("getPackageTypes packageName=" + packageName + " add service returnType " + op.getReturnType().getPackageName() + '.' + op.getReturnType().getName());
1651                         }
1652                     }
1653                 }
1654             }
1655             if (logger.isDebugEnabled())
1656             {
1657                 logger.debug("getPackageTypes packageName=" + packageName + ' ' + pkgRefs);
1658             }
1659         }
1660         else
1661         {
1662             if (logger.isDebugEnabled())
1663             {
1664                 logger.debug("getPackageTypes packageName=null");
1665             }
1666         }
1667         return pkgTypes;
1668     }
1669 
1670     /**
1671      * Gets the <code>type</code> or <code>returnType</code> of the model element (if the model element has a type or
1672      * returnType). Duplicate of method in WebServiceLogicImpl.
1673      *
1674      * @param modelElement the model element we'll retrieve the type of.
1675      * @return ClassifierFacade Type of modelElement Object
1676      */
1677     private ClassifierFacade getType(Object modelElement)
1678     {
1679         try
1680         {
1681             final Introspector introspector = Introspector.instance();
1682             ClassifierFacade type = null;
1683             String typeProperty = "type";
1684 
1685             // only continue if the model element has a type
1686             if (introspector.isReadable(modelElement, typeProperty))
1687             {
1688                 type = (ClassifierFacade)introspector.getProperty(modelElement, typeProperty);
1689             }
1690 
1691             // try for return type if type wasn't found
1692             typeProperty = "returnType";
1693             if (type == null && introspector.isReadable(modelElement, typeProperty))
1694             {
1695                 type = (ClassifierFacade)introspector.getProperty(modelElement, typeProperty);
1696             }
1697             return type;
1698         }
1699         catch (final Throwable throwable)
1700         {
1701             String errMsg = "Error performing WebServiceLogicImpl.getType";
1702             logger.error(errMsg, throwable);
1703             throw new MetafacadeException(errMsg, throwable);
1704         }
1705     }
1706 
1707     /**
1708      * Determine if an object has schema complex types (associations, multiplicity > 1, or complex attributes).
1709      * Needed when useAttributes=true so wsdl/xsd outputs attributes instead of elements , no complex type element declarations.
1710      * If no complex types, only attribute declarations are needed in the object schema definition.
1711      * Sees if attribute packages are something other than java.lang, java,util, java.math.
1712      * @param facade Type to determine if it contains complex types
1713      * @param follow Follow inheritance hierarchy for type when determining complex types
1714      * @return pkgRefs
1715      */
1716     public boolean hasComplexTypes(ClassifierFacade facade, boolean follow)
1717     {
1718         boolean rtn = false;
1719         // Associations to other types are automatically complex, can only be elements
1720         if (!facade.getNavigableConnectingEnds(follow).isEmpty())
1721         {
1722             return true;
1723         }
1724         // Determine if attributes are multiple or anything other than simple types
1725         for (final Object obj : facade.getAttributes(follow))
1726         {
1727             AttributeFacade attr = (AttributeFacade)obj;
1728             if (attr.getUpper() > 1 || attr.getUpper() == -1)
1729             {
1730                 return true;
1731             }
1732             // can't think of an easy way to determine simple type, just look at attribute package / type
1733             String pkg = attr.getType().getFullyQualifiedName(false);
1734             if (logger.isDebugEnabled())
1735             {
1736                 String fqn = attr.getGetterSetterTypeName();
1737                 String cpkg= attr.getType().getPackageName();
1738                 logger.debug("attr=" + attr.getName() + " pkg=" + pkg + " fqn=" + fqn + " cpkg=" + cpkg);
1739             }
1740             if (StringUtils.isEmpty(pkg) || pkg.indexOf('.')<1)
1741             {
1742                 //TODO: Make sure all types are mapped
1743                 // Type mapping is missing? No FQN type, but xs:<type> is still output.
1744             }
1745             else if (pkg.length()<9)
1746             {
1747                 // Assume complex type if package name is too short but still contains '.'
1748                 return true;
1749             }
1750             else
1751             {
1752                 pkg=pkg.substring(0, 9);
1753                 if (!"java.lang".equals(pkg) && !"java.util".equals(pkg) && !"java.math".equals(pkg))
1754                 {
1755                     return true;
1756                 }
1757             }
1758         }
1759         return rtn;
1760     }
1761 
1762     /**
1763      * Creates the package name from the element namespace, following the JAXB rules.
1764      * Reverse the hostname (separated by .)
1765      * Add the service context (separated by /)
1766      * Substitute underscore _ for dash - in name
1767      * Put _ in front of numeric values for package components.
1768      *
1769      * @param namespace the XML namespace.
1770      * @return the reversed package name.
1771      */
1772     public static String getPackageName(String namespace)
1773     {
1774         if (StringUtils.isBlank(namespace))
1775         {
1776             return "";
1777         }
1778         if (namespace.startsWith("http://"))
1779         {
1780             namespace = namespace.substring(7);
1781         }
1782         if (namespace.endsWith("/"))
1783         {
1784             namespace = namespace.substring(0, namespace.length()-1);
1785         }
1786         if (namespace.endsWith(".xsd"))
1787         {
1788             namespace = namespace.substring(0, namespace.length()-4);
1789         }
1790         String hostname = namespace;
1791         if (namespace.indexOf('/')>0)
1792         {
1793             hostname = namespace.substring(0, namespace.indexOf('/'));
1794             namespace = StringUtils.reverseDelimited(hostname, WebServiceGlobals.NAMESPACE_DELIMITER)
1795                 + namespace.substring(namespace.indexOf('/'), namespace.length());
1796         }
1797         else
1798         {
1799             namespace = StringUtils.reverseDelimited(hostname, WebServiceGlobals.NAMESPACE_DELIMITER);
1800         }
1801         // TODO Change to tokenizer + pattern matcher
1802         /*StrTokenizer tok = new StrTokenizer(namespace, WebServiceGlobals.NAMESPACE_DELIMITER);
1803         for (String token : (List<String>)tok.getTokenList())
1804         {
1805             if (token.s)
1806         }*/
1807         namespace = StringUtils.replaceChars(namespace, '-', '_');
1808         namespace = StringUtils.replace(namespace, ".0", "_0");
1809         namespace = StringUtils.replace(namespace, ".1", "_1");
1810         namespace = StringUtils.replace(namespace, ".2", "_2");
1811         namespace = StringUtils.replace(namespace, ".3", "_3");
1812         namespace = StringUtils.replace(namespace, ".4", "_4");
1813         namespace = StringUtils.replace(namespace, ".5", "_5");
1814         namespace = StringUtils.replace(namespace, ".6", "_6");
1815         namespace = StringUtils.replace(namespace, ".7", "_7");
1816         namespace = StringUtils.replace(namespace, ".8", "_8");
1817         namespace = StringUtils.replace(namespace, ".9", "_9");
1818         namespace = StringUtils.replace(namespace, "$", "");
1819         namespace = StringUtils.replaceChars(namespace, '/', WebServiceGlobals.NAMESPACE_DELIMITER);
1820         namespace = StringUtils.replace(namespace, ".0", "._0");
1821         namespace = StringUtils.replace(namespace, ".1", "._1");
1822         namespace = StringUtils.replace(namespace, ".2", "._2");
1823         namespace = StringUtils.replace(namespace, ".3", "._3");
1824         namespace = StringUtils.replace(namespace, ".4", "._4");
1825         namespace = StringUtils.replace(namespace, ".5", "._5");
1826         namespace = StringUtils.replace(namespace, ".6", "._6");
1827         namespace = StringUtils.replace(namespace, ".7", "._7");
1828         namespace = StringUtils.replace(namespace, ".8", "._8");
1829         namespace = StringUtils.replace(namespace, ".9", "._9");
1830         return namespace;
1831     }
1832 
1833     /**
1834      * Gets the fully qualified name of a class given the XML Element Name and namespace.
1835      * Assumes the namespace is the reversed package name.
1836      *
1837      * @param elementName the XML element name.
1838      * @param namespace the XML namespace for the element.
1839      * @return String the package + element name
1840      */
1841     public String getElementClassName(String elementName, String namespace)
1842     {
1843         if (StringUtils.isBlank(elementName) || StringUtils.isBlank(namespace))
1844         {
1845             return "";
1846         }
1847         return WebServiceUtils.reversePackage(namespace) + '.' + elementName;
1848     }
1849 
1850     /**
1851      * Supplies a result for type = <new value>; initialization for all types
1852      * @param facade Type to create default object for
1853      * @return Constructor String with facade name
1854      */
1855     public String createConstructor(ModelElementFacade facade)
1856     {
1857         return createConstructor(facade, false);
1858     }
1859 
1860     /**
1861      * Supplies a result for type = <new value>; initialization for all types
1862      * @param facade Type to create default object for
1863      * @param useMany Return constructor with multiplicity type instead of underlying type
1864      * @return Constructor String with facade name
1865      */
1866     public String createConstructor(ModelElementFacade facade, boolean useMany)
1867     {
1868         return createConstructor(facade, useMany, null);
1869     }
1870 
1871     /**
1872      * Supplies a result for type = <new value>; initialization for all types
1873      * @param facade Type to create default object for
1874      * @param useMany Return constructor with multiplicity type instead of underlying type
1875      * @param parent Object containing this facade, which may have an attribute named dependency to a different type
1876      * @return Constructor String with facade name
1877      */
1878     @SuppressWarnings("null")
1879     public String createConstructor(ModelElementFacade facade, boolean useMany, ModelElementFacade parent)
1880     {
1881         if (facade==null)
1882         {
1883             return "facade was null";
1884         }
1885         String rtn = "";
1886         String toString = "";
1887         ClassifierFacade type = null;
1888         String typeName = facade.getFullyQualifiedName();
1889         String name = facade.getName();
1890         String defaultValue = "";
1891         // TODO: Default collection type from properties
1892         String collectionType = "java.util.ArrayList";
1893         Boolean isMany = null;
1894         boolean isEnumeration = false;
1895         /*if (parent != null)
1896         {
1897             // See if a named dependency exists with the same facadeName
1898             for (final DependencyFacade dependency : parent.getSourceDependencies())
1899             {
1900                 if (dependency.getName().equals(facade.getName()) && dependency instanceof DependencyFacade)
1901                 {
1902                     facade = ((DependencyFacade)dependency).getTargetElement();
1903                     toString = ".toString()";
1904                     break;
1905                 }
1906             }
1907         }*/
1908         try {
1909             if (logger.isDebugEnabled())
1910             {
1911                 logger.debug("facade=" + facade + " parent=" + parent + " useMany=" + useMany);
1912             }
1913             if (facade instanceof ClassifierFacade)
1914             {
1915                 ClassifierFacade classifier = (ClassifierFacade) facade;
1916                 type = classifier;
1917                 typeName = classifier.getFullyQualifiedName();
1918             }
1919             if (facade instanceof AttributeFacade)
1920             {
1921                 AttributeFacade attr = (AttributeFacade) facade;
1922                 defaultValue = attr.getDefaultValue();
1923                 type = attr.getType();
1924                 if (useMany)
1925                 {
1926                     typeName = attr.getGetterSetterTypeName();
1927                 }
1928                 else
1929                 {
1930                     typeName = type.getFullyQualifiedName();
1931                 }
1932                 if (attr.getUpper()>1 || attr.getUpper()==-1)
1933                 {
1934                     isMany = true;
1935                 }
1936             }
1937             else if (facade instanceof WSDLTypeAttributeLogic)
1938             {
1939                 WSDLTypeAttributeLogic attr = (WSDLTypeAttributeLogic) facade;
1940                 defaultValue = attr.getDefaultValue();
1941                 type = attr.getType();
1942                 if (useMany)
1943                 {
1944                     typeName = attr.getGetterSetterTypeName();
1945                 }
1946                 else
1947                 {
1948                     typeName = type.getFullyQualifiedName();
1949                 }
1950                 if (attr.getUpper()>1 || attr.getUpper()==-1)
1951                 {
1952                     isMany = true;
1953                 }
1954             }
1955             else if (facade instanceof ParameterFacade)
1956             {
1957                 ParameterFacade attr = (ParameterFacade) facade;
1958                 defaultValue = attr.getDefaultValue();
1959                 type = attr.getType();
1960                 typeName = type.getFullyQualifiedName();
1961                 if (type.isEnumeration())
1962                 {
1963                     facade = type;
1964                 }
1965                 else if (useMany)
1966                 {
1967                     typeName = collectionType + '<' + type.getFullyQualifiedName() + '>';
1968                 }
1969                 else
1970                 {
1971                     typeName = type.getFullyQualifiedName();
1972                 }
1973                 if (attr.getUpper()>1 || attr.getUpper()==-1)
1974                 {
1975                     isMany = true;
1976                 }
1977             }
1978             if (facade instanceof AssociationEndFacade)
1979             {
1980                 AssociationEndFacade attr = (AssociationEndFacade) facade;
1981                 type = attr.getType();
1982                 if (useMany)
1983                 {
1984                     typeName = attr.getGetterSetterTypeName();
1985                 }
1986                 else
1987                 {
1988                     typeName = type.getFullyQualifiedName();
1989                 }
1990                 if (attr.getUpper()>1 || attr.getUpper()==-1)
1991                 {
1992                     isMany = true;
1993                 }
1994                 facade = attr.getType();
1995             }
1996             if (facade instanceof WSDLTypeAssociationEnd)
1997             {
1998                 WSDLTypeAssociationEnd attr = (WSDLTypeAssociationEnd) facade;
1999                 type = attr.getType();
2000                 if (useMany)
2001                 {
2002                     typeName = attr.getGetterSetterTypeName();
2003                 }
2004                 else
2005                 {
2006                     typeName = type.getFullyQualifiedName();
2007                 }
2008                 if (attr.getUpper()>1 || attr.getUpper()==-1)
2009                 {
2010                     isMany = true;
2011                 }
2012                 facade = attr.getType();
2013             }
2014             // TODO: Make this work for attribute types other than String.
2015             if (parent != null && StringUtils.isEmpty(defaultValue) && ("String".equals(typeName) || "java.lang.String".equals(typeName)))
2016             {
2017                 // See if a named dependency exists with the same facadeName
2018                 for (final DependencyFacade dependency : parent.getSourceDependencies())
2019                 {
2020                     if (dependency.getName().equals(facade.getName()))
2021                     {
2022                         facade = dependency.getTargetElement();
2023                         // DependencyFacade type comes back empty for UML2::Integer
2024                         // Need to get metaObject Name property and verify it is not null.
2025                         if (facade instanceof WSDLTypeLogic)
2026                         {
2027                             WSDLTypeLogic wsdlType = (WSDLTypeLogic) facade;
2028                             if (logger.isDebugEnabled())
2029                             {
2030                                 logger.debug(wsdlType + " fqn=" + wsdlType.getFullyQualifiedName() + " name="
2031                                     + wsdlType.getName() + " id=" + wsdlType.getId() + " properties="
2032                                     + wsdlType.getAllProperties() + " MetaObject=" + wsdlType.getMetaObject() + " properties="
2033                                     + wsdlType.getProperties());
2034                             }
2035                             if (StringUtils.isEmpty(wsdlType.getName()))
2036                             {
2037                                 break;
2038                             }
2039                         }
2040                         if (facade instanceof ClassifierFacade)
2041                         {
2042                             type = (ClassifierFacade) facade;
2043                         }
2044                         typeName = facade.getFullyQualifiedName();
2045                         toString = ".toString()";
2046                         if (logger.isDebugEnabled())
2047                         {
2048                             logger.debug(parent + " " + facade + " = "
2049                                     + dependency + " type=" + type + " typeName="
2050                                     + typeName);
2051                         }
2052                         break;
2053                     }
2054                 }
2055             }
2056             if (type instanceof WSDLEnumerationTypeLogic)
2057             {
2058                 if (logger.isDebugEnabled())
2059                 {
2060                     logger.debug("facade=" + facade + " type=" + type + " default=" + defaultValue);
2061                 }
2062                 WSDLEnumerationTypeLogic enumer = (WSDLEnumerationTypeLogic) type;
2063                 //type = enumer.getLiteralType().getFullyQualifiedName();
2064                 Collection<AttributeFacade> literals = enumer.getLiterals();
2065                 if (StringUtils.isEmpty(defaultValue) && !literals.isEmpty())
2066                 {
2067                     // Just get the first enumeration literal
2068                     Object literal = literals.iterator().next();
2069                     if (literal instanceof EnumerationLiteralFacade)
2070                     {
2071                         EnumerationLiteralFacade enumLiteral = (EnumerationLiteralFacade) literal;
2072                         // Use the literal name to retrieve the value with .valueOf(). XML version has only the value.
2073                         Boolean useEnumValueInXSD = Boolean.valueOf(String.valueOf(enumer.getConfiguredProperty("useEnumValueInXSD")));
2074                         if (useEnumValueInXSD)
2075                         {
2076                             defaultValue = enumLiteral.getValue();
2077                         }
2078                         else
2079                         {
2080                             defaultValue = enumLiteral.getName();
2081                         }
2082                     }
2083                     else if (literal instanceof AttributeFacade)
2084                     {
2085                         AttributeFacade attrib = (AttributeFacade) literal;
2086                         defaultValue = attrib.getEnumerationValue();
2087                         if (defaultValue==null)
2088                         {
2089                             defaultValue = attrib.getDefaultValue();
2090                         }
2091                     }
2092                     // Literal value is always a String. Remove quotes if part of default (i.e. class attribute).
2093                     // wsdl2java may add unexpected underscores such that name and literal value no longer match.
2094                     defaultValue = StringUtils.remove(defaultValue, "\"");
2095                     defaultValue = enumer.getFullyQualifiedName() + ".fromValue(\"" + defaultValue + "\")";
2096                 }
2097                 else
2098                 {
2099                     defaultValue = enumer.getName() + '.' + defaultValue;
2100                 }
2101                 isEnumeration = true;
2102             }
2103             if (useMany && (isMany==null || isMany.booleanValue()))
2104             {
2105                 if (!typeName.startsWith("java.util"))
2106                 {
2107                     rtn = "new " + collectionType + '<' + typeName + ">()";
2108                 }
2109                 /*if (type.equals("java.util.Collection") || typeName.equals("java.util.List"))
2110                 {
2111                     rtn = "new " + collectionType + "<" + typeName + ">()";
2112                 }
2113                 else if (typeName.equals("java.util.Set"))
2114                 {
2115                     rtn = "new java.util.HashSet<" + typeName + ">";
2116                 }
2117                 else if (typeName.equals("java.util.Map"))
2118                 {
2119                     rtn = "new java.util.HashMap<" + typeName + ">";
2120                 }*/
2121                 else
2122                 {
2123                     // Assume array or type Collection<type>
2124                     rtn = "new " + typeName + "()";
2125                 }
2126             }
2127             else if ("String".equals(typeName) || "java.lang.String".equals(typeName))
2128             {
2129                 rtn = (StringUtils.isNotBlank(defaultValue) ? defaultValue : '\"' + name + '\"');
2130             }
2131             else if ("Boolean".equals(typeName) || "java.lang.Boolean".equals(typeName))
2132             {
2133                 rtn = (StringUtils.isNotBlank(defaultValue) ? "Boolean." + defaultValue.toUpperCase() : "Boolean.TRUE");
2134             }
2135             else if ("boolean".equals(typeName))
2136             {
2137                 rtn = (StringUtils.isNotBlank(defaultValue) ? defaultValue : "true");
2138             }
2139             else if ("int".equals(typeName) || "short".equals(typeName) || "long".equals(typeName)
2140                     || "byte".equals(typeName) || "float".equals(typeName) || "double".equals(typeName))
2141             {
2142                 rtn = (StringUtils.isNotBlank(defaultValue) ? defaultValue : "1");
2143             }
2144             else if ("java.util.Date".equals(typeName))
2145             {
2146                 rtn = "new " + typeName + "()";
2147             }
2148             else if ("java.sql.Timestamp".equals(typeName))
2149             {
2150                 rtn = "new java.sql.Timestamp(System.currentTimeMillis())";
2151             }
2152             else if ("java.util.Calendar".equals(typeName))
2153             {
2154                 rtn = "java.util.Calendar.getInstance()";
2155             }
2156             else if ("org.joda.time.LocalTime".equals(typeName))
2157             {
2158                 rtn = "new org.joda.time.LocalTime(1, 1)";
2159             }
2160             else if ("char".equals(typeName))
2161             {
2162                 rtn = "'" + (StringUtils.isNotEmpty(defaultValue) ? defaultValue : name.substring(0, 1)) + "'";
2163             }
2164             else if ("Character".equals(typeName))
2165             {
2166                 rtn = "new Character('" + (StringUtils.isNotEmpty(defaultValue) ? "new Character(" + defaultValue : name.substring(0, 1)) + "')";
2167             }
2168             else if ("Byte".equals(typeName) || "java.lang.Byte".equals(typeName))
2169             {
2170                 rtn = "new Byte(\"" + facade.getName() + "\")";
2171             }
2172             else if ("Short".equals(typeName) || "java.lang.Short".equals(typeName)
2173                     || "Integer".equals(typeName) || "java.lang.Integer".equals(typeName)
2174                     || "Long".equals(typeName) || "java.lang.Long".equals(typeName)
2175                     || "Float".equals(typeName) || "java.lang.Float".equals(typeName)
2176                     || "Double".equals(typeName) || "java.lang.Double".equals(typeName)
2177                     || "java.math.BigDecimal".equals(typeName))
2178             {
2179                 rtn = (!StringUtils.isEmpty(defaultValue) ? typeName + ".valueOf(" + defaultValue + ")" : typeName + ".valueOf(1)");
2180             }
2181             else if ("java.math.BigInteger".equals(typeName))
2182             {
2183                 rtn = (!StringUtils.isEmpty(defaultValue) ? "java.math.BigInteger.valueOf(" + defaultValue + ')' : "java.math.BigInteger.valueOf(1)");
2184             }
2185             else if ("byte[]".equals(typeName))
2186             {
2187                 rtn = (StringUtils.isNotBlank(defaultValue) ? defaultValue : '\"' + name + '\"') + ".getBytes()";
2188             }
2189             else if ("char[]".equals(typeName))
2190             {
2191                 String value = StringUtils.isNotBlank(defaultValue) ? defaultValue : name;
2192                 if (!value.startsWith("\""))
2193                 {
2194                     value = "\"" + value;
2195                 }
2196                 if (!value.endsWith("\""))
2197                 {
2198                     value = value + "\"";
2199                 }
2200                 rtn = value + ".toCharArray()";
2201             }
2202             else if ("String[]".equals(typeName))
2203             {
2204                 rtn = "new String[] { " + (StringUtils.isNotBlank(defaultValue) ? defaultValue : '\"' + name + '\"') + " }";
2205             }
2206             else if (isEnumeration)
2207             {
2208                 if (useMany)
2209                 {
2210                     rtn = collectionType + '<' + defaultValue + '>';
2211                 }
2212                 else
2213                 {
2214                     rtn = defaultValue;
2215                 }
2216             }
2217             else if (!StringUtils.isEmpty(defaultValue))
2218             {
2219                 rtn = "new " + typeName + '(' + defaultValue + ')';
2220             }
2221             else if (type != null && type.hasStereotype("Entity"))
2222             {
2223                 // Entity classes will always be abstract with Impl generated classes.
2224                 rtn = '(' + typeName + ")new " + typeName + "Impl()";
2225             }
2226             else if (type instanceof GeneralizableElementFacade)
2227             {
2228                 // If type has a descendant with name <typeName>Impl, assume typeNameImpl must be instantiated instead of typeName
2229                 if (typeName.endsWith("[]"))
2230                 {
2231                     rtn = "{ new " + typeName.substring(0, typeName.length()-2) + "() }";
2232                 }
2233                 else
2234                 {
2235                     rtn = "new " + typeName + "()";
2236                 }
2237                 //if (facade instanceof ClassifierFacade)
2238                 //{
2239                     //ClassifierFacade classifier = (ClassifierFacade)facade;
2240                     // If type is abstract, choose Impl descendant if exists, or the last descendant
2241                     if (type.isAbstract())
2242                     {
2243                         // Can't instantiate abstract class - pick some descendant
2244                         for (GeneralizableElementFacade spec : type.getSpecializations())
2245                         {
2246                             if (spec.getName().equals(type.getName() + "Impl"))
2247                             {
2248                                 rtn = '(' + type.getName() + ")new " + typeName + "Impl()";
2249                                 break;
2250                             }
2251                             rtn = '(' + type.getName() + ")new " + spec.getFullyQualifiedName() + "()";
2252                         }
2253                     }
2254                 //}
2255                 GeneralizableElementFacade generalization = (GeneralizableElementFacade)type;
2256                 for (GeneralizableElementFacade spec : generalization.getSpecializations())
2257                 {
2258                     if (spec.getName().equals(type.getName() + "Impl"))
2259                     {
2260                         rtn = '(' + type.getName() + ")new " + spec.getFullyQualifiedName() + "Impl()";
2261                     }
2262                 }
2263             }
2264             else if (typeName.endsWith("[]"))
2265             {
2266                 rtn = "{ new " + typeName.substring(0, typeName.length()-2) + "() }";
2267             }
2268             else
2269             {
2270                 rtn = "new " + typeName + "()";
2271             }
2272             rtn = StringUtils.replace(rtn, "java.util.Collection", "java.util.ArrayList") + toString;
2273             rtn = StringUtils.replace(rtn, "java.util.Set", "java.util.HashSet") + toString;
2274             if (logger.isDebugEnabled())
2275             {
2276                 logger.debug("facade=" + facade + " facadeName=" + facade.getName() + " type=" + type + " typeName=" + typeName + " name=" + name + " isMany=" + isMany + " defaultValue=" + defaultValue + " rtn=" + rtn);
2277             }
2278         } catch (RuntimeException e) {
2279             logger.error(e + " facade=" + facade + " facadeName=" + facade.getName() + " parent=" + parent + " type=" + type + " typeName=" + typeName + " name=" + name + " isMany=" + isMany + " defaultValue=" + defaultValue);
2280             e.printStackTrace();
2281         }
2282         return rtn;
2283     }
2284 
2285     /**
2286      * Creates a list of referenced packages for all subclasses referenced by the element.
2287      * Used to add XmlSeeAlso references to the SEI Interface.
2288      * @param service WebService containing WS operations with references.
2289      * @param pkgRef Current List of package references to be modified
2290      * @return pkgRef Collection<ModelElementFacade> referenced types
2291      */
2292     private Collection<PackageFacade> getServiceDescendantPackages(ModelElementFacade element, Collection<PackageFacade> pkgRef, Collection<ModelElementFacade> added)
2293     {
2294         if (element==null) return pkgRef;
2295         ModelElementFacade pkg = element.getPackage();
2296         if (pkg==null || pkg.getFullyQualifiedName().indexOf('.') < 1
2297             || pkg.getFullyQualifiedName().startsWith("java.util.")) return pkgRef;
2298         //name = ex.getName();
2299         if (!pkgRef.contains(pkg) && pkg instanceof PackageFacade)
2300         {
2301             pkgRef.add((PackageFacade)pkg);
2302         }
2303         if (logger.isDebugEnabled() && pkg.getName().indexOf('.')>0)
2304         {
2305             logger.debug("getServiceDescendantPackages " + element.getFullyQualifiedName() + " package " + pkg.getName() + " size=" + pkgRef.size());
2306         }
2307         if (element instanceof ClassifierFacade)
2308         {
2309             ClassifierFacade classifier = (ClassifierFacade) element;
2310             // Use commented and change getAllProperties to getProperties, if only descendant references are needed
2311             /*for (final GeneralizableElementFacade descendant : classifier.getAllSpecializations())
2312             {
2313                 pkgRef = getServiceDescendantPackages(descendant, pkgRef);
2314                 // Get all associations and attributes, down the inheritance hierarchy
2315             }*/
2316             for (final ModelElementFacade property : (List<ModelElementFacade>)classifier.getAllProperties())
2317             {
2318                 if (property instanceof AttributeFacade)
2319                 {
2320                     AttributeFacade attrib = (AttributeFacade) property;
2321                     if (!attrib.getType().equals(classifier) && !added.contains(attrib.getType())
2322                         && attrib.getType().getPackageName().indexOf('.')>0)
2323                     {
2324                         if (logger.isDebugEnabled())
2325                         {
2326                             logger.debug("getServiceDescendantPackages " + attrib.getName() + ' ' + attrib.getType().getFullyQualifiedName() + " attribute in " + classifier.getFullyQualifiedName() + " size=" + pkgRef.size());
2327                         }
2328                         added.add(attrib.getType());
2329                         pkgRef = getServiceDescendantPackages(attrib.getType(), pkgRef, added);
2330                     }
2331                 }
2332                 else if (property instanceof AssociationEndFacade)
2333                 {
2334                     AssociationEndFacade assoc = (AssociationEndFacade) property;
2335                     if (!assoc.getType().equals(classifier) && !added.contains(assoc.getType())
2336                         && assoc.getType().getPackageName().indexOf('.')>0)
2337                     {
2338                         if (logger.isDebugEnabled())
2339                         {
2340                             logger.debug("getServiceDescendantPackages " + assoc.getName() + ' ' + assoc.getType().getFullyQualifiedName() + " association in " + classifier.getFullyQualifiedName() + " size=" + pkgRef.size());
2341                         }
2342                         added.add(assoc.getType());
2343                         pkgRef = getServiceDescendantPackages(assoc.getType(), pkgRef, added);
2344                     }
2345                 }
2346             }
2347         }
2348         return pkgRef;
2349     }
2350 
2351     /**
2352      * Creates a list of referenced packages for all subclasses referenced by the service.
2353      * Used to add XmlSeeAlso references to the SEI Interface.
2354      * @param service WebService containing WS operations with references.
2355      * @param follow Follow Inheritance references $extensionInheritanceDisabled
2356      * @return typeRef Collection<ModelElementFacade> referenced types
2357      */
2358     public Collection<PackageFacade> getServiceDescendantPackages(WebServiceLogicImpl service, boolean follow)
2359     {
2360         // Note: The way XmlSeeAlso is supposed to work: any descendant classes from parameter or return or exception classes
2361         // not directly referenced by the XML types should have their package ObjectFactory added to the reference list.
2362         // The way CXF works: parameter types and type hierarchy referenced by the service are added.
2363         Collection<PackageFacade> pkgRef = new HashSet<PackageFacade>();
2364         // Keep track of elements already iterated, avoid stackOverflow.
2365         Collection<ModelElementFacade> added = new HashSet<ModelElementFacade>();
2366         // For each service parameter and return type and exception, find all descendants
2367         for (final WebServiceOperation op : service.getAllowedOperations())
2368         {
2369             if (logger.isDebugEnabled())
2370             {
2371                 logger.debug("getServiceDescendantPackages " + service.getFullyQualifiedName() + '.' + op.getName() + " parms=" + op.getParameters().size() + " size=" + pkgRef.size());
2372             }
2373             /*for (final ModelElementFacade ex : op.getExceptions())
2374             {
2375                 if (!added.contains(ex))
2376                 {
2377                     if (logger.isDebugEnabled())
2378                     {
2379                         logger.debug("getServiceDescendantPackages " + service.getFullyQualifiedName() + '.' + op.getName() + " exception=" + ex.getFullyQualifiedName() + " size=" + pkgRef.size());
2380                     }
2381                     added.add(ex);
2382                     pkgRef = getServiceDescendantPackages(ex, pkgRef, added);
2383                 }
2384             }*/
2385             for (final ParameterFacade arg : op.getParameters())
2386             {
2387                 if (!added.contains(arg.getType()))
2388                 {
2389                     if (logger.isDebugEnabled())
2390                     {
2391                         logger.debug("getServiceDescendantPackages " + service.getFullyQualifiedName() + '.' + op.getName() + " parameter=" + arg.getName() + " size=" + pkgRef.size());
2392                     }
2393                     added.add(arg.getType());
2394                     pkgRef = getServiceDescendantPackages(arg.getType(), pkgRef, added);
2395                 }
2396             }
2397 
2398         }
2399         // Don't put current package into package reference list
2400         pkgRef.remove(service.getPackage());
2401         return pkgRef;
2402     }
2403 
2404     /**
2405      * Creates a list of referenced types for the service.
2406      * Used to add element references to the service namespace, for bare parameters.
2407      * @param service WebService containing WS operations with references.
2408      * @param follow Follow Inheritance references $extensionInheritanceDisabled
2409      * @return typeRef Collection<ModelElementFacade> referenced types
2410      */
2411     public Collection<ModelElementFacade> getServiceReferences(WebServiceLogicImpl service, boolean follow)
2412     {
2413         Collection<ModelElementFacade> typeRef = new HashSet<ModelElementFacade>();
2414         // Temporary holder until we determine that the service can be bare
2415         Collection<ModelElementFacade> opRef = new HashSet<ModelElementFacade>();
2416         //String name = null;
2417         String pkg = null;
2418         @SuppressWarnings("unused")
2419         String typeRefs = "";
2420         // Copy package names and collection of related packages to package references list
2421         // Add references from the operations of the service package itself
2422         for (final WebServiceOperation op : service.getAllowedOperations())
2423         {
2424             boolean isMany = false;
2425             /*for (final ModelElementFacade ex : op.getExceptions())
2426             {
2427                 pkg = ex.getPackageName();
2428                 //name = ex.getName();
2429                 if (pkg!=null && pkg.indexOf('.') > 0 && !typeRef.contains(ex) && !opRef.contains(ex))
2430                 {
2431                     opRef.add(ex);
2432                     if (logger.isDebugEnabled())
2433                     {
2434                         typeRefs += ex + ",";
2435                         logger.debug("getServiceReferences exception " + pkg + '.' + ex.getName());
2436                     }
2437                 }
2438             }*/
2439             for (final ParameterFacade arg : op.getParameters())
2440             {
2441                 pkg = arg.getType().getPackageName();
2442                 //name = arg.getType().getName();
2443                 if (arg.getUpper()>1 || arg.getUpper()==-1)
2444                 {
2445                     // Can't handle return size > 1 for object - need wrapper
2446                     isMany = true;
2447                 }
2448                 if (pkg!=null && pkg.indexOf('.') > 0 && !typeRef.contains(arg.getType()) && !opRef.contains(arg.getType()))
2449                 {
2450                     opRef.add(arg.getType());
2451                     if (logger.isDebugEnabled())
2452                     {
2453                         typeRefs += arg.getType() + ",";
2454                         logger.debug("getServiceReferences parameter " + pkg + '.' + arg.getType().getName());
2455                     }
2456                 }
2457             }
2458 /*            if (op.getReturnType()!=null)
2459             {
2460                 ClassifierFacade rtnType = op.getReturnType();
2461                 pkg = rtnType.getPackageName();
2462                 //name = rtnType.getName();
2463                 if (logger.isDebugEnabled())
2464                 {
2465                     logger.debug("getServiceReferences packageName=" + packageName + " return " + pkg + "." + name);
2466                 }
2467                 if (pkg!=null && !pkg.equals(service.getPackageName()) && pkg.indexOf('.') > 0 && !typeRef.contains(rtnType))
2468                 {
2469                     typeRef.add(rtnType);
2470                     //pkgRefs += pkg + ",";
2471                     if (logger.isDebugEnabled())
2472                     {
2473                         logger.debug("getServiceReferences packageName=" + packageName + " add return " + pkg + "." + name);
2474                     }
2475                 }
2476             }*/
2477             if (!isMany)
2478             {
2479                 typeRef.addAll(opRef);
2480             }
2481         }
2482         /*for (final ModelElementFacade type : typeRef)
2483         {
2484             if (logger.isDebugEnabled())
2485             {
2486                 logger.debug("getServiceReferences packageName=" + type.getPackageName() + "." + type.getName());
2487             }
2488         }*/
2489         if (logger.isDebugEnabled())
2490         {
2491             logger.debug("getServiceReferences typeRef " + service.getPackageName() + '.' + service.getName() + ' ' + typeRef);
2492         }
2493         return typeRef;
2494     }
2495 
2496     /**
2497      * Reverses the <code>packageName</code>.
2498      *
2499      * @param packageName the package name to reverse.
2500      * @return the reversed package name.
2501      */
2502     public static String reversePackage(String packageName)
2503     {
2504         if (StringUtils.isBlank(packageName))
2505         {
2506             return "";
2507         }
2508         if (packageName.startsWith("http://"))
2509         {
2510             packageName = packageName.substring(7);
2511         }
2512         return StringUtils.reverseDelimited(packageName, WebServiceGlobals.NAMESPACE_DELIMITER);
2513     }
2514 
2515     private static FastDateFormat df = FastDateFormat.getInstance("MM/dd/yyyy HH:mm:ssZ");
2516 
2517     /**
2518      * Returns the current Date in the specified format.
2519      *
2520      * @param format The format for the output date
2521      * @return the current date in the specified format.
2522      */
2523     public static String getDate(String format)
2524     {
2525         if (df == null || !format.equals(df.getPattern()))
2526         {
2527             df = FastDateFormat.getInstance(format);
2528         }
2529         return df.format(new Date());
2530     }
2531 
2532     /**
2533      * Returns the current Date in the specified format.
2534      *
2535      * @return the current date with the default format .
2536      */
2537     public static String getDate()
2538     {
2539         return df.format(new Date());
2540     }
2541 
2542     /**
2543      * Determine how a model type is mapped to a java implementation type.
2544      * Used to resolve conflicts between java and webservice type mappings.
2545      * i.e. webservice maps Integer as BigInteger and Date/Time/DateTime as Calendar, so
2546      * Value Object attributes will not match webservice attribute types.
2547      * Called from vsl $webServiceUtils.getTypeMapping($service.
2548      * @param mappings
2549      * @param from
2550      *
2551      * @return the String mapping type to.
2552      */
2553     public String getTypeMapping(TypeMappings mappings, String from)
2554     {
2555         // URI is the namespace value in andromda.xml configuration parameter for the type mapping
2556         //MetafacadeFactory.getInstance().getRegisteredProperty( metafacade, "languageMappingsUri");
2557         //Object property = metafacade.getConfiguredProperty("languageMappingsUri");
2558         //TypeMappings mappings = TypeMappings.getInstance(property);
2559         return mappings.getTo("datatype::"+from);
2560     }
2561 
2562     /**
2563      * <p> Creates and returns the schema type for the given <code>type</code>.
2564      * It finds the mapped schema type from the passed in
2565      * <code>schemaTypeMappings</code>.
2566      * </p>
2567      *
2568      * @param type the ClassifierFacade instance
2569      * @param schemaTypeMappings contains the mappings from model datatypes to
2570      *        schema datatypes.
2571      * @param namespacePrefix the prefix given to the schema type if it's a
2572      *        custom type (non XSD type).
2573      * @param qName the qualified name
2574      * @param wrappedArrayTypePrefix a prefix to give to wrapped array types.
2575      * @param withPrefix a flag indicating whether or not the type should have
2576      *        the prefix defined
2577      * @param preserveArray true/false, if true then if the schema type is an
2578      *        array we'll preserve the fact that its an array and return an
2579      *        array schema type name. If false we will return back the non array
2580      *        type even if its an array.
2581      * @return the schema type name - String
2582      */
2583     public static String getSchemaType(
2584         ClassifierFacade type,
2585         TypeMappings schemaTypeMappings,
2586         String namespacePrefix,
2587         String qName,
2588         String wrappedArrayTypePrefix,
2589         boolean withPrefix,
2590         boolean preserveArray)
2591     {
2592         StringBuilder schemaType = new StringBuilder();
2593         String modelName = type.getFullyQualifiedName(true);
2594         if (schemaTypeMappings != null)
2595         {
2596             namespacePrefix += ':';
2597             String mappedValue = schemaTypeMappings.getTo(modelName);
2598             if (!mappedValue.equals(modelName) || StringUtils.isEmpty(type.getPackageName()))
2599             {
2600                 schemaType.append(mappedValue);
2601             }
2602             else
2603             {
2604                 if (withPrefix)
2605                 {
2606                     schemaType.append(namespacePrefix);
2607                 }
2608                 if (type.isArrayType())
2609                 {
2610                     ClassifierFacade nonArray = type.getNonArray();
2611                     if (nonArray != null)
2612                     {
2613                         if (nonArray instanceof WSDLType)
2614                         {
2615                             schemaType.append(((WSDLType)nonArray).getName());
2616                         }
2617                         else if (nonArray instanceof WSDLEnumerationType)
2618                         {
2619                             schemaType.append(((WSDLEnumerationType)nonArray).getName());
2620                         }
2621                     }
2622                 }
2623                 else
2624                 {
2625                     schemaType.append(qName);
2626                 }
2627             }
2628             // remove any array '[]' suffix
2629             schemaType = new StringBuilder(schemaType.toString().replaceAll("\\[\\]", ""));
2630             if (preserveArray && type.isArrayType())
2631             {
2632                 int insertIndex = namespacePrefix.length();
2633                 if (!schemaType.toString().startsWith(namespacePrefix))
2634                 {
2635                     if (withPrefix)
2636                     {
2637                         // add the prefix for any normal XSD types
2638                         // that may not have been set above
2639                         schemaType.insert(0, namespacePrefix);
2640                     }
2641                     else
2642                     {
2643                         // since we aren't adding the prefix, set
2644                         // the correct insert index
2645                         insertIndex = 0;
2646                     }
2647                 }
2648                 schemaType.insert(insertIndex, wrappedArrayTypePrefix);
2649             }
2650             if (withPrefix && !schemaType.toString().startsWith(namespacePrefix))
2651             {
2652                 schemaType.insert(0, WebServiceGlobals.XSD_NAMESPACE_PREFIX);
2653             }
2654         }
2655         return schemaType.toString();
2656     }
2657 
2658     /**
2659      * <p> Returns true if java.lang.* or java.util.* datatype and not many*
2660      * </p>
2661      *
2662      * @param element the ClassifierFacade instance
2663      * @return if type is one of the PrimitiveTypes and not an array/list
2664      */
2665     public static boolean isSimpleType(ModelElementFacade element)
2666     {
2667         boolean simple = false;
2668         String typeName = null;
2669         ClassifierFacade type = null;
2670         boolean many = false;
2671         if (element instanceof AttributeFacade)
2672         {
2673             AttributeFacade attrib = (AttributeFacade)element;
2674             type = attrib.getType();
2675             many = attrib.isMany() && !type.isArrayType() && !type.isCollectionType();
2676         }
2677         else if (element instanceof AssociationEndFacade)
2678         {
2679             AssociationEndFacade association = (AssociationEndFacade)element;
2680             type = association.getType();
2681             many = association.isMany() && !type.isArrayType() && !type.isCollectionType();
2682         }
2683         else if (element instanceof ParameterFacade)
2684         {
2685             ParameterFacade param = (ParameterFacade)element;
2686             type = param.getType();
2687             many = param.isMany() && !type.isArrayType() && !type.isCollectionType();
2688         }
2689         else if (element instanceof WSDLTypeAttributeLogic)
2690         {
2691             WSDLTypeAttributeLogic attrib = (WSDLTypeAttributeLogic)element;
2692             type = attrib.getType();
2693             many = attrib.isMany() && !type.isArrayType() && !type.isCollectionType();
2694         }
2695         else if (element instanceof WSDLTypeAssociationEndLogic)
2696         {
2697             WSDLTypeAssociationEndLogic association = (WSDLTypeAssociationEndLogic)element;
2698             type = association.getType();
2699             many = association.isMany() && !type.isArrayType() && !type.isCollectionType();
2700         }
2701         else if (element instanceof WebServiceParameterLogic)
2702         {
2703             WebServiceParameterLogic param = (WebServiceParameterLogic)element;
2704             type = param.getType();
2705             many = param.isMany() && !type.isArrayType() && !type.isCollectionType();
2706         }
2707         else if (element instanceof ClassifierFacade)
2708         {
2709             ClassifierFacade classifier = (ClassifierFacade)element;
2710             type = classifier;
2711         }
2712         else
2713         {
2714             return simple;
2715         }
2716         typeName = type.getFullyQualifiedName();
2717         if (type.isPrimitive() || typeName.startsWith("java.lang.") || typeName.startsWith("java.util.")
2718             || !typeName.contains("."))
2719         {
2720             if (!many)
2721             {
2722                 simple = true;
2723             }
2724         }
2725         return simple;
2726     }
2727 }