1 package org.andromda.cartridges.webservice.metafacades;
2
3 import java.text.Collator;
4 import java.text.MessageFormat;
5 import java.util.ArrayList;
6 import java.util.Collection;
7 import java.util.Collections;
8 import java.util.Comparator;
9 import java.util.HashMap;
10 import java.util.HashSet;
11 import java.util.Iterator;
12 import java.util.LinkedHashSet;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.Set;
16 import java.util.TreeMap;
17 import java.util.TreeSet;
18 import org.andromda.cartridges.webservice.WebServiceGlobals;
19 import org.andromda.cartridges.webservice.WebServiceUtils;
20 import org.andromda.core.common.ExceptionUtils;
21 import org.andromda.core.common.Introspector;
22 import org.andromda.core.metafacade.MetafacadeBase;
23 import org.andromda.core.metafacade.MetafacadeException;
24 import org.andromda.core.metafacade.ModelValidationMessage;
25 import org.andromda.metafacades.uml.AssociationEndFacade;
26 import org.andromda.metafacades.uml.AttributeFacade;
27 import org.andromda.metafacades.uml.ClassifierFacade;
28 import org.andromda.metafacades.uml.GeneralizableElementFacade;
29 import org.andromda.metafacades.uml.ModelElementFacade;
30 import org.andromda.metafacades.uml.OperationFacade;
31 import org.andromda.metafacades.uml.PackageFacade;
32 import org.andromda.metafacades.uml.ParameterFacade;
33 import org.andromda.metafacades.uml.Role;
34 import org.andromda.metafacades.uml.ServiceOperation;
35 import org.andromda.metafacades.uml.TypeMappings;
36 import org.andromda.metafacades.uml.UMLMetafacadeProperties;
37 import org.andromda.metafacades.uml.UMLProfile;
38 import org.andromda.translation.ocl.validation.OCLExpressions;
39 import org.andromda.translation.ocl.validation.OCLIntrospector;
40 import org.apache.commons.collections.Closure;
41 import org.apache.commons.collections.CollectionUtils;
42 import org.apache.commons.collections.Predicate;
43 import org.apache.commons.lang.ObjectUtils;
44 import org.apache.commons.lang.StringUtils;
45 import org.apache.log4j.Logger;
46
47
48
49
50
51
52
53 public class WebServiceLogicImpl
54 extends WebServiceLogic
55 {
56 private static final long serialVersionUID = 34L;
57
58
59
60
61
62 public WebServiceLogicImpl(
63 Object metaObject,
64 String context)
65 {
66 super(metaObject, context);
67 }
68
69
70
71
72 private static final Logger logger = Logger.getLogger(WebServiceLogicImpl.class);
73
74 private static final String DEFAULT = "default";
75
76
77
78
79
80 protected Collection<OperationFacade> handleGetAllowedOperations()
81 {
82 List<OperationFacade> operations = new ArrayList<OperationFacade>(this.getOperations());
83 CollectionUtils.filter(
84 operations,
85 new Predicate()
86 {
87 public boolean evaluate(Object object)
88 {
89 boolean valid = WebServiceOperation.class.isAssignableFrom(object.getClass());
90 if (valid)
91 {
92 valid = ((WebServiceOperation)object).isExposed();
93 }
94 return valid;
95 }
96 });
97 if (this.getWSDLOperationSortMode().equals(OPERATION_SORT_MODE_NAME))
98 {
99 Collections.sort(
100 operations,
101 new OperationNameComparator());
102 }
103 return operations;
104 }
105
106
107
108
109
110 protected String handleGetAllowedMethods()
111 {
112 Collection<String> methodNames = new ArrayList<String>();
113 Collection<WebServiceOperation> operations = this.getAllowedOperations();
114 if (operations != null && !operations.isEmpty())
115 {
116 for (WebServiceOperation operation : operations)
117 {
118 methodNames.add(StringUtils.trimToEmpty(operation.getName()));
119 }
120 }
121 return StringUtils.join(
122 methodNames.iterator(),
123 " ");
124 }
125
126
127
128
129
130 protected String handleGetQName()
131 {
132 return MessageFormat.format(
133 this.getQualifiedNameLocalPartPattern(),
134 StringUtils.trimToEmpty(this.getName()));
135 }
136
137
138
139
140
141 protected String handleGetNamespace()
142 {
143 String packageName = this.getPackageName();
144 if (this.isReverseNamespace())
145 {
146 packageName = WebServiceUtils.reversePackage(packageName);
147 }
148 return MessageFormat.format(
149 this.getNamespacePattern(),
150 StringUtils.trimToEmpty(packageName));
151 }
152
153
154
155
156 private static final String PROPERTY_DEFAULT_STYLE = "defaultStyle";
157
158
159
160
161
162 protected String handleGetStyle()
163 {
164 String style = (String)this.findTaggedValue(UMLProfile.TAGGEDVALUE_WEBSERVICE_STYLE);
165 if (StringUtils.isBlank(style) || style.equals(DEFAULT))
166 {
167 style = String.valueOf(this.getConfiguredProperty(PROPERTY_DEFAULT_STYLE));
168 }
169 return style;
170 }
171
172
173
174
175 private static final String PROPERTY_DEFAULT_USE = "defaultUse";
176
177
178
179
180
181 protected String handleGetUse()
182 {
183 String use = (String)this.findTaggedValue(UMLProfile.TAGGEDVALUE_WEBSERVICE_USE);
184 if (StringUtils.isBlank(use) || use.equals(DEFAULT))
185 {
186 use = String.valueOf(this.getConfiguredProperty(PROPERTY_DEFAULT_USE));
187 }
188 return use;
189 }
190
191
192
193
194 private Set<ModelElementFacade> elementSet = new TreeSet<ModelElementFacade>(new TypeComparator());
195
196
197
198
199
200 private Collection<ModelElementFacade> checkedTypes = new ArrayList<ModelElementFacade>();
201
202
203
204
205
206 protected Collection<ModelElementFacade> handleGetTypeMappingElements()
207 {
208 final Collection<ParameterFacade> parameterTypes = new LinkedHashSet<ParameterFacade>();
209 for (final WebServiceOperation operation : this.getAllowedOperations())
210 {
211 parameterTypes.addAll(operation.getParameters());
212 }
213
214 final Set<ModelElementFacade> types = new TreeSet<ModelElementFacade>(new TypeComparator());
215 final Collection<ModelElementFacade> nonArrayTypes = new TreeSet<ModelElementFacade>(new TypeComparator());
216
217
218
219
220 this.checkedTypes.clear();
221 for (final ParameterFacade parameter : parameterTypes)
222 {
223 this.loadTypes((ModelElementFacade)parameter, types, nonArrayTypes);
224 }
225
226 for (final WebServiceOperation operation : this.getAllowedOperations())
227 {
228 final Collection<ModelElementFacade> exceptions = operation.getExceptions();
229 exceptions.addAll(exceptions);
230
231 for (final ModelElementFacade exception : exceptions)
232 {
233 this.loadTypes(exception, types, nonArrayTypes);
234 }
235 }
236
237
238
239
240
241 types.addAll(nonArrayTypes);
242
243 this.elementSet = types;
244
245 return types;
246 }
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262 private void loadTypes(ModelElementFacade modelElement, Set<ModelElementFacade> types,
263 Collection<ModelElementFacade> nonArrayTypes)
264 {
265 ExceptionUtils.checkNull("types", types);
266 ExceptionUtils.checkNull("nonArrayTypes", nonArrayTypes);
267
268 try
269 {
270 if (modelElement != null && !this.checkedTypes.contains(modelElement))
271 {
272 final ClassifierFacade parameterType = this.getType(modelElement);
273
274
275 if (parameterType != null)
276 {
277 final Set<ModelElementFacade> allTypes = new LinkedHashSet<ModelElementFacade>();
278 allTypes.add(parameterType);
279
280
281 final Collection<GeneralizableElementFacade> generalizations = parameterType.getAllGeneralizations();
282
283 if (generalizations != null)
284 {
285 allTypes.addAll(generalizations);
286 }
287
288 final Collection<GeneralizableElementFacade> specializations = parameterType.getAllSpecializations();
289
290 if (specializations != null)
291 {
292 allTypes.addAll(specializations);
293 }
294
295 if (!this.checkedTypes.contains(parameterType))
296 {
297 this.checkedTypes.add(parameterType);
298
299 for (final Iterator allTypesIterator = allTypes.iterator(); allTypesIterator.hasNext();)
300 {
301 ClassifierFacade type = (ClassifierFacade) allTypesIterator.next();
302
303 if (!this.containsManyType(types, modelElement))
304 {
305 ClassifierFacade nonArrayType = type;
306 final boolean arrayType = type.isArrayType();
307
308 if (arrayType || this.isValidAssociationEnd(modelElement))
309 {
310 types.add(modelElement);
311
312 if (arrayType)
313 {
314
315
316 nonArrayType = type.getNonArray();
317
318
319
320 type = nonArrayType;
321 }
322 }
323
324 if (nonArrayType != null)
325 {
326 if (nonArrayType.hasStereotype(UMLProfile.STEREOTYPE_VALUE_OBJECT)
327 || nonArrayType.hasStereotype(UMLProfile.STEREOTYPE_APPLICATION_EXCEPTION)
328 || nonArrayType.isEnumeration())
329 {
330
331
332
333
334
335 nonArrayTypes.add(nonArrayType);
336 }
337 }
338 }
339
340 if (type != null)
341 {
342 final List<? extends ModelElementFacade> properties = type.getProperties();
343 if (properties != null && !properties.isEmpty())
344 {
345 for (final ModelElementFacade property : properties)
346 {
347
348 if (!property.getFullyQualifiedName().equals(modelElement.getFullyQualifiedName()))
349 {
350 this.loadTypes(property, types, nonArrayTypes);
351 }
352 }
353 }
354 }
355 }
356 }
357 }
358 }
359 }
360 catch (final Throwable throwable)
361 {
362 final String message = "Error performing loadTypes";
363 logger.error(throwable);
364 throw new MetafacadeException(message, throwable);
365 }
366 }
367
368
369
370
371 private Map<String, String> packageAbbr = new TreeMap<String, String>();
372 private static final String EMPTY_STRING = "";
373
374
375
376
377
378 protected Collection<String> handleGetPackages()
379 {
380 if (this.elementSet == null || this.elementSet.size()<1)
381 {
382 this.elementSet = (TreeSet<ModelElementFacade>)handleGetTypeMappingElements();
383 }
384 setPkgAbbr(this.elementSet);
385 @SuppressWarnings("unused")
386 String pkgList = EMPTY_STRING;
387 for (final String pkg : this.packageAbbr.keySet())
388 {
389 pkgList += pkg + ", ";
390 }
391 return this.packageAbbr.keySet();
392 }
393
394
395
396
397
398 protected String handleGetPkgAbbr(String pkgName)
399 {
400 if (StringUtils.isBlank(pkgName) || pkgName.length()<1)
401 {
402 return EMPTY_STRING;
403 }
404 if (this.elementSet == null || this.elementSet.size()<1)
405 {
406 this.elementSet = (TreeSet<ModelElementFacade>)handleGetTypeMappingElements();
407 }
408 if (this.packageAbbr == null || this.packageAbbr.size()<1)
409 {
410 setPkgAbbr(this.elementSet);
411 }
412 String rtn = this.packageAbbr.get(pkgName);
413 if (StringUtils.isBlank(rtn))
414 {
415
416 int namespaceCount = this.packageAbbr.size();
417 rtn = "ns" + namespaceCount;
418 this.packageAbbr.put(pkgName, rtn);
419 logger.info(this.getName() + " missing PkgAbbr for " + pkgName);
420 }
421 return rtn;
422 }
423
424
425
426
427
428
429
430
431 private Map<String, String> setPkgAbbr(Set<ModelElementFacade> types)
432 {
433 Map<String, String> pkgAbbr = new TreeMap<String, String>();
434 int namespaceCount = 1;
435
436 for (final OperationFacade op : this.getOperations())
437 {
438 for (final Iterator opiterator = op.getExceptions().iterator(); opiterator.hasNext();)
439 {
440 ModelElementFacade arg = (ModelElementFacade)opiterator.next();
441 String pkg = arg.getPackageName();
442 if (!pkgAbbr.containsKey(pkg) && pkg != null && pkg.indexOf('.') > 0)
443 {
444 pkgAbbr.put(pkg, "ns" + namespaceCount);
445 namespaceCount++;
446 }
447 }
448 for (final ParameterFacade arg : op.getArguments())
449 {
450 String pkg = arg.getPackageName();
451 if (!pkgAbbr.containsKey(pkg) && pkg != null && pkg.indexOf('.') > 0)
452 {
453 pkgAbbr.put(pkg, "ns" + namespaceCount);
454 namespaceCount++;
455 }
456 }
457 if (op.getReturnType()!=null)
458 {
459 String pkg = op.getReturnType().getPackageName();
460 if (!pkgAbbr.containsKey(pkg) && pkg != null && pkg.indexOf('.') > 0)
461 {
462 pkgAbbr.put(pkg, "ns" + namespaceCount);
463 namespaceCount++;
464 }
465 }
466 }
467 for (final Iterator iterator = types.iterator(); iterator.hasNext();)
468 {
469 ModelElementFacade type = ((ModelElementFacade)iterator.next());
470 String pkg = type.getPackageName();
471 if (!pkgAbbr.containsKey(pkg) && pkg != null && pkg.indexOf('.') > 0)
472 {
473 pkgAbbr.put(pkg, "ns" + namespaceCount);
474 namespaceCount++;
475 }
476 }
477 this.packageAbbr = pkgAbbr;
478 return pkgAbbr;
479 }
480
481
482
483
484 private Map<String, Set<String>> packageRefs = new HashMap<String, Set<String>>();
485
486
487
488
489
490
491
492 protected Collection<String> handleGetPackageReferences(String pkg, boolean follow)
493 {
494
495
496 this.elementSet = (TreeSet<ModelElementFacade>)handleGetTypeMappingElements();
497
498
499
500 setPkgRefs(this.elementSet, follow);
501
502 return this.packageRefs.get(pkg);
503 }
504
505
506
507
508
509
510
511
512 private Map<String, Set<String>> setPkgRefs(Set<ModelElementFacade> types, boolean follow)
513 {
514
515
516 for (final Iterator<ModelElementFacade> iterator = types.iterator(); iterator.hasNext();)
517 {
518 try
519 {
520 MetafacadeBase element = (MetafacadeBase)iterator.next();
521 if (element instanceof WSDLTypeLogicImpl)
522 {
523 WSDLTypeLogicImpl type = (WSDLTypeLogicImpl)element;
524 String pkg = type.getPackageName();
525 if (pkg != null && pkg.indexOf('.') > 0)
526 {
527
528 for (final Iterator<AttributeFacade> itAttr = type.getAttributes(follow).iterator(); itAttr.hasNext();)
529 {
530 try
531 {
532 ModelElementFacade attr = (itAttr.next());
533 if (getType(attr) != null)
534 {
535 attr = getType(attr);
536 }
537 addPkgRef(pkg, attr.getPackageName(), attr);
538 }
539 catch (Exception e)
540 {
541 logger.error("WebServiceLogicImpl.setPkgRefs getAttributes: " + e);
542 }
543 }
544 }
545 }
546 else if (element instanceof WSDLTypeAssociationEndLogicImpl)
547 {
548 WSDLTypeAssociationEndLogicImpl type = (WSDLTypeAssociationEndLogicImpl)element;
549 String pkg = type.getPackageName();
550 if (pkg != null && pkg.indexOf('.') > 0)
551 {
552
553 for (final Iterator<AssociationEndFacade> otherEnds = type.getType().getNavigableConnectingEnds(follow).iterator(); otherEnds.hasNext();)
554 {
555 try
556 {
557 ModelElementFacade otherEnd = ((ModelElementFacade)otherEnds.next());
558 if (getType(otherEnd) != null)
559 {
560 otherEnd = getType(otherEnd);
561 }
562 addPkgRef(pkg, otherEnd.getPackageName(), otherEnd);
563 }
564 catch (RuntimeException e)
565 {
566 logger.error("WebServiceLogicImpl.setPkgRefs getNavigableConnectingEnds: " + e);
567 }
568 }
569 }
570 }
571 else
572 {
573
574 logger.error("Unexpected element type: " + element);
575 }
576 }
577 catch (Exception e)
578 {
579 logger.error("WebServiceLogicImpl.setPkgRefs types: " + e);
580 }
581 }
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630 for (final OperationFacade op : this.getOperations())
631 {
632 for (final Object exception : op.getExceptions())
633 {
634 ModelElementFacade arg = (ModelElementFacade)exception;
635 addPkgRef(this.getPackageName(), arg.getPackageName(), arg);
636 }
637 for (final ParameterFacade arg : op.getArguments())
638 {
639 addPkgRef(this.getPackageName(), arg.getPackageName(), arg);
640 }
641 if (op.getReturnType()!=null)
642 {
643 String pkg = op.getReturnType().getPackageName();
644 addPkgRef(this.getPackageName(), pkg, op.getReturnType());
645 }
646 }
647 return packageRefs;
648 }
649
650 private void addPkgRef(String pkg, String pkgRef, ModelElementFacade type)
651 {
652 Set<String> pkgRefSet;
653 if (!packageRefs.containsKey(pkg))
654 {
655
656 pkgRefSet = new TreeSet<String>();
657 packageRefs.put(pkg, pkgRefSet);
658 }
659 else
660 {
661
662 pkgRefSet = packageRefs.get(pkg);
663 }
664 if (pkgRef!=null && pkg!=null && !pkgRef.equals(pkg) && pkgRef.indexOf('.') > 0 && !pkgRefSet.contains(pkgRef))
665 {
666 pkgRefSet.add(pkgRef);
667 logger.debug("Added pkgRef " + pkg + " references " + pkgRef + " in " + type.getName());
668 }
669 }
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687 private boolean containsManyType(
688 final Collection<ModelElementFacade> types,
689 final Object modelElement)
690 {
691 final ClassifierFacade compareType = this.getClassifier(modelElement);
692 boolean containsManyType = false;
693 if (compareType != null)
694 {
695 containsManyType =
696 CollectionUtils.find(
697 types,
698 new Predicate()
699 {
700 public boolean evaluate(Object object)
701 {
702 return compareType.equals(getClassifier(object));
703 }
704 }) != null;
705 }
706 return containsManyType;
707 }
708
709
710
711
712
713
714
715 private ClassifierFacade getClassifier(final Object element)
716 {
717 ClassifierFacade type = null;
718 if (element instanceof AssociationEndFacade)
719 {
720 AssociationEndFacade end = (AssociationEndFacade)element;
721 if (end.isMany())
722 {
723 type = ((AssociationEndFacade)element).getType();
724 }
725 }
726 else if (element instanceof AttributeFacade)
727 {
728 type = ((AttributeFacade)element).getType();
729 }
730 else if (element instanceof ParameterFacade)
731 {
732 type = ((ParameterFacade)element).getType();
733 }
734 if (element instanceof ClassifierFacade)
735 {
736 type = (ClassifierFacade)element;
737 }
738 if (type != null)
739 {
740 if (type.isArrayType())
741 {
742 type = type.getNonArray();
743 }
744 }
745 return type;
746 }
747
748
749
750
751
752
753
754
755 private boolean isValidAssociationEnd(Object modelElement)
756 {
757 return modelElement instanceof AssociationEndFacade && ((AssociationEndFacade)modelElement).isMany();
758 }
759
760
761
762
763
764 protected String handleGetProvider()
765 {
766 String provider = (String)this.findTaggedValue(UMLProfile.TAGGEDVALUE_WEBSERVICE_PROVIDER);
767 if (StringUtils.isBlank(provider) || provider.equals(DEFAULT))
768 {
769 provider = (String)this.getConfiguredProperty("defaultProvider");
770 }
771 return provider;
772 }
773
774
775
776
777
778 protected String handleGetWsdlFile()
779 {
780 return StringUtils.replace(
781 this.getFullyQualifiedName(),
782 String.valueOf(this.getConfiguredProperty(UMLMetafacadeProperties.NAMESPACE_SEPARATOR)),
783 "/") + ".wsdl";
784 }
785
786
787
788
789 public final class TypeComparator
790 implements Comparator
791 {
792 private final Collator collator = Collator.getInstance();
793
794
795
796
797 public TypeComparator()
798 {
799 collator.setStrength(Collator.PRIMARY);
800 }
801
802
803
804
805 public int compare(
806 Object objectA,
807 Object objectB)
808 {
809 final ModelElementFacade a = (ModelElementFacade)objectA;
810 ModelElementFacade aType = getType(a);
811 if (aType == null)
812 {
813 aType = a;
814 }
815 final ModelElementFacade b = (ModelElementFacade)objectB;
816 ModelElementFacade bType = getType(b);
817 if (bType == null)
818 {
819 bType = b;
820 }
821 return collator.compare(
822 aType.getFullyQualifiedName(),
823 bType.getFullyQualifiedName());
824 }
825 }
826
827
828
829
830
831
832
833
834 public ClassifierFacade getType(Object modelElement)
835 {
836 try
837 {
838 final Introspector introspector = Introspector.instance();
839 ClassifierFacade type = null;
840 String typeProperty = "type";
841
842
843 if (introspector.isReadable(modelElement, typeProperty))
844 {
845 type = (ClassifierFacade)introspector.getProperty(modelElement, typeProperty);
846 }
847
848
849 typeProperty = "returnType";
850 if (type == null && introspector.isReadable(modelElement, typeProperty))
851 {
852 type = (ClassifierFacade)introspector.getProperty(modelElement, typeProperty);
853 }
854
855 if (type == null && modelElement instanceof ClassifierFacade)
856 {
857 type = (ClassifierFacade)modelElement;
858 }
859 return type;
860 }
861 catch (final Throwable throwable)
862 {
863 String errMsg = "Error performing WebServiceLogicImpl.getType";
864 logger.error(errMsg, throwable);
865 throw new MetafacadeException(errMsg, throwable);
866 }
867 }
868
869
870
871
872 static final String NAMESPACE_PREFIX = "namespacePrefix";
873
874
875
876
877
878 protected String handleGetNamespacePrefix()
879 {
880 String prefix = (String)this.getConfiguredProperty(NAMESPACE_PREFIX);
881 if (StringUtils.isBlank(prefix))
882 {
883 prefix = "impl";
884 }
885 return prefix;
886 }
887
888
889
890
891 static final String QNAME_LOCAL_PART_PATTERN = "qualifiedNameLocalPartPattern";
892
893
894
895
896
897 protected String getQualifiedNameLocalPartPattern()
898 {
899 String pattern = (String)this.getConfiguredProperty(QNAME_LOCAL_PART_PATTERN);
900 if (StringUtils.isBlank(pattern))
901 {
902 pattern = "{0}";
903 }
904 return pattern;
905 }
906
907
908
909
910 static final String NAMESPACE_PATTERN = "namespacePattern";
911
912
913
914
915
916
917 protected String getNamespacePattern()
918 {
919 String pattern = (String)this.getConfiguredProperty(NAMESPACE_PATTERN);
920 if (StringUtils.isBlank(pattern))
921 {
922 pattern = "http://{0}/";
923 }
924 return pattern;
925 }
926
927
928
929
930 static final String REVERSE_NAMESPACE = "reverseNamespace";
931
932
933
934
935
936
937 protected boolean isReverseNamespace()
938 {
939 return Boolean.valueOf(String.valueOf(this.getConfiguredProperty(REVERSE_NAMESPACE))).booleanValue();
940 }
941
942
943
944
945
946 protected String handleGetEjbJndiName()
947 {
948 StringBuilder jndiName = new StringBuilder();
949 String jndiNamePrefix = StringUtils.trimToEmpty(this.getEjbJndiNamePrefix());
950 if (StringUtils.isNotBlank(jndiNamePrefix))
951 {
952 jndiName.append(jndiNamePrefix);
953 jndiName.append('/');
954 }
955 jndiName.append("ejb/");
956 jndiName.append(this.getFullyQualifiedName());
957 return jndiName.toString();
958 }
959
960
961
962
963
964
965 protected String getEjbJndiNamePrefix()
966 {
967 final String property = "ejbJndiNamePrefix";
968 return this.isConfiguredProperty(property) ? ObjectUtils.toString(this.getConfiguredProperty(property)) : null;
969 }
970
971
972
973
974
975 protected String handleGetEjbHomeInterface()
976 {
977 return MessageFormat.format(
978 this.getEjbHomeInterfacePattern(),
979 StringUtils.trimToEmpty(this.getPackageName()), StringUtils.trimToEmpty(this.getName()));
980 }
981
982
983
984
985
986
987 protected String getEjbHomeInterfacePattern()
988 {
989 return (String)this.getConfiguredProperty("ejbHomeInterfacePattern");
990 }
991
992
993
994
995
996 protected String handleGetEjbInterface()
997 {
998 return MessageFormat.format(
999 this.getEjbInterfacePattern(),
1000 StringUtils.trimToEmpty(this.getPackageName()), StringUtils.trimToEmpty(this.getName()));
1001 }
1002
1003
1004
1005
1006
1007
1008 protected String getEjbInterfacePattern()
1009 {
1010 return (String)this.getConfiguredProperty("ejbInterfacePattern");
1011 }
1012
1013 private static final String RPC_CLASS_NAME_PATTERN = "rpcClassNamePattern";
1014
1015
1016
1017
1018
1019 protected String getRpcClassNamePattern()
1020 {
1021 return (String)this.getConfiguredProperty(RPC_CLASS_NAME_PATTERN);
1022 }
1023
1024
1025
1026
1027
1028 protected String handleGetRpcClassName()
1029 {
1030 return MessageFormat.format(
1031 this.getRpcClassNamePattern(),
1032 StringUtils.trimToEmpty(this.getPackageName()), StringUtils.trimToEmpty(this.getName()));
1033 }
1034
1035 private static final String WSDL_OPERATION_SORT_MODE = "wsdlOperationSortMode";
1036
1037
1038
1039
1040 public static final class OperationNameComparator
1041 implements Comparator
1042 {
1043 private final Collator collator = Collator.getInstance();
1044
1045
1046
1047
1048 public OperationNameComparator()
1049 {
1050 collator.setStrength(Collator.PRIMARY);
1051 }
1052
1053
1054
1055
1056 public int compare(
1057 Object objectA,
1058 Object objectB)
1059 {
1060 ModelElementFacade a = (ModelElementFacade)objectA;
1061 ModelElementFacade b = (ModelElementFacade)objectB;
1062
1063 return collator.compare(
1064 a.getName(),
1065 b.getName());
1066 }
1067 }
1068
1069
1070
1071
1072 private static final String OPERATION_SORT_MODE_NAME = "name";
1073
1074
1075
1076
1077 private static final String OPERATION_SORT_MODE_NONE = "none";
1078
1079
1080
1081
1082
1083
1084 private String getWSDLOperationSortMode()
1085 {
1086 Object property = this.getConfiguredProperty(WSDL_OPERATION_SORT_MODE);
1087 return property != null ? (property.equals(OPERATION_SORT_MODE_NAME) ? (String)property : OPERATION_SORT_MODE_NONE) : OPERATION_SORT_MODE_NONE;
1088 }
1089
1090
1091
1092
1093
1094 protected boolean handleIsSecured()
1095 {
1096 Collection<Role> roles = this.getAllRoles();
1097 return roles != null && !roles.isEmpty();
1098 }
1099
1100
1101
1102
1103
1104
1105 public Collection<Role> getAllRoles()
1106 {
1107 final Collection<Role> roles = new LinkedHashSet<Role>(this.getRoles());
1108 CollectionUtils.forAllDo(
1109 this.getAllowedOperations(),
1110 new Closure()
1111 {
1112 public void execute(Object object)
1113 {
1114 if (object != null && ServiceOperation.class.isAssignableFrom(object.getClass()))
1115 {
1116 roles.addAll(((ServiceOperation)object).getRoles());
1117 }
1118 }
1119 });
1120 return roles;
1121 }
1122
1123
1124
1125
1126 private static final String TEST_PACKAGE_NAME_PATTERN = "testPackageNamePattern";
1127
1128
1129
1130
1131
1132 protected String handleGetTestPackageName()
1133 {
1134 return String.valueOf(this.getConfiguredProperty(TEST_PACKAGE_NAME_PATTERN)).replaceAll(
1135 "\\{0\\}",
1136 this.getPackageName());
1137 }
1138
1139
1140
1141
1142
1143 protected String handleGetFullyQualifiedTestName()
1144 {
1145 return this.getTestPackageName() + '.' + this.getTestName();
1146 }
1147
1148
1149
1150
1151 private static final String TEST_NAME_PATTERN = "testNamePattern";
1152
1153
1154
1155
1156
1157 protected String handleGetTestName()
1158 {
1159 return String.valueOf(this.getConfiguredProperty(TEST_NAME_PATTERN)).replaceAll(
1160 "\\{0\\}",
1161 this.getName());
1162 }
1163
1164
1165
1166
1167 private static final String STYLE_WRAPPED = "wrapped";
1168
1169
1170
1171
1172
1173 protected boolean handleIsWrappedStyle()
1174 {
1175 return this.getStyle().equalsIgnoreCase(STYLE_WRAPPED);
1176 }
1177
1178
1179
1180
1181 private static final String STYLE_DOCUMENT = "document";
1182
1183
1184
1185
1186
1187 protected boolean handleIsDocumentStyle()
1188 {
1189 return this.getStyle().equalsIgnoreCase(STYLE_DOCUMENT);
1190 }
1191
1192
1193
1194
1195 private static final String STYLE_RPC = "rpc";
1196
1197
1198
1199
1200
1201 protected boolean handleIsRpcStyle()
1202 {
1203 return this.getStyle().equalsIgnoreCase(STYLE_RPC);
1204 }
1205
1206
1207
1208
1209 private static final String USE_LITERAL = "literal";
1210
1211
1212
1213
1214
1215 protected boolean handleIsLiteralUse()
1216 {
1217 return this.getStyle().equalsIgnoreCase(USE_LITERAL);
1218 }
1219
1220
1221
1222
1223 private static final String USE_ENCODED = "encoded";
1224
1225
1226
1227
1228
1229 protected boolean handleIsEncodedUse()
1230 {
1231 return this.getStyle().equalsIgnoreCase(USE_ENCODED);
1232 }
1233
1234
1235
1236
1237 private static final String TEST_IMPLEMENTATION_NAME_PATTERN = "testImplementationNamePattern";
1238
1239
1240
1241
1242
1243 protected String handleGetTestImplementationName()
1244 {
1245 return String.valueOf(this.getConfiguredProperty(TEST_IMPLEMENTATION_NAME_PATTERN)).replaceAll(
1246 "\\{0\\}",
1247 this.getName());
1248 }
1249
1250
1251
1252
1253
1254 protected String handleGetFullyQualifiedTestImplementationName()
1255 {
1256 return this.getTestPackageName() + '.' + this.getTestImplementationName();
1257 }
1258
1259
1260
1261
1262
1263
1264 protected TypeMappings handleGetSchemaMappings()
1265 {
1266 final String propertyName = WebServiceGlobals.SCHEMA_TYPE_MAPPINGS_URI;
1267 Object property = this.getConfiguredProperty(propertyName);
1268 TypeMappings mappings = null;
1269 String uri = null;
1270 if (property instanceof String)
1271 {
1272 uri = (String)property;
1273 try
1274 {
1275 mappings = TypeMappings.getInstance(uri);
1276 mappings.setArraySuffix(this.getArraySuffix());
1277 this.setProperty(propertyName, mappings);
1278 }
1279 catch (Throwable th)
1280 {
1281 String errMsg = "Error getting '" + propertyName + "' --> '" + uri + '\'';
1282 logger.error(errMsg, th);
1283
1284 }
1285 }
1286 else
1287 {
1288 mappings = (TypeMappings)property;
1289 }
1290 return mappings;
1291 }
1292
1293
1294
1295
1296
1297
1298 private String getArraySuffix()
1299 {
1300 return String.valueOf(this.getConfiguredProperty(UMLMetafacadeProperties.ARRAY_NAME_SUFFIX));
1301 }
1302
1303
1304
1305
1306 protected Collection handleGetAllowedOperationExceptions()
1307 {
1308 final Collection exceptions = new HashSet();
1309
1310
1311 for (final OperationFacade operation : this.getAllowedOperations())
1312 {
1313 exceptions.addAll(operation.getExceptions());
1314 }
1315
1316 return exceptions;
1317 }
1318
1319
1320
1321
1322
1323 public Collection<PackageFacade> getPackages() {
1324 return new WebServiceUtils().getPackages(this, (Set) this.getAllowedOperations(), true);
1325 }
1326
1327
1328
1329
1330
1331
1332 public String getPkgAbbr(PackageFacade pkg) {
1333 return new WebServiceUtils().getPkgAbbr(pkg);
1334 }
1335
1336
1337
1338
1339 private static final String PROPERTY_SCHEMA_VALIDATION = "schemaValidation";
1340 private static final String BOOLEAN_FALSE = "false";
1341 private static final String BOOLEAN_TRUE = "true";
1342
1343
1344
1345
1346 @Override
1347 protected boolean handleIsSchemaValidation()
1348 {
1349 String mode = (String)this.findTaggedValue(WebServiceGlobals.XML_SCHEMA_VALIDATION);
1350 if (StringUtils.isBlank(mode) || mode.equals(DEFAULT))
1351 {
1352 mode = String.valueOf(this.getConfiguredProperty(PROPERTY_SCHEMA_VALIDATION));
1353 }
1354 if (StringUtils.isBlank(mode) || mode.equals(DEFAULT))
1355 {
1356 mode = BOOLEAN_FALSE;
1357 }
1358 return Boolean.parseBoolean(mode);
1359 }
1360
1361
1362
1363
1364 private static final String PROPERTY_SIMPLE_BINDING_MODE = "simpleBindingMode";
1365
1366
1367
1368
1369 @Override
1370 protected boolean handleIsSimpleBindingMode()
1371 {
1372 String mode = (String)this.findTaggedValue(WebServiceGlobals.JAXB_SIMPLE_BINDING_MODE);
1373 if (StringUtils.isBlank(mode) || mode.equals(DEFAULT))
1374 {
1375 mode = String.valueOf(this.getConfiguredProperty(PROPERTY_SIMPLE_BINDING_MODE));
1376 }
1377 return Boolean.parseBoolean(mode);
1378 }
1379
1380
1381
1382
1383
1384 private static final String PROPERTY_XJC_ARGUMENTS = "xjcArguments";
1385
1386
1387
1388
1389 @Override
1390 protected String handleGetXjcArguments()
1391 {
1392 String mode = (String)this.findTaggedValue(WebServiceGlobals.JAXB_XJC_ARGUMENTS);
1393 if (StringUtils.isBlank(mode) || mode.equals(DEFAULT))
1394 {
1395 mode = String.valueOf(this.getConfiguredProperty(PROPERTY_XJC_ARGUMENTS));
1396 }
1397 return mode;
1398 }
1399
1400
1401
1402
1403 @Override
1404 protected String handleGetRestCacheType()
1405 {
1406 String cacheType = (String)this.findTaggedValue(WebServiceGlobals.CACHE_TYPE);
1407 if (!(this.getRestCount()>0) || StringUtils.isBlank(cacheType) || cacheType.equals(DEFAULT))
1408 {
1409 cacheType = EMPTY_STRING;
1410 }
1411 return cacheType;
1412 }
1413
1414
1415
1416
1417 @Override
1418 protected String handleGetRestConsumes()
1419 {
1420 String consumes = (String)this.findTaggedValue(WebServiceGlobals.REST_CONSUMES);
1421 if (!(this.getRestCount()>0) || StringUtils.isBlank(consumes) || consumes.equals(DEFAULT))
1422 {
1423 consumes = EMPTY_STRING;
1424 }
1425 else
1426 {
1427 consumes = WebServiceOperationLogicImpl.translateMediaType(consumes);
1428 }
1429 return consumes;
1430 }
1431
1432
1433
1434
1435
1436 @Override
1437 protected List<String> handleGetRestContexts()
1438 {
1439 List<String> contexts = new ArrayList<String>();
1440 String context = (String)this.findTaggedValue(WebServiceGlobals.REST_CONTEXT);
1441 if (!(this.getRestCount()>0) || StringUtils.isBlank(context) || context.equals(DEFAULT))
1442 {
1443 context = EMPTY_STRING;
1444 }
1445 else
1446 {
1447
1448 String[] parsed = StringUtils.split(context, ",;|");
1449 for (int i=0; i<parsed.length; i++)
1450 {
1451 contexts.add(parsed[i]);
1452 }
1453 }
1454 return contexts;
1455 }
1456
1457
1458
1459
1460 @Override
1461 protected String handleGetRestMethod()
1462 {
1463 String method = (String)this.findTaggedValue(WebServiceGlobals.REST_HTTP_METHOD);
1464 if (!(this.getRestCount()>0) || StringUtils.isBlank(method) || method.equals(DEFAULT))
1465 {
1466 method = EMPTY_STRING;
1467 }
1468 return method;
1469 }
1470
1471 private static final String SLASH = "/";
1472 private static final String QUOTE = "\"";
1473
1474
1475
1476
1477
1478 @Override
1479 protected String handleGetRestPath()
1480 {
1481 String path = (String)this.findTaggedValue(WebServiceGlobals.REST_PATH);
1482 if (StringUtils.isBlank(path))
1483 {
1484 path = EMPTY_STRING;
1485 }
1486 if (!(this.getRestCount()>0) || StringUtils.isBlank(path) || path.equals(DEFAULT))
1487 {
1488 path = QUOTE + SLASH + this.getName().toLowerCase() + SLASH + QUOTE;
1489 }
1490 else
1491 {
1492 if (!path.startsWith(QUOTE))
1493 {
1494 path = QUOTE + path;
1495 }
1496 if (!path.endsWith(QUOTE) || path.length()<2)
1497 {
1498 path = path + QUOTE;
1499 }
1500 }
1501 return path;
1502 }
1503
1504
1505
1506
1507
1508 @Override
1509 protected String handleGetRestProduces()
1510 {
1511 return WebServiceOperationLogicImpl.translateMediaType((String)this.findTaggedValue(WebServiceGlobals.REST_PRODUCES));
1512 }
1513
1514
1515
1516
1517 @Override
1518 protected String handleGetRestProvider()
1519 {
1520 String provider = (String)this.findTaggedValue(WebServiceGlobals.REST_PROVIDER);
1521 if (!(this.getRestCount()>0) || StringUtils.isBlank(provider) || provider.equals(DEFAULT))
1522 {
1523 provider = EMPTY_STRING;
1524 }
1525 return provider;
1526 }
1527
1528
1529
1530
1531 @Override
1532 protected String handleGetRestRetention()
1533 {
1534 String retention = (String)this.findTaggedValue(WebServiceGlobals.REST_RETENTION);
1535 if (!(this.getRestCount()>0) || StringUtils.isBlank(retention) || retention.equals(DEFAULT))
1536 {
1537 retention = EMPTY_STRING;
1538 }
1539 return retention;
1540 }
1541
1542
1543
1544
1545 @Override
1546 protected String handleGetRestTarget()
1547 {
1548 String target = (String)this.findTaggedValue(WebServiceGlobals.REST_TARGET);
1549 if (!(this.getRestCount()>0) || StringUtils.isBlank(target) || target.equals(DEFAULT))
1550 {
1551 target = EMPTY_STRING;
1552 }
1553 return target;
1554 }
1555
1556
1557
1558
1559 @Override
1560 protected boolean handleIsRestAtom()
1561 {
1562 boolean restAtom = false;
1563 if (this.getRestCount()>0)
1564 {
1565 Collection<WebServiceOperation> operations = this.getAllowedOperations();
1566 for (WebServiceOperation operation : operations)
1567 {
1568 String restProduces = operation.getRestProduces();
1569 if (StringUtils.isNotBlank(restProduces) && restProduces.contains("atom"))
1570 {
1571 restAtom = true;
1572 break;
1573 }
1574 }
1575 if (!restAtom)
1576 {
1577 restAtom = StringUtils.isNotBlank(this.getRestProduces()) && this.getRestProduces().indexOf("atom") > -1;
1578 }
1579 }
1580 return restAtom;
1581 }
1582
1583
1584
1585
1586 @Override
1587 protected int handleGetRestCount()
1588 {
1589 int restCount = 0;
1590 String rest = (String)this.findTaggedValue(WebServiceGlobals.REST);
1591 for (WebServiceOperation operation : this.getAllowedOperations())
1592 {
1593 if (StringUtils.isNotBlank(rest) && (operation.isRest() || rest.equals(BOOLEAN_TRUE)))
1594 {
1595 restCount++;
1596 }
1597 }
1598 return restCount;
1599 }
1600
1601
1602
1603
1604 @Override
1605 protected int handleGetJaxwsCount()
1606 {
1607 int jaxwsCount = 0;
1608 String rest = (String)this.findTaggedValue(WebServiceGlobals.REST);
1609 for (WebServiceOperation operation : this.getAllowedOperations())
1610 {
1611 if (StringUtils.isBlank(rest) || rest.equals(BOOLEAN_FALSE) && (!operation.isRest()))
1612 {
1613 jaxwsCount++;
1614 }
1615 }
1616 return jaxwsCount;
1617 }
1618
1619
1620
1621
1622
1623
1624 public Boolean useEnumValueInXSD()
1625 {
1626 final String propertyName = WebServiceGlobals.USE_ENUM_VALUE_IN_XSD;
1627
1628 Object property = this.getConfiguredProperty(propertyName);
1629 if (property != null && String.class.isAssignableFrom(property.getClass()))
1630 {
1631 return Boolean.valueOf(String.valueOf(property)).booleanValue();
1632 }
1633 return Boolean.TRUE;
1634 }
1635
1636
1637
1638
1639
1640 @Override
1641 public void validateInvariants(Collection<ModelValidationMessage> validationMessages)
1642 {
1643 super.validateInvariants(validationMessages);
1644 try
1645 {
1646 final Object contextElement = this.THIS();
1647 final String name = (String)OCLIntrospector.invoke(contextElement,"name");
1648 boolean constraintValid = OCLExpressions.equal(
1649 name.substring(0,1).toUpperCase(),
1650 name.substring(0,1));
1651 if (!constraintValid)
1652 {
1653 validationMessages.add(
1654 new ModelValidationMessage(
1655 (MetafacadeBase)contextElement ,
1656 "org::andromda::cartridges::webservice::metafacades::WebService::class name must start with an uppercase letter",
1657 "WebService Class name must start with an uppercase letter."));
1658 }
1659 }
1660 catch (Throwable th)
1661 {
1662 Throwable cause = th.getCause();
1663 int depth = 0;
1664 while (cause != null && depth < 7)
1665 {
1666 th = cause;
1667 depth++;
1668 }
1669 logger.error("Error validating constraint 'org::andromda::cartridges::webservice::WebService::class name must start with an uppercase letter' ON "
1670 + this.THIS().toString() + ": " + th.getMessage(), th);
1671 }
1672 }
1673 }